unleashed-firmware/lib/toolbox/profiler.c
あく acc39a4bc0
Api Symbols: replace asserts with checks (#3507)
* Api Symbols: replace asserts with checks
* Api Symbols: replace asserts with checks part 2
* Update no args function signatures with void, to help compiler to track incorrect usage
* More unavoidable void
* Update PVS config and code to make it happy
* Format sources
* nfc: fix checks
* dead code cleanup & include fixes

Co-authored-by: gornekich <n.gorbadey@gmail.com>
Co-authored-by: hedger <hedger@users.noreply.github.com>
Co-authored-by: hedger <hedger@nanode.su>
2024-03-19 23:43:52 +09:00

87 lines
2.4 KiB
C

#include "profiler.h"
#include <stdlib.h>
#include <m-dict.h>
#include <furi.h>
#include <furi_hal_gpio.h>
typedef struct {
uint32_t start;
uint32_t length;
uint32_t count;
} ProfilerRecord;
DICT_DEF2(ProfilerRecordDict, const char*, M_CSTR_OPLIST, ProfilerRecord, M_POD_OPLIST)
#define M_OPL_ProfilerRecord_t() DICT_OPLIST(ProfilerRecord, M_CSTR_OPLIST, M_POD_OPLIST)
struct Profiler {
ProfilerRecordDict_t records;
};
Profiler* profiler_alloc(void) {
Profiler* profiler = malloc(sizeof(Profiler));
ProfilerRecordDict_init(profiler->records);
return profiler;
}
void profiler_free(Profiler* profiler) {
ProfilerRecordDict_clear(profiler->records);
free(profiler);
}
void profiler_prealloc(Profiler* profiler, const char* key) {
ProfilerRecord record = {
.start = 0,
.length = 0,
.count = 0,
};
ProfilerRecordDict_set_at(profiler->records, key, record);
}
void profiler_start(Profiler* profiler, const char* key) {
ProfilerRecord* record = ProfilerRecordDict_get(profiler->records, key);
if(record == NULL) {
profiler_prealloc(profiler, key);
record = ProfilerRecordDict_get(profiler->records, key);
}
furi_check(record->start == 0);
record->start = DWT->CYCCNT;
}
void profiler_stop(Profiler* profiler, const char* key) {
ProfilerRecord* record = ProfilerRecordDict_get(profiler->records, key);
furi_check(record != NULL);
record->length += DWT->CYCCNT - record->start;
record->start = 0;
record->count++;
}
void profiler_dump(Profiler* profiler) {
printf("Profiler:\r\n");
ProfilerRecordDict_it_t it;
for(ProfilerRecordDict_it(it, profiler->records); !ProfilerRecordDict_end_p(it);
ProfilerRecordDict_next(it)) {
const ProfilerRecordDict_itref_t* itref = ProfilerRecordDict_cref(it);
uint32_t count = itref->value.count;
uint32_t clocks = itref->value.length;
double us = (double)clocks / (double)64.0;
double ms = (double)clocks / (double)64000.0;
double s = (double)clocks / (double)64000000.0;
printf("\t%s[%lu]: %f s, %f ms, %f us, %lu clk\r\n", itref->key, count, s, ms, us, clocks);
if(count > 1) {
us /= (double)count;
ms /= (double)count;
s /= (double)count;
clocks /= count;
printf("\t%s[1]: %f s, %f ms, %f us, %lu clk\r\n", itref->key, s, ms, us, clocks);
}
}
}