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:
Tue May 10 07:51:44 2016 -0500
Revision:
14:5abf2ccf2dbf
Parent:
10:62767e708bb6
Child:
15:92d7c0b8a0f5
Move to internal memory management

Allows an event to be enqueued multiple times before being handled.
Downside is cancel is non-trivial to support.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Christopher Haster 0:b1b901ae3696 1 /* EventQueue
Christopher Haster 0:b1b901ae3696 2 *
Christopher Haster 0:b1b901ae3696 3 * Flexible queue for managing events
Christopher Haster 0:b1b901ae3696 4 */
Christopher Haster 0:b1b901ae3696 5 #ifndef EVENT_QUEUE_H
Christopher Haster 0:b1b901ae3696 6 #define EVENT_QUEUE_H
Christopher Haster 0:b1b901ae3696 7
Christopher Haster 10:62767e708bb6 8 #include "Timer.h"
Christopher Haster 10:62767e708bb6 9 #include "Ticker.h"
Christopher Haster 14:5abf2ccf2dbf 10 #include "FuncPtr.h"
Christopher Haster 14:5abf2ccf2dbf 11 #include "Binder.h"
Christopher Haster 2:11cda6bead99 12
Christopher Haster 0:b1b901ae3696 13
Christopher Haster 0:b1b901ae3696 14 /** Flexible queue for managing events
Christopher Haster 0:b1b901ae3696 15 */
Christopher Haster 0:b1b901ae3696 16 class EventQueue {
Christopher Haster 0:b1b901ae3696 17 public:
Christopher Haster 2:11cda6bead99 18 /** Create an event queue
Christopher Haster 14:5abf2ccf2dbf 19 * @param event_count Number of events to allow enqueueing at once
Christopher Haster 14:5abf2ccf2dbf 20 * @param event_context Max size of arguments passed with an event
Christopher Haster 2:11cda6bead99 21 */
Christopher Haster 14:5abf2ccf2dbf 22 EventQueue(unsigned event_count=32,
Christopher Haster 14:5abf2ccf2dbf 23 unsigned event_context=0);
Christopher Haster 14:5abf2ccf2dbf 24 virtual ~EventQueue();
Christopher Haster 2:11cda6bead99 25
Christopher Haster 0:b1b901ae3696 26 /** Dispatch pending events
Christopher Haster 1:2202c19570e5 27 * @param ms Time to wait for events in milliseconds,
Christopher Haster 0:b1b901ae3696 28 * 0 indicates to return immediately if no events are pending
Christopher Haster 0:b1b901ae3696 29 */
Christopher Haster 1:2202c19570e5 30 void dispatch(int ms=-1);
Christopher Haster 0:b1b901ae3696 31
Christopher Haster 2:11cda6bead99 32 /** Get current tick of the event queue
Christopher Haster 2:11cda6bead99 33 * @return Number of milliseconds since the queue was instantiated,
Christopher Haster 2:11cda6bead99 34 * this count intentionally overflows to 0 after 2^32-1
Christopher Haster 2:11cda6bead99 35 */
Christopher Haster 2:11cda6bead99 36 unsigned get_tick();
Christopher Haster 2:11cda6bead99 37
Christopher Haster 0:b1b901ae3696 38 private:
Christopher Haster 0:b1b901ae3696 39 struct event {
Christopher Haster 1:2202c19570e5 40 struct event *volatile next;
Christopher Haster 2:11cda6bead99 41 unsigned target;
Christopher Haster 2:11cda6bead99 42 int period;
Christopher Haster 2:11cda6bead99 43
Christopher Haster 14:5abf2ccf2dbf 44 void (*dispatch)(void *p);
Christopher Haster 14:5abf2ccf2dbf 45 // data follows
Christopher Haster 0:b1b901ae3696 46 };
Christopher Haster 0:b1b901ae3696 47
Christopher Haster 14:5abf2ccf2dbf 48 struct event *alloc(unsigned size, int ms=-1);
Christopher Haster 14:5abf2ccf2dbf 49 void dealloc(struct event *);
Christopher Haster 14:5abf2ccf2dbf 50
Christopher Haster 14:5abf2ccf2dbf 51 void trigger(struct event *e, int delay);
Christopher Haster 14:5abf2ccf2dbf 52
Christopher Haster 14:5abf2ccf2dbf 53 template <typename F>
Christopher Haster 14:5abf2ccf2dbf 54 bool trigger(F func, int delay, int period, int tolerance, int ms=-1) {
Christopher Haster 14:5abf2ccf2dbf 55 struct event *e = alloc(sizeof(F), ms);
Christopher Haster 14:5abf2ccf2dbf 56 if (!e) {
Christopher Haster 14:5abf2ccf2dbf 57 return false;
Christopher Haster 14:5abf2ccf2dbf 58 }
Christopher Haster 14:5abf2ccf2dbf 59
Christopher Haster 14:5abf2ccf2dbf 60 e->period = period;
Christopher Haster 14:5abf2ccf2dbf 61 (void)tolerance; // unused
Christopher Haster 14:5abf2ccf2dbf 62 e->dispatch = &F::thunk;
Christopher Haster 14:5abf2ccf2dbf 63 *reinterpret_cast<F*>(e+1) = func;
Christopher Haster 14:5abf2ccf2dbf 64
Christopher Haster 14:5abf2ccf2dbf 65 trigger(e, delay);
Christopher Haster 14:5abf2ccf2dbf 66 return true;
Christopher Haster 14:5abf2ccf2dbf 67 }
Christopher Haster 0:b1b901ae3696 68
Christopher Haster 2:11cda6bead99 69 void tick();
Christopher Haster 2:11cda6bead99 70 void wakeup();
Christopher Haster 2:11cda6bead99 71
Christopher Haster 14:5abf2ccf2dbf 72 unsigned _event_count;
Christopher Haster 14:5abf2ccf2dbf 73 unsigned _event_context;
Christopher Haster 14:5abf2ccf2dbf 74
Christopher Haster 2:11cda6bead99 75 struct event *volatile _queue;
Christopher Haster 14:5abf2ccf2dbf 76 struct event *volatile _free;
Christopher Haster 14:5abf2ccf2dbf 77 void *_mem;
Christopher Haster 14:5abf2ccf2dbf 78
Christopher Haster 2:11cda6bead99 79 unsigned _tick;
Christopher Haster 2:11cda6bead99 80 mbed::Ticker _ticker;
Christopher Haster 2:11cda6bead99 81 mbed::Timer _timer;
Christopher Haster 2:11cda6bead99 82
Christopher Haster 0:b1b901ae3696 83 template <typename F>
Christopher Haster 0:b1b901ae3696 84 friend class Event;
Christopher Haster 0:b1b901ae3696 85 };
Christopher Haster 0:b1b901ae3696 86
Christopher Haster 0:b1b901ae3696 87
Christopher Haster 0:b1b901ae3696 88 #endif