altos: Block interrupts while waking tasks sleeping on timers.
authorKeith Packard <keithp@keithp.com>
Wed, 29 Jun 2016 00:04:59 +0000 (17:04 -0700)
committerKeith Packard <keithp@keithp.com>
Thu, 30 Jun 2016 02:17:45 +0000 (19:17 -0700)
Interrupts may not be blocked in the timer ISR, but they need to be
while walking the pending timer list and moving tasks back to the run
queue.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/kernel/ao.h
src/kernel/ao_task.c
src/stm/ao_arch_funcs.h

index 6ed0299e2d707baa607a515394ab4f4eccb7988b..27a16606010ff8f629c30755ed1e9ec39aeea1c3 100644 (file)
@@ -73,6 +73,7 @@ typedef AO_PORT_TYPE ao_port_t;
 #define AO_PANIC_EXTI          16      /* Mis-using exti API */
 #define AO_PANIC_FAST_TIMER    17      /* Mis-using fast timer API */
 #define AO_PANIC_ADC           18      /* Mis-using ADC interface */
+#define AO_PANIC_IRQ           19      /* interrupts not blocked */
 #define AO_PANIC_SELF_TEST_CC1120      0x40 | 1        /* Self test failure */
 #define AO_PANIC_SELF_TEST_HMC5883     0x40 | 2        /* Self test failure */
 #define AO_PANIC_SELF_TEST_MPU6000     0x40 | 3        /* Self test failure */
index e430edc6c02f3e5854b5163ebd18afc26d6c0e0e..03d69caab88906ca573ebd8483f3548139625c29 100644 (file)
@@ -165,13 +165,14 @@ ao_task_check_alarm(uint16_t tick)
 {
        struct ao_task  *alarm, *next;
 
-       ao_list_for_each_entry_safe(alarm, next, &alarm_queue, struct ao_task, alarm_queue) {
-               if ((int16_t) (tick - alarm->alarm) < 0)
-                       break;
-               alarm->alarm = 0;
-               ao_task_from_alarm_queue(alarm);
-               ao_task_to_run_queue(alarm);
-       }
+       ao_arch_critical(
+               ao_list_for_each_entry_safe(alarm, next, &alarm_queue, struct ao_task, alarm_queue) {
+                       if ((int16_t) (tick - alarm->alarm) < 0)
+                               break;
+                       alarm->alarm = 0;
+                       ao_task_from_alarm_queue(alarm);
+                       ao_task_to_run_queue(alarm);
+               });
 }
 
 void
index 2c017c79f0191b5b5395f66f508a26748cb048db..33359857041f2c6f1f4dff4a0509f4d0b6b2cee6 100644 (file)
@@ -343,6 +343,14 @@ ao_arch_memory_barrier() {
        asm volatile("" ::: "memory");
 }
 
+static inline void
+ao_arch_irq_check(void) {
+       uint32_t        primask;
+       asm("mrs %0,primask" : "=&r" (primask));
+       if ((primask & 1) == 0)
+               ao_panic(AO_PANIC_IRQ);
+}
+
 #if HAS_TASK
 static inline void
 ao_arch_init_stack(struct ao_task *task, void *start)