From d53cd19142a90cebd12541c0d5ec50dd3fc5ce3e Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Fri, 9 Sep 2022 21:24:11 +0200 Subject: [PATCH] core/sched.c: fix undefined behavior on 8-bit/16-bit An `1 << x` with `x >= 15` is undefined behavior on 8-bit / 16-bit machines (which typically have `sizeof(int) == 2`). Using `1UL << x` is safe for `x <= 31`, which is large enough to make use of the full 32 bits in `runqueue_bitcache`. In addition, a `static_assert()` is added to enforce that `SCHED_PRIO_LEVELS` is never set to anything larger than 32. --- core/sched.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/core/sched.c b/core/sched.c index fb8dbc3d7c..e99272dc11 100644 --- a/core/sched.c +++ b/core/sched.c @@ -23,12 +23,13 @@ #include #include -#include "sched.h" -#include "clist.h" +#include "assert.h" #include "bitarithm.h" +#include "clist.h" #include "irq.h" -#include "thread.h" #include "log.h" +#include "sched.h" +#include "thread.h" #ifdef MODULE_MPU_STACK_GUARD #include "mpu.h" @@ -58,6 +59,8 @@ volatile kernel_pid_t sched_active_pid = KERNEL_PID_UNDEF; volatile thread_t *sched_threads[KERNEL_PID_LAST + 1]; volatile int sched_num_threads = 0; +static_assert(SCHED_PRIO_LEVELS <= 32, "SCHED_PRIO_LEVELS may at most be 32"); + FORCE_USED_SECTION const uint8_t max_threads = ARRAY_SIZE(sched_threads); @@ -92,7 +95,7 @@ static inline void _set_runqueue_bit(uint8_t priority) #if defined(BITARITHM_HAS_CLZ) runqueue_bitcache |= BIT31 >> priority; #else - runqueue_bitcache |= 1 << priority; + runqueue_bitcache |= 1UL << priority; #endif } @@ -101,7 +104,7 @@ static inline void _clear_runqueue_bit(uint8_t priority) #if defined(BITARITHM_HAS_CLZ) runqueue_bitcache &= ~(BIT31 >> priority); #else - runqueue_bitcache &= ~(1 << priority); + runqueue_bitcache &= ~(1UL << priority); #endif }