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:
Fri Apr 22 02:21:25 2016 -0500
Revision:
9:2b0910397844
Parent:
7:dcd589b578ca
Child:
10:62767e708bb6
Move to yield in loop when rtos is present

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Christopher Haster 2:11cda6bead99 1 #include "EventQueue.h"
Christopher Haster 2:11cda6bead99 2 #include "Event.h"
Christopher Haster 0:b1b901ae3696 3
Christopher Haster 9:2b0910397844 4 #ifndef EVENTS_NO_RTOS
Christopher Haster 9:2b0910397844 5 #include "rtos.h"
Christopher Haster 9:2b0910397844 6 #endif
Christopher Haster 9:2b0910397844 7
Christopher Haster 0:b1b901ae3696 8
Christopher Haster 2:11cda6bead99 9 EventQueue::EventQueue() {
Christopher Haster 5:9963a617f952 10 _queue = 0;
Christopher Haster 2:11cda6bead99 11 _tick = 0;
Christopher Haster 2:11cda6bead99 12 _timer.start();
Christopher Haster 2:11cda6bead99 13 _ticker.attach_us(this, &EventQueue::tick, (1 << 16) * 1000);
Christopher Haster 2:11cda6bead99 14 }
Christopher Haster 2:11cda6bead99 15
Christopher Haster 2:11cda6bead99 16 unsigned EventQueue::get_tick() {
Christopher Haster 2:11cda6bead99 17 return _tick + (unsigned)_timer.read_ms();
Christopher Haster 2:11cda6bead99 18 }
Christopher Haster 2:11cda6bead99 19
Christopher Haster 2:11cda6bead99 20 void EventQueue::tick() {
Christopher Haster 2:11cda6bead99 21 _timer.reset();
Christopher Haster 2:11cda6bead99 22 _tick += 1 << 16;
Christopher Haster 2:11cda6bead99 23 }
Christopher Haster 2:11cda6bead99 24
Christopher Haster 2:11cda6bead99 25 void EventQueue::wakeup() {
Christopher Haster 2:11cda6bead99 26
Christopher Haster 2:11cda6bead99 27 }
Christopher Haster 0:b1b901ae3696 28
Christopher Haster 1:2202c19570e5 29 void EventQueue::dispatch(int ms) {
Christopher Haster 0:b1b901ae3696 30 mbed::Timeout timeout;
Christopher Haster 2:11cda6bead99 31 struct event exit;
Christopher Haster 2:11cda6bead99 32
Christopher Haster 2:11cda6bead99 33 if (ms >= 0) {
Christopher Haster 2:11cda6bead99 34 memset(&exit, 0, sizeof exit);
Christopher Haster 2:11cda6bead99 35 event_register(&exit, ms);
Christopher Haster 2:11cda6bead99 36 }
Christopher Haster 0:b1b901ae3696 37
Christopher Haster 0:b1b901ae3696 38 while (true) {
Christopher Haster 0:b1b901ae3696 39 while (_queue) {
Christopher Haster 2:11cda6bead99 40 int diff = (int)(_queue->target - get_tick());
Christopher Haster 2:11cda6bead99 41 if (diff > 0) {
Christopher Haster 2:11cda6bead99 42 timeout.attach_us(this, &EventQueue::wakeup, diff * 1000);
Christopher Haster 2:11cda6bead99 43 break;
Christopher Haster 2:11cda6bead99 44 }
Christopher Haster 2:11cda6bead99 45
Christopher Haster 2:11cda6bead99 46 struct event *volatile e = _queue;
Christopher Haster 0:b1b901ae3696 47 _queue = _queue->next;
Christopher Haster 2:11cda6bead99 48 e->registered = false;
Christopher Haster 2:11cda6bead99 49
Christopher Haster 2:11cda6bead99 50 if (e == &exit) {
Christopher Haster 2:11cda6bead99 51 return;
Christopher Haster 2:11cda6bead99 52 }
Christopher Haster 0:b1b901ae3696 53
Christopher Haster 2:11cda6bead99 54 e->callback(e->data);
Christopher Haster 2:11cda6bead99 55
Christopher Haster 2:11cda6bead99 56 if (e->period >= 0) {
Christopher Haster 2:11cda6bead99 57 event_register(e, e->period);
Christopher Haster 2:11cda6bead99 58 }
Christopher Haster 0:b1b901ae3696 59 }
Christopher Haster 0:b1b901ae3696 60
Christopher Haster 9:2b0910397844 61 #ifndef EVENTS_NO_RTOS
Christopher Haster 9:2b0910397844 62 Thread::yield();
Christopher Haster 9:2b0910397844 63 #else
Christopher Haster 0:b1b901ae3696 64 __WFI();
Christopher Haster 9:2b0910397844 65 #endif
Christopher Haster 0:b1b901ae3696 66 }
Christopher Haster 0:b1b901ae3696 67 }
Christopher Haster 0:b1b901ae3696 68
Christopher Haster 2:11cda6bead99 69 void EventQueue::event_register(struct event *event, int ms) {
Christopher Haster 2:11cda6bead99 70 if (event->registered) {
Christopher Haster 2:11cda6bead99 71 return;
Christopher Haster 2:11cda6bead99 72 }
Christopher Haster 2:11cda6bead99 73
Christopher Haster 2:11cda6bead99 74 event->target = get_tick() + (unsigned)ms;
Christopher Haster 2:11cda6bead99 75 event->registered = true;
Christopher Haster 2:11cda6bead99 76
Christopher Haster 6:31c141d3bcc7 77 uint32_t primask = __get_PRIMASK();
Christopher Haster 0:b1b901ae3696 78 __disable_irq();
Christopher Haster 6:31c141d3bcc7 79
Christopher Haster 2:11cda6bead99 80 struct event *volatile *p = &_queue;
Christopher Haster 2:11cda6bead99 81 while (*p && (*p)->target < event->target) {
Christopher Haster 2:11cda6bead99 82 p = &(*p)->next;
Christopher Haster 0:b1b901ae3696 83 }
Christopher Haster 2:11cda6bead99 84
Christopher Haster 2:11cda6bead99 85 event->next = *p;
Christopher Haster 2:11cda6bead99 86 *p = event;
Christopher Haster 6:31c141d3bcc7 87
Christopher Haster 7:dcd589b578ca 88 __set_PRIMASK(primask);
Christopher Haster 0:b1b901ae3696 89 }
Christopher Haster 0:b1b901ae3696 90
Christopher Haster 0:b1b901ae3696 91 void EventQueue::event_unregister(struct event *event) {
Christopher Haster 6:31c141d3bcc7 92 uint32_t primask = __get_PRIMASK();
Christopher Haster 0:b1b901ae3696 93 __disable_irq();
Christopher Haster 6:31c141d3bcc7 94
Christopher Haster 1:2202c19570e5 95 for (struct event *volatile *p = &_queue; *p; p = &(*p)->next) {
Christopher Haster 0:b1b901ae3696 96 if (*p == event) {
Christopher Haster 0:b1b901ae3696 97 *p = event->next;
Christopher Haster 0:b1b901ae3696 98 break;
Christopher Haster 0:b1b901ae3696 99 }
Christopher Haster 0:b1b901ae3696 100 }
Christopher Haster 6:31c141d3bcc7 101
Christopher Haster 7:dcd589b578ca 102 __set_PRIMASK(primask);
Christopher Haster 0:b1b901ae3696 103 }
Christopher Haster 0:b1b901ae3696 104