-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprofiler.h
81 lines (65 loc) · 1.71 KB
/
profiler.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#pragma once
#include "hardware/sync.h"
#include "linkedlist.h"
#ifndef PICORO_ENABLE_PROFILER
#define PICORO_ENABLE_PROFILER 0
#endif
#if PICORO_ENABLE_PROFILER
// forward decl
struct FuncProfile;
extern volatile FuncProfile* currentfunction;
/** Helper function called by PROFILE_THIS_FUNC. */
extern void linkup_func(FuncProfile* func);
/** Call this to print out the profile to stdout/console. */
extern void stop_and_dump_profile();
struct FuncProfile
{
LinkedListEntry llentry;
unsigned int entries;
unsigned int samples;
const char* name;
FuncProfile(const char* name_)
: entries(0), samples(0), name(name_)
{
linkup_func(this);
}
};
struct ProfileStackframeHelper
{
FuncProfile* prev;
ProfileStackframeHelper(FuncProfile* current)
: prev((FuncProfile*) currentfunction)
{
uint32_t save = save_and_disable_interrupts();
currentfunction = current;
current->entries++;
restore_interrupts(save);
}
~ProfileStackframeHelper()
{
uint32_t save = save_and_disable_interrupts();
currentfunction = prev;
restore_interrupts(save);
}
};
/**
* Put PROFILE_THIS_FUNC at the top of your function.
* Looks like:
* \code
* void funcA() {
* PROFILE_THIS_FUNC;
* do_stuff();
* }
* void funcB() {
* PROFILE_THIS_FUNC;
* funcA();
* do_other_stuff();
* }
* \endcode
*/
#define PROFILE_THIS_FUNC \
static FuncProfile __CONCAT(profile, __LINE__)(__PRETTY_FUNCTION__); \
const ProfileStackframeHelper __CONCAT(psh, __LINE__)(&__CONCAT(profile, __LINE__))
#else
#define PROFILE_THIS_FUNC do {} while (false)
#endif