From 40675bd1f432490d76a5fe741572c28510f1d8c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Tue, 27 Feb 2018 18:39:59 +0100 Subject: [PATCH] logger: fix potential semaphore counter overflow When the timer callback is called at a higher rate than the logger can execute the main loop (which is never the case under normal conditions), the semaphore counter will increase unbounded, and eventually lead to an assertion failure in NuttX. The maximum semaphore counter is 0x7FFF, and when the logger runs at default rate (3.5ms), the logger task must be blocked for 0x7FFF*3.5/1000 = 114 seconds continuously for an overflow to happen. I see 2 cases where that could happen: - the logger execution blocks somehow, or busy-loops in an inner loop - a higher-prio task runs busy and hogs the CPU over a long period of time --- src/modules/logger/logger.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/modules/logger/logger.cpp b/src/modules/logger/logger.cpp index 8066bc4448..8dc1605e97 100644 --- a/src/modules/logger/logger.cpp +++ b/src/modules/logger/logger.cpp @@ -92,6 +92,19 @@ using namespace px4::logger; static void timer_callback(void *arg) { px4_sem_t *semaphore = (px4_sem_t *)arg; + + /* check the value of the semaphore: if the logger cannot keep up with running it's main loop as fast + * as the timer_callback here increases the semaphore count, the counter would increase unbounded, + * leading to an overflow at some point. This case we want to avoid here, so we check the current + * value against a (somewhat arbitrary) threshold, and avoid calling sem_post() if it's exceeded. + * (it's not a problem if the threshold is a bit too large, it just means the logger will do + * multiple iterations at once, the next time it's scheduled). */ + int semaphore_value; + + if (px4_sem_getvalue(semaphore, &semaphore_value) == 0 && semaphore_value > 1) { + return; + } + px4_sem_post(semaphore); }