From 8bb6cc07def78a03de028016c86f1f03860a7689 Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Tue, 13 Oct 2020 09:22:51 +0300 Subject: [PATCH] hrt: Add interface functions for latency counters Add interface functions for fetching latency buckets and counters and use those in perf_counter.cpp. This cleans up the usage of perf counters and enables implementing kernel-userspace interface for those for nuttx protected/kernel build. Signed-off-by: Jukka Laitinen --- .../nuttx/src/px4/stm/stm32_common/hrt/hrt.c | 17 +++++++++++ src/drivers/drv_hrt.h | 30 ++++++++++++++++++- src/lib/perf/perf_counter.cpp | 14 ++++----- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/platforms/nuttx/src/px4/stm/stm32_common/hrt/hrt.c b/platforms/nuttx/src/px4/stm/stm32_common/hrt/hrt.c index a88a973f69..92e503fb97 100644 --- a/platforms/nuttx/src/px4/stm/stm32_common/hrt/hrt.c +++ b/platforms/nuttx/src/px4/stm/stm32_common/hrt/hrt.c @@ -1003,4 +1003,21 @@ hrt_call_delay(struct hrt_call *entry, hrt_abstime delay) entry->deadline = hrt_absolute_time() + delay; } +#if !defined(CONFIG_BUILD_FLAT) +/* These functions are inlined in all but NuttX protected/kernel builds */ + +latency_info_t get_latency(uint16_t bucket_idx, uint16_t counter_idx) +{ + latency_info_t ret = {latency_buckets[bucket_idx], latency_counters[counter_idx]}; + return ret; +} + +void reset_latency_counters(void) +{ + for (int i = 0; i <= get_latency_bucket_count(); i++) { + latency_counters[i] = 0; + } +} +#endif + #endif /* HRT_TIMER */ diff --git a/src/drivers/drv_hrt.h b/src/drivers/drv_hrt.h index 0654b287a1..6def3f85ee 100644 --- a/src/drivers/drv_hrt.h +++ b/src/drivers/drv_hrt.h @@ -208,8 +208,36 @@ static inline void px4_lockstep_progress(int component) { } static inline void px4_lockstep_wait_for_components(void) { } #endif /* defined(ENABLE_LOCKSTEP_SCHEDULER) */ -__END_DECLS +/* Latency counter functions */ + +static inline uint16_t get_latency_bucket_count(void) { return LATENCY_BUCKET_COUNT; } + +#if defined(CONFIG_BUILD_FLAT) || !defined(__PX4_NUTTX) + +static inline latency_info_t get_latency(uint16_t bucket_idx, uint16_t counter_idx) +{ + latency_info_t ret = {latency_buckets[bucket_idx], latency_counters[counter_idx]}; + return ret; +} + +static inline void reset_latency_counters(void) +{ + for (int i = 0; i <= get_latency_bucket_count(); i++) { + latency_counters[i] = 0; + } +} + +#else + +/* NuttX protected/kernel build interface functions */ + +latency_info_t get_latency(uint16_t bucket_idx, uint16_t counter_idx); +void reset_latency_counters(void); + +#endif + +__END_DECLS #ifdef __cplusplus diff --git a/src/lib/perf/perf_counter.cpp b/src/lib/perf/perf_counter.cpp index 79eed9fc43..9eb9ab7ec2 100644 --- a/src/lib/perf/perf_counter.cpp +++ b/src/lib/perf/perf_counter.cpp @@ -610,15 +610,17 @@ perf_print_all(int fd) void perf_print_latency(int fd) { + latency_info_t latency; dprintf(fd, "bucket [us] : events\n"); - for (int i = 0; i < latency_bucket_count; i++) { - dprintf(fd, " %4i : %li\n", latency_buckets[i], (long int)latency_counters[i]); + for (int i = 0; i < get_latency_bucket_count(); i++) { + latency = get_latency(i, i); + dprintf(fd, " %4i : %li\n", latency.bucket, (long int)latency.counter); } // print the overflow bucket value - dprintf(fd, " >%4" PRIu16 " : %" PRIu32 "\n", latency_buckets[latency_bucket_count - 1], - latency_counters[latency_bucket_count]); + latency = get_latency(get_latency_bucket_count() - 1, get_latency_bucket_count()); + dprintf(fd, " >%4" PRIu16 " : %" PRIu32 "\n", latency.bucket, latency.counter); } void @@ -634,7 +636,5 @@ perf_reset_all(void) pthread_mutex_unlock(&perf_counters_mutex); - for (int i = 0; i <= latency_bucket_count; i++) { - latency_counters[i] = 0; - } + reset_latency_counters(); }