|  | /* | 
|  | * Copyright 2017, Data61 | 
|  | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) | 
|  | * ABN 41 687 119 230. | 
|  | * | 
|  | * This software may be distributed and modified according to the terms of | 
|  | * the BSD 2-Clause license. Note that NO WARRANTY is provided. | 
|  | * See "LICENSE_BSD2.txt" for details. | 
|  | * | 
|  | * @TAG(DATA61_BSD) | 
|  | */ | 
|  |  | 
|  | #pragma once | 
|  |  | 
|  | #include <sel4utils/util.h> | 
|  | #include <stdint.h> | 
|  |  | 
|  | #define PROFILE_VAR_TYPE_INT32 1 | 
|  | #define PROFILE_VAR_TYPE_INT64 2 | 
|  |  | 
|  | typedef struct profile_var { | 
|  | int type; | 
|  | void *var; | 
|  | const char *varname; | 
|  | const char *description; | 
|  | } profile_var_t; | 
|  |  | 
|  | #define __WATCH_VAR(_type, _var, _description, _unique) \ | 
|  | static profile_var_t profile_##_unique \ | 
|  | __attribute__((used)) __attribute__((section("_profile_var"))) \ | 
|  | = {.type = _type, .var = &_var, .varname = #_var, .description = _description} | 
|  |  | 
|  | #define _WATCH_VAR32(var, description, unique) \ | 
|  | compile_time_assert(profile_size_##unique, sizeof(var) == 4); \ | 
|  | __WATCH_VAR(PROFILE_VAR_TYPE_INT32, var, description, unique) | 
|  |  | 
|  | #define WATCH_VAR32(var, description) \ | 
|  | _WATCH_VAR32(var, description, __LINE__) | 
|  |  | 
|  | #define _WATCH_VAR64(var, description, unique) \ | 
|  | compile_time_assert(profile_size_##unique, sizeof(var) == 8); \ | 
|  | __WATCH_VAR(PROFILE_VAR_TYPE_INT64, var, description, unique) | 
|  |  | 
|  | #define WATCH_VAR64(var, description) \ | 
|  | _WATCH_VAR64(var, description, __LINE__) | 
|  |  | 
|  | typedef void (*profile_callback32)(uint32_t value, const char *varname, const char *descrption, void *cookie); | 
|  | typedef void (*profile_callback64)(uint64_t value, const char *varname, const char *descrption, void *cookie); | 
|  |  | 
|  | /* Sample functions that just output the vars using printf. cookie is ignored */ | 
|  | void profile_print32(uint32_t value, const char *varname, const char *description, void *cookie); | 
|  | void profile_print64(uint64_t value, const char *varname, const char *description, void *cookie); | 
|  |  | 
|  | /* Iterates over all profile variables and calls back the specified function(s) | 
|  | * with the current value. */ | 
|  | void profile_scrape(profile_callback32 callback32, profile_callback64 callback64, void *cookie); | 
|  |  | 
|  | /* Iterates over all profile variables and resets the value to zero */ | 
|  | void profile_reset(void); | 
|  |  | 
|  | #define _PSTART_TIME(x) uint32_t __begin_time##x = read_ccnt() | 
|  | #define _PEND_TIME(x) uint32_t __end_time##x = read_ccnt() | 
|  | #define _PTIME_DIFF(x) (__end_time##x - __begin_time##x) | 
|  | #define PINC(name) PADD(name, 1) | 
|  | #define PADDTIMEDIFF(name) PADD(name, PTIMEDIFF(name)) | 
|  | #define PADDTIME(name) PEND_TIME(name); PADDTIMEDIFF(name) | 
|  | #define PTIMEDIFF(x) _PTIME_DIFF(x) | 
|  |  | 
|  | #ifdef CONFIG_SEL4UTILS_PROFILE | 
|  | #define PVARUINT32(name, desc) static uint32_t name = 0; WATCH_VAR32(name, desc); | 
|  | #define PVARUINT64(name, desc) static uint64_t name = 0; WATCH_VAR64(name, desc); | 
|  | #define PADD(name, x) do {name += (x); } while(0) | 
|  | #define PSTART_TIME(x) _PSTART_TIME(x) | 
|  | #define PEND_TIME(x) _PEND_TIME(x) | 
|  | #else | 
|  | #define PVARUINT32(name, desc) | 
|  | #define PVARUINT64(name, desc) | 
|  | #define PADD(name, x) do { } while(0) | 
|  | #define PSTART_TIME(x) do { } while(0) | 
|  | #define PEND_TIME(x) do { } while(0) | 
|  | #endif | 
|  |  |