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:
Mon Apr 18 13:22:21 2016 -0500
Revision:
20:2f9d9c53a5af
Parent:
16:ff5d48fcce1b
Add event_pointer argument to avoid memory allocation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Christopher Haster 8:3c2a014bd907 1 #include "EventLoop.h"
Christopher Haster 16:ff5d48fcce1b 2 #include "rtos.h"
Christopher Haster 8:3c2a014bd907 3
Christopher Haster 8:3c2a014bd907 4
Christopher Haster 14:5abf2ccf2dbf 5 EventLoop::EventLoop(osPriority priority,
Christopher Haster 14:5abf2ccf2dbf 6 unsigned event_count,
Christopher Haster 14:5abf2ccf2dbf 7 unsigned event_context,
Christopher Haster 20:2f9d9c53a5af 8 unsigned char *event_pointer,
Christopher Haster 14:5abf2ccf2dbf 9 uint32_t stack_size,
Christopher Haster 14:5abf2ccf2dbf 10 unsigned char *stack_pointer)
Christopher Haster 20:2f9d9c53a5af 11 : EventQueue(event_count, event_context, event_pointer) {
Christopher Haster 8:3c2a014bd907 12 _running = false;
Christopher Haster 14:5abf2ccf2dbf 13 _priority = priority;
Christopher Haster 14:5abf2ccf2dbf 14 _stack_size = stack_size;
Christopher Haster 14:5abf2ccf2dbf 15 _stack_pointer = stack_pointer;
Christopher Haster 8:3c2a014bd907 16 }
Christopher Haster 8:3c2a014bd907 17
Christopher Haster 8:3c2a014bd907 18 EventLoop::EventLoop(bool start,
Christopher Haster 8:3c2a014bd907 19 osPriority priority,
Christopher Haster 14:5abf2ccf2dbf 20 unsigned event_count,
Christopher Haster 14:5abf2ccf2dbf 21 unsigned event_context,
Christopher Haster 20:2f9d9c53a5af 22 unsigned char *event_pointer,
Christopher Haster 8:3c2a014bd907 23 uint32_t stack_size,
Christopher Haster 14:5abf2ccf2dbf 24 unsigned char *stack_pointer)
Christopher Haster 20:2f9d9c53a5af 25 : EventQueue(event_count, event_context, event_pointer) {
Christopher Haster 8:3c2a014bd907 26 _running = false;
Christopher Haster 14:5abf2ccf2dbf 27 _priority = priority;
Christopher Haster 14:5abf2ccf2dbf 28 _stack_size = stack_size;
Christopher Haster 14:5abf2ccf2dbf 29 _stack_pointer = stack_pointer;
Christopher Haster 8:3c2a014bd907 30
Christopher Haster 8:3c2a014bd907 31 if (start) {
Christopher Haster 14:5abf2ccf2dbf 32 EventLoop::start();
Christopher Haster 8:3c2a014bd907 33 }
Christopher Haster 8:3c2a014bd907 34 }
Christopher Haster 8:3c2a014bd907 35
Christopher Haster 8:3c2a014bd907 36 EventLoop::~EventLoop() {
Christopher Haster 8:3c2a014bd907 37 stop();
Christopher Haster 8:3c2a014bd907 38 }
Christopher Haster 8:3c2a014bd907 39
Christopher Haster 16:ff5d48fcce1b 40 osStatus EventLoop::start() {
Christopher Haster 8:3c2a014bd907 41 if (_running) {
Christopher Haster 16:ff5d48fcce1b 42 return osOK;
Christopher Haster 8:3c2a014bd907 43 }
Christopher Haster 8:3c2a014bd907 44
Christopher Haster 8:3c2a014bd907 45 _running = true;
Christopher Haster 14:5abf2ccf2dbf 46 _thread = new Thread(run, this, _priority, _stack_size, _stack_pointer);
Christopher Haster 16:ff5d48fcce1b 47 if (!_thread) {
Christopher Haster 16:ff5d48fcce1b 48 return osErrorNoMemory;
Christopher Haster 16:ff5d48fcce1b 49 }
Christopher Haster 16:ff5d48fcce1b 50
Christopher Haster 16:ff5d48fcce1b 51 return osOK;
Christopher Haster 8:3c2a014bd907 52 }
Christopher Haster 8:3c2a014bd907 53
Christopher Haster 16:ff5d48fcce1b 54 osStatus EventLoop::stop() {
Christopher Haster 8:3c2a014bd907 55 if (!_running) {
Christopher Haster 16:ff5d48fcce1b 56 return osOK;
Christopher Haster 8:3c2a014bd907 57 }
Christopher Haster 8:3c2a014bd907 58
Christopher Haster 8:3c2a014bd907 59 Thread *thread = _thread;
Christopher Haster 8:3c2a014bd907 60 _thread = 0;
Christopher Haster 8:3c2a014bd907 61
Christopher Haster 8:3c2a014bd907 62 _running = false;
Christopher Haster 16:ff5d48fcce1b 63 while (true) {
Christopher Haster 16:ff5d48fcce1b 64 uint8_t state = thread->get_state();
Christopher Haster 16:ff5d48fcce1b 65 if (state == Thread::Inactive || state == osErrorParameter) {
Christopher Haster 16:ff5d48fcce1b 66 break;
Christopher Haster 16:ff5d48fcce1b 67 }
Christopher Haster 16:ff5d48fcce1b 68
Christopher Haster 16:ff5d48fcce1b 69 osStatus status = Thread::yield();
Christopher Haster 16:ff5d48fcce1b 70 if (status != osOK) {
Christopher Haster 16:ff5d48fcce1b 71 break;
Christopher Haster 16:ff5d48fcce1b 72 }
Christopher Haster 8:3c2a014bd907 73 }
Christopher Haster 8:3c2a014bd907 74
Christopher Haster 8:3c2a014bd907 75 delete thread;
Christopher Haster 16:ff5d48fcce1b 76 return osOK;
Christopher Haster 8:3c2a014bd907 77 }
Christopher Haster 8:3c2a014bd907 78
Christopher Haster 8:3c2a014bd907 79 void EventLoop::run(const void *p) {
Christopher Haster 8:3c2a014bd907 80 EventLoop *loop = (EventLoop *)p;
Christopher Haster 8:3c2a014bd907 81
Christopher Haster 8:3c2a014bd907 82 while (loop->_running) {
Christopher Haster 8:3c2a014bd907 83 loop->dispatch(0);
Christopher Haster 8:3c2a014bd907 84 Thread::yield();
Christopher Haster 8:3c2a014bd907 85 }
Christopher Haster 8:3c2a014bd907 86 }
Christopher Haster 8:3c2a014bd907 87