From 9d4a92003c8e4ba37aa7ac6b62c1487461538f53 Mon Sep 17 00:00:00 2001 From: Ludwig Ortmann Date: Fri, 16 May 2014 15:48:48 +0200 Subject: [PATCH] core/hwtimer: disable interrupts in hwtimer_remove Before only the hardware timer's own interrupt was being disabled. This led to a race condition in the following scenario: ``` Thread1: hwtimer_remove() hwtimer_arch_disable_interrupt(); // INTERRUPT -> Thread2 (which has a higher priority than Thread1) gets scheduled Thread2: ... hwtimer_remove() hwtimer_arch_disable_interrupt(); // hwtimer interrupt is already disabled ... hwtimer_arch_enable_interrupt(); ... // yield | terminate -> Thread1 gets scheduled again Thread1: ... // these instructions are being run with the hwtimer interrupt enabled hwtimer_arch_enable_interrupt(); // hwtimer interrupt is already enabled ``` Fixes #924 --- core/hwtimer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/hwtimer.c b/core/hwtimer.c index b0ba36412c9e..bc0bc6c50272 100644 --- a/core/hwtimer.c +++ b/core/hwtimer.c @@ -202,7 +202,8 @@ int hwtimer_set_absolute(unsigned long offset, void (*callback)(void*), void *pt int hwtimer_remove(int n) { DEBUG("hwtimer_remove n=%d\n", n); - hwtimer_arch_disable_interrupt(); + + int state = disableIRQ(); hwtimer_arch_unset(n); lifo_insert(lifo, n); @@ -210,6 +211,7 @@ int hwtimer_remove(int n) lpm_prevent_sleep--; - hwtimer_arch_enable_interrupt(); + restoreIRQ(state); + return 1; }