Skip to content

Commit 3464c8b

Browse files
committed
Bulletproof event scheduler event vector updates.
1 parent 42a9d87 commit 3464c8b

2 files changed

Lines changed: 20 additions & 5 deletions

File tree

right/src/event_scheduler.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "event_scheduler.h"
2+
#include "atomicity.h"
23
#include "timer.h"
34
#include "macros/core.h"
45
#include "macro_recorder.h"
@@ -127,8 +128,16 @@ static inline heap_entry_t* heapPeek(void) {
127128
return heapSize > 0 ? &heap[0] : NULL;
128129
}
129130

131+
// Must run inside the enclosing heap critical section: the heapSize read and
132+
// the vector update have to be atomic, and the nested guard of
133+
// EventVector_Set/Unset would re-enable irqs mid-section on MCUX.
130134
static void updateEventVector(void) {
131-
EventVector_SetValue(EventVector_EventScheduler, heapSize > 0);
135+
ASSERT_IRQS_DISABLED();
136+
if (heapSize > 0) {
137+
EventScheduler_Vector |= EventVector_EventScheduler;
138+
} else {
139+
EventScheduler_Vector &= ~EventVector_EventScheduler;
140+
}
132141
}
133142

134143
#define RETURN_IF_SPAM(EVT) if (isSpam(EVT)) { return; }
@@ -283,8 +292,8 @@ void EventScheduler_Reschedule(uint32_t at, event_scheduler_event_t evt, const c
283292
} else {
284293
heapInsert(evt, at, label);
285294
}
286-
ENABLE_IRQ();
287295
updateEventVector();
296+
ENABLE_IRQ();
288297

289298
#ifdef __ZEPHYR__
290299
Main_Wake();
@@ -309,8 +318,8 @@ void EventScheduler_Schedule(uint32_t at, event_scheduler_event_t evt, const cha
309318
} else {
310319
heapInsert(evt, at, label);
311320
}
312-
ENABLE_IRQ();
313321
updateEventVector();
322+
ENABLE_IRQ();
314323

315324
#ifdef __ZEPHYR__
316325
Main_Wake();
@@ -326,8 +335,8 @@ void EventScheduler_Unschedule(event_scheduler_event_t evt)
326335
if (idx != HEAP_INDEX_NONE) {
327336
heapRemove(idx);
328337
}
329-
ENABLE_IRQ();
330338
updateEventVector();
339+
ENABLE_IRQ();
331340
}
332341

333342
uint32_t EventScheduler_Process()
@@ -343,9 +352,9 @@ uint32_t EventScheduler_Process()
343352
}
344353
heap_entry_t entry = heap[0];
345354
heapRemove(0);
355+
updateEventVector();
346356
ENABLE_IRQ();
347357

348-
updateEventVector();
349358

350359
LOG_SCHEDULE(
351360
if (entry.label != NULL) {

shared/atomicity.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33

44
#ifdef __ZEPHYR__
55
#include <zephyr/irq.h>
6+
#include <zephyr/sys/__assert.h>
7+
#include <cmsis_core.h>
68
#define DISABLE_IRQ() unsigned int key = irq_lock()
79
#define ENABLE_IRQ() irq_unlock(key)
10+
// irq_lock() masks via BASEPRI on Cortex-M; PRIMASK covers __disable_irq/ISR-entry masking.
11+
#define ASSERT_IRQS_DISABLED() __ASSERT((__get_PRIMASK() != 0) || (__get_BASEPRI() != 0), "irqs are enabled")
812
#else
13+
#include <assert.h>
914
#include "fsl_common.h"
1015
#define DISABLE_IRQ() __disable_irq()
1116
#define ENABLE_IRQ() __enable_irq()
17+
#define ASSERT_IRQS_DISABLED() assert(__get_PRIMASK() != 0)
1218
#endif
1319

1420
// Includes:

0 commit comments

Comments
 (0)