summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--quantum/basic_profiling.h69
1 files changed, 69 insertions, 0 deletions
diff --git a/quantum/basic_profiling.h b/quantum/basic_profiling.h
new file mode 100644
index 0000000000..d371acd6f0
--- /dev/null
+++ b/quantum/basic_profiling.h
@@ -0,0 +1,69 @@
+// Copyright 2023 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+/*
+    This API allows for basic profiling information to be printed out over console.
+
+    Usage example:
+
+        #include "basic_profiling.h"
+
+        // Original code:
+        matrix_task();
+
+        // Delete the original, replace with the following (variant 1, automatic naming):
+        PROFILE_CALL(1000, matrix_task());
+
+        // Delete the original, replace with the following (variant 2, explicit naming):
+        PROFILE_CALL_NAMED(1000, "matrix_task", {
+            matrix_task();
+        });
+*/
+
+#if defined(PROTOCOL_LUFA) || defined(PROTOCOL_VUSB)
+#    define TIMESTAMP_GETTER TCNT0
+#elif defined(PROTOCOL_CHIBIOS)
+#    define TIMESTAMP_GETTER chSysGetRealtimeCounterX()
+#elif defined(PROTOCOL_ARM_ATSAM)
+#    error arm_atsam not currently supported
+#else
+#    error Unknown protocol in use
+#endif
+
+#ifndef CONSOLE_ENABLE
+// Can't do anything if we don't have console output enabled.
+#    define PROFILE_CALL_NAMED(count, name, call) \
+        do {                                      \
+        } while (0)
+#else
+#    define PROFILE_CALL_NAMED(count, name, call)                                                                         \
+        do {                                                                                                              \
+            static uint64_t inner_sum = 0;                                                                                \
+            static uint64_t outer_sum = 0;                                                                                \
+            uint32_t        start_ts;                                                                                     \
+            static uint32_t end_ts;                                                                                       \
+            static uint32_t write_location = 0;                                                                           \
+            start_ts                       = TIMESTAMP_GETTER;                                                            \
+            if (write_location > 0) {                                                                                     \
+                outer_sum += start_ts - end_ts;                                                                           \
+            }                                                                                                             \
+            do {                                                                                                          \
+                call;                                                                                                     \
+            } while (0);                                                                                                  \
+            end_ts = TIMESTAMP_GETTER;                                                                                    \
+            inner_sum += end_ts - start_ts;                                                                               \
+            ++write_location;                                                                                             \
+            if (write_location >= ((uint32_t)count)) {                                                                    \
+                uint32_t inner_avg = inner_sum / (((uint32_t)count) - 1);                                                 \
+                uint32_t outer_avg = outer_sum / (((uint32_t)count) - 1);                                                 \
+                dprintf("%s -- Percentage time spent: %d%%\n", (name), (int)(inner_avg * 100 / (inner_avg + outer_avg))); \
+                inner_sum      = 0;                                                                                       \
+                outer_sum      = 0;                                                                                       \
+                write_location = 0;                                                                                       \
+            }                                                                                                             \
+        } while (0)
+
+#endif // CONSOLE_ENABLE
+
+#define PROFILE_CALL(count, call) PROFILE_CALL_NAMED(count, #call, call)