diff options
-rw-r--r-- | board/zinger/runtime.c | 19 | ||||
-rw-r--r-- | core/cortex-m/task.c | 3 | ||||
-rw-r--r-- | core/cortex-m0/task.c | 28 | ||||
-rw-r--r-- | core/host/task.c | 28 |
4 files changed, 76 insertions, 2 deletions
diff --git a/board/zinger/runtime.c b/board/zinger/runtime.c index f2b40cbfd9..8631eea74e 100644 --- a/board/zinger/runtime.c +++ b/board/zinger/runtime.c @@ -216,6 +216,25 @@ uint32_t task_wait_event(int timeout_us) return evt; } +uint32_t task_wait_event_mask(uint32_t event_mask, int timeout_us) +{ + uint32_t evt = 0; + + /* Add the timer event to the mask so we can indicate a timeout */ + event_mask |= TASK_EVENT_TIMER; + + /* Wait until an event matching event_mask */ + do { + evt |= task_wait_event(timeout_us); + } while (!(evt & event_mask)); + + /* Restore any pending events not in the event_mask */ + if (evt & ~event_mask) + task_set_event(0, evt & ~event_mask, 0); + + return evt & event_mask; +} + void __keep cpu_reset(void) { /* Disable interrupts */ diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c index 342fcdcf39..f9e4d11fdb 100644 --- a/core/cortex-m/task.c +++ b/core/cortex-m/task.c @@ -403,8 +403,7 @@ uint32_t task_wait_event_mask(uint32_t event_mask, int timeout_us) /* Re-post any other events collected */ if (events & ~event_mask) - atomic_or(task_get_event_bitmap(task_get_current()), - events & ~event_mask); + atomic_or(¤t_task->events, events & ~event_mask); return events & event_mask; } diff --git a/core/cortex-m0/task.c b/core/cortex-m0/task.c index d26a82b6d2..1ab82d7d24 100644 --- a/core/cortex-m0/task.c +++ b/core/cortex-m0/task.c @@ -400,6 +400,34 @@ uint32_t task_wait_event(int timeout_us) return __wait_evt(timeout_us, TASK_ID_IDLE); } +uint32_t task_wait_event_mask(uint32_t event_mask, int timeout_us) +{ + uint64_t deadline = get_time().val + timeout_us; + uint32_t events = 0; + int time_remaining_us = timeout_us; + + /* Add the timer event to the mask so we can indicate a timeout */ + event_mask |= TASK_EVENT_TIMER; + + while (!(events & event_mask)) { + /* Collect events to re-post later */ + events |= __wait_evt(time_remaining_us, TASK_ID_IDLE); + + time_remaining_us = deadline - get_time().val; + if (timeout_us > 0 && time_remaining_us <= 0) { + /* Ensure we return a TIMER event if we timeout */ + events |= TASK_EVENT_TIMER; + break; + } + } + + /* Re-post any other events collected */ + if (events & ~event_mask) + atomic_or(¤t_task->events, events & ~event_mask); + + return events & event_mask; +} + void task_enable_irq(int irq) { CPU_NVIC_EN(0) = 1 << irq; diff --git a/core/host/task.c b/core/host/task.c index 98a77b8e41..53f722e8b7 100644 --- a/core/host/task.c +++ b/core/host/task.c @@ -196,6 +196,34 @@ uint32_t task_wait_event(int timeout_us) return ret; } +uint32_t task_wait_event_mask(uint32_t event_mask, int timeout_us) +{ + uint64_t deadline = get_time().val + timeout_us; + uint32_t events = 0; + int time_remaining_us = timeout_us; + + /* Add the timer event to the mask so we can indicate a timeout */ + event_mask |= TASK_EVENT_TIMER; + + while (!(events & event_mask)) { + /* Collect events to re-post later */ + events |= task_wait_event(time_remaining_us); + + time_remaining_us = deadline - get_time().val; + if (timeout_us > 0 && time_remaining_us <= 0) { + /* Ensure we return a TIMER event if we timeout */ + events |= TASK_EVENT_TIMER; + break; + } + } + + /* Re-post any other events collected */ + if (events & ~event_mask) + tasks[task_get_current()].event |= events & ~event_mask; + + return events & event_mask; +} + void mutex_lock(struct mutex *mtx) { int value = 0; |