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 09:47:21 2016 -0500
Revision:
16:ff5d48fcce1b
Parent:
14:5abf2ccf2dbf
Child:
20:2f9d9c53a5af
Make rtos requirement

Move to yield over wfi
Remove problematic timeout logic as optimization

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