Note! This project has moved to github.com/armmbed/mbed-events

Dependents:   SimpleHTTPExample

This repository has been superceded

This project has moved to mbed-events

Composable event loops combine the cheap synchronicity of event loops with the composability of preempted threads.

Two modular event queue classes are provided:

  • EventLoop - for loops coupled with a c++ managed thread
  • EventQueue - for manually managed event queues

The Event class takes advantage of the extensibility of FuncPtr to allow an event to be passed through APIs as a normal function.

More information on composable event loops.

Committer:
Christopher Haster
Date:
Wed Apr 20 12:40:18 2016 -0500
Revision:
1:2202c19570e5
Parent:
0:b1b901ae3696
Child:
2:11cda6bead99
Fix several boundary conditions

- Non-volatile queue optimized out loop
- Timeout occured before timer
- Race conditions in event_register

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Christopher Haster 0:b1b901ae3696 1 #include <EventQueue.h>
Christopher Haster 0:b1b901ae3696 2 #include "mbed.h"
Christopher Haster 0:b1b901ae3696 3
Christopher Haster 0:b1b901ae3696 4
Christopher Haster 0:b1b901ae3696 5 static void wakeup() {}
Christopher Haster 0:b1b901ae3696 6
Christopher Haster 1:2202c19570e5 7 void EventQueue::dispatch(int ms) {
Christopher Haster 0:b1b901ae3696 8 mbed::Timer timer;
Christopher Haster 0:b1b901ae3696 9 mbed::Timeout timeout;
Christopher Haster 0:b1b901ae3696 10 timer.start();
Christopher Haster 1:2202c19570e5 11 timeout.attach_us(wakeup, ms * 1000);
Christopher Haster 0:b1b901ae3696 12
Christopher Haster 0:b1b901ae3696 13 while (true) {
Christopher Haster 0:b1b901ae3696 14 while (_queue) {
Christopher Haster 0:b1b901ae3696 15 _queue->callback(_queue->data);
Christopher Haster 0:b1b901ae3696 16 _queue = _queue->next;
Christopher Haster 0:b1b901ae3696 17 }
Christopher Haster 0:b1b901ae3696 18
Christopher Haster 1:2202c19570e5 19 if (ms >= 0 && timer.read_ms() >= ms) {
Christopher Haster 0:b1b901ae3696 20 break;
Christopher Haster 0:b1b901ae3696 21 }
Christopher Haster 0:b1b901ae3696 22
Christopher Haster 0:b1b901ae3696 23 __WFI();
Christopher Haster 0:b1b901ae3696 24 }
Christopher Haster 0:b1b901ae3696 25 }
Christopher Haster 0:b1b901ae3696 26
Christopher Haster 0:b1b901ae3696 27 void EventQueue::event_register(struct event *event) {
Christopher Haster 0:b1b901ae3696 28 __disable_irq();
Christopher Haster 1:2202c19570e5 29 for (struct event *volatile *p = &_queue;; p = &(*p)->next) {
Christopher Haster 0:b1b901ae3696 30 if (!*p) {
Christopher Haster 0:b1b901ae3696 31 event->next = 0;
Christopher Haster 0:b1b901ae3696 32 *p = event;
Christopher Haster 0:b1b901ae3696 33 break;
Christopher Haster 0:b1b901ae3696 34 } else if (*p == event) {
Christopher Haster 0:b1b901ae3696 35 break;
Christopher Haster 0:b1b901ae3696 36 }
Christopher Haster 0:b1b901ae3696 37 }
Christopher Haster 0:b1b901ae3696 38 __enable_irq();
Christopher Haster 0:b1b901ae3696 39 }
Christopher Haster 0:b1b901ae3696 40
Christopher Haster 0:b1b901ae3696 41 void EventQueue::event_unregister(struct event *event) {
Christopher Haster 0:b1b901ae3696 42 __disable_irq();
Christopher Haster 1:2202c19570e5 43 for (struct event *volatile *p = &_queue; *p; p = &(*p)->next) {
Christopher Haster 0:b1b901ae3696 44 if (*p == event) {
Christopher Haster 0:b1b901ae3696 45 *p = event->next;
Christopher Haster 0:b1b901ae3696 46 break;
Christopher Haster 0:b1b901ae3696 47 }
Christopher Haster 0:b1b901ae3696 48 }
Christopher Haster 0:b1b901ae3696 49 __enable_irq();
Christopher Haster 0:b1b901ae3696 50 }
Christopher Haster 0:b1b901ae3696 51