at master 4.3 kB view raw
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#else 29# error Unknown protocol in use 30#endif 31 32#ifndef CONSOLE_ENABLE 33// Can't do anything if we don't have console output enabled. 34# define PROFILE_CALL_NAMED(count, name, call) \ 35 do { \ 36 } while (0) 37#else 38# define PROFILE_CALL_NAMED(count, name, call) \ 39 do { \ 40 static uint64_t inner_sum = 0; \ 41 static uint64_t outer_sum = 0; \ 42 uint32_t start_ts; \ 43 static uint32_t end_ts; \ 44 static uint32_t write_location = 0; \ 45 start_ts = TIMESTAMP_GETTER; \ 46 if (write_location > 0) { \ 47 outer_sum += start_ts - end_ts; \ 48 } \ 49 do { \ 50 call; \ 51 } while (0); \ 52 end_ts = TIMESTAMP_GETTER; \ 53 inner_sum += end_ts - start_ts; \ 54 ++write_location; \ 55 if (write_location >= ((uint32_t)count)) { \ 56 uint32_t inner_avg = inner_sum / (((uint32_t)count) - 1); \ 57 uint32_t outer_avg = outer_sum / (((uint32_t)count) - 1); \ 58 dprintf("%s -- Percentage time spent: %d%%\n", (name), (int)(inner_avg * 100 / (inner_avg + outer_avg))); \ 59 inner_sum = 0; \ 60 outer_sum = 0; \ 61 write_location = 0; \ 62 } \ 63 } while (0) 64 65#endif // CONSOLE_ENABLE 66 67#define PROFILE_CALL(count, call) PROFILE_CALL_NAMED(count, #call, call)