Skip to content

Commit b1b8cd1

Browse files
authored
Add basic profiler. (qmk#20238)
1 parent 8971311 commit b1b8cd1

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

quantum/basic_profiling.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright 2023 Nick Brassel (@tzarc)
2+
// SPDX-License-Identifier: GPL-2.0-or-later
3+
#pragma once
4+
5+
/*
6+
This API allows for basic profiling information to be printed out over console.
7+
8+
Usage example:
9+
10+
#include "basic_profiling.h"
11+
12+
// Original code:
13+
matrix_task();
14+
15+
// Delete the original, replace with the following (variant 1, automatic naming):
16+
PROFILE_CALL(1000, matrix_task());
17+
18+
// Delete the original, replace with the following (variant 2, explicit naming):
19+
PROFILE_CALL_NAMED(1000, "matrix_task", {
20+
matrix_task();
21+
});
22+
*/
23+
24+
#if defined(PROTOCOL_LUFA) || defined(PROTOCOL_VUSB)
25+
# define TIMESTAMP_GETTER TCNT0
26+
#elif defined(PROTOCOL_CHIBIOS)
27+
# define TIMESTAMP_GETTER chSysGetRealtimeCounterX()
28+
#elif defined(PROTOCOL_ARM_ATSAM)
29+
# error arm_atsam not currently supported
30+
#else
31+
# error Unknown protocol in use
32+
#endif
33+
34+
#ifndef CONSOLE_ENABLE
35+
// Can't do anything if we don't have console output enabled.
36+
# define PROFILE_CALL_NAMED(count, name, call) \
37+
do { \
38+
} while (0)
39+
#else
40+
# define PROFILE_CALL_NAMED(count, name, call) \
41+
do { \
42+
static uint64_t inner_sum = 0; \
43+
static uint64_t outer_sum = 0; \
44+
uint32_t start_ts; \
45+
static uint32_t end_ts; \
46+
static uint32_t write_location = 0; \
47+
start_ts = TIMESTAMP_GETTER; \
48+
if (write_location > 0) { \
49+
outer_sum += start_ts - end_ts; \
50+
} \
51+
do { \
52+
call; \
53+
} while (0); \
54+
end_ts = TIMESTAMP_GETTER; \
55+
inner_sum += end_ts - start_ts; \
56+
++write_location; \
57+
if (write_location >= ((uint32_t)count)) { \
58+
uint32_t inner_avg = inner_sum / (((uint32_t)count) - 1); \
59+
uint32_t outer_avg = outer_sum / (((uint32_t)count) - 1); \
60+
dprintf("%s -- Percentage time spent: %d%%\n", (name), (int)(inner_avg * 100 / (inner_avg + outer_avg))); \
61+
inner_sum = 0; \
62+
outer_sum = 0; \
63+
write_location = 0; \
64+
} \
65+
} while (0)
66+
67+
#endif // CONSOLE_ENABLE
68+
69+
#define PROFILE_CALL(count, call) PROFILE_CALL_NAMED(count, #call, call)

0 commit comments

Comments
 (0)