Note! This project has moved to github.com/armmbed/mbed-events
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.
EventQueue.cpp
- Committer:
- Christopher Haster
- Date:
- 2016-04-20
- Revision:
- 2:11cda6bead99
- Parent:
- 1:2202c19570e5
- Child:
- 5:9963a617f952
File content as of revision 2:11cda6bead99:
#include "EventQueue.h" #include "Event.h" EventQueue::EventQueue() { _tick = 0; _timer.start(); _ticker.attach_us(this, &EventQueue::tick, (1 << 16) * 1000); } unsigned EventQueue::get_tick() { return _tick + (unsigned)_timer.read_ms(); } void EventQueue::tick() { _timer.reset(); _tick += 1 << 16; } void EventQueue::wakeup() { } void EventQueue::dispatch(int ms) { mbed::Timeout timeout; struct event exit; if (ms >= 0) { memset(&exit, 0, sizeof exit); event_register(&exit, ms); } while (true) { while (_queue) { int diff = (int)(_queue->target - get_tick()); if (diff > 0) { timeout.attach_us(this, &EventQueue::wakeup, diff * 1000); break; } struct event *volatile e = _queue; _queue = _queue->next; e->registered = false; if (e == &exit) { return; } e->callback(e->data); if (e->period >= 0) { event_register(e, e->period); } } __WFI(); } } void EventQueue::event_register(struct event *event, int ms) { if (event->registered) { return; } event->target = get_tick() + (unsigned)ms; event->registered = true; __disable_irq(); struct event *volatile *p = &_queue; while (*p && (*p)->target < event->target) { p = &(*p)->next; } event->next = *p; *p = event; __enable_irq(); } void EventQueue::event_unregister(struct event *event) { __disable_irq(); for (struct event *volatile *p = &_queue; *p; p = &(*p)->next) { if (*p == event) { *p = event->next; break; } } __enable_irq(); }