diff options
Diffstat (limited to 'quantum/basic_profiling.h')
| -rw-r--r-- | quantum/basic_profiling.h | 69 | 
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) | 
