mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-23 04:53:08 +00:00
acc39a4bc0
* 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>
87 lines
2.4 KiB
C
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);
|
|
}
|
|
}
|
|
}
|