Skip to content
This repository was archived by the owner on Aug 19, 2021. It is now read-only.

Commit 17dfdd5

Browse files
committed
Updated documentation
- EventQueue documentation - README documentation
2 parents 3338ca1 + fe021da commit 17dfdd5

File tree

8 files changed

+492
-177
lines changed

8 files changed

+492
-177
lines changed

EventQueue.h

Lines changed: 89 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -39,29 +39,37 @@ namespace events {
3939

4040
/** EventQueue
4141
*
42-
* Flexible event queue
42+
* Flexible event queue for dispatching events
4343
*/
4444
class EventQueue {
4545
public:
46-
/** Create an event queue
46+
/** EventQueue lifetime
4747
*
48-
* @param queue_size Size of buffer to use for events
49-
* (default: EVENTS_QUEUE_SIZE)
50-
* @param queue_pointer Pointer to memory region to use for events
51-
* (default: NULL)
52-
*/
53-
EventQueue(unsigned queue_size=EVENTS_QUEUE_SIZE,
54-
unsigned char *queue_pointer=NULL);
55-
56-
/** Destroy an event queue
48+
* Create and destroy event queues. The event queue either allocates
49+
* a buffer of the specified size with malloc or uses the user provided
50+
* buffer.
51+
*
52+
* @param size Size of buffer to use for events in bytes
53+
* (default to EVENTS_QUEUE_SIZE)
54+
* @param buffer Pointer to buffer to use for events
55+
* (default to NULL)
5756
*/
57+
EventQueue(unsigned size=EVENTS_QUEUE_SIZE, unsigned char *buffer=NULL);
5858
~EventQueue();
5959

60-
/** Dispatch pending events
61-
* @param ms Time to wait for events in milliseconds, 0 will return
62-
* immediately if no events are pending, a negative
63-
* value will dispatch events forever
64-
* (default: -1)
60+
/** Dispatch events
61+
*
62+
* Executes events until the specified milliseconds have passed.
63+
* If ms is negative, the dispatch function will dispatch events
64+
* indefinitely or until break_dispatch is called on this queue.
65+
*
66+
* When called with a finite timeout, the dispatch function is garunteed
67+
* to terminate. When called with a timeout of 0, the dispatch function
68+
* does not wait and is irq safe.
69+
*
70+
* @param ms Time to wait for events in milliseconds, a negative
71+
* value will dispatch events indefinitely
72+
* (default to -1)
6573
*/
6674
void dispatch(int ms);
6775
void dispatch() { dispatch(-1); }
@@ -73,27 +81,43 @@ class EventQueue {
7381
*/
7482
void break_dispatch();
7583

76-
/* Monotonic counter for the event queue
77-
* @return A monotonically incrementing counter in milliseconds
78-
* this count intentionally overflows to 0 after 2^32-1
84+
/** Millisecond counter
85+
*
86+
* Returns the underlying tick of the event queue represented as the
87+
* number of milliseconds that have passed since an arbitrary point in
88+
* time. Intentionally overflows to 0 after 2^32-1.
89+
*
90+
* @return The underlying tick of the event queue in milliseconds
7991
*/
8092
unsigned tick();
8193

82-
/** Cancel events that are in flight
94+
/** Cancel an in-flight event
95+
*
96+
* Attempts to cancel an event referenced by the unique id returned from
97+
* one of the call functions. It is safe to call cancel after an event
98+
* has already been dispatched.
99+
*
100+
* The cancel function is irq safe.
83101
*
84-
* If event has already been dispatched or does not exist, no error occurs.
102+
* If called while the event queue's dispatch loop is active, the cancel
103+
* function does not garuntee that the event will not execute after it
104+
* returns, as the event may have already begun executing.
85105
*
86-
* @param id Event id to cancel
87-
* @note This can not stop a currently executing event
106+
* @param id Unique id of the event
88107
*/
89108
void cancel(int id);
90109

91110
/** Background an event queue onto a single-shot timer
92111
*
93112
* The provided update function will be called to indicate when the queue
94113
* should be dispatched. A negative timeout will be passed to the update
95-
* function when the timer is no longer needed. A null update function
96-
* will disable the existing timer.
114+
* function when the time is no longer needed.
115+
*
116+
* Passing a null update function disables the existing timre.
117+
*
118+
* The background function allows an event queue to take advantage of
119+
* hardware timers or even other event loops, allowing an event queue to
120+
* be effectively backgrounded.
97121
*
98122
* @param update Function called to indicate when the queue should be
99123
* dispatched
@@ -103,20 +127,33 @@ class EventQueue {
103127
/** Chain an event queue onto another event queue
104128
*
105129
* After chaining a queue to a target, calling dispatch on the target
106-
* queue will also dispatch events from this queue. The queues will use
107-
* their own buffers and events are handled independently. A null queue
108-
* as the target will unchain the queue.
130+
* queue will also dispatch events from this queue. The queues use
131+
* their own buffers and events must be handled independently.
132+
*
133+
* A null queue as the target will unchain the existing queue.
109134
*
110-
* @param target Queue to chain onto
135+
* The chain function allows multiple event queuest to be composed,
136+
* sharing the context of a dispatch loop while still being managed
137+
* independently
138+
*
139+
* @param target Queue that will dispatch this queue's events as a
140+
* part of its dispatch loop
111141
*/
112142
void chain(EventQueue *target);
113143

114144
/** Post an event to the queue
115145
*
116-
* @param f Function to call on event dispatch
146+
* The specified callback will be executed in the context of the event
147+
* queue's dispatch loop.
148+
*
149+
* The call function is irq safe and can act as a mechanism for moving
150+
* events out of irq contexts.
151+
*
152+
* @param f Function to execute in the context of the dispatch loop
117153
* @param a0..a4 Arguments to pass to the callback
118-
* @return A positive id representing the event in the queue,
119-
* or 0 on failure
154+
* @return A unique id that represents the posted event and can
155+
* be passed to cancel, or an id of 0 if there is not
156+
* enough memory to allocate the event.
120157
*/
121158
template <typename F>
122159
int call(F f) {
@@ -157,11 +194,18 @@ class EventQueue {
157194

158195
/** Post an event to the queue after a specified delay
159196
*
160-
* @param f Function to call on event dispatch
197+
* The specified callback will be executed in the context of the event
198+
* queue's dispatch loop.
199+
*
200+
* The call_in function is irq safe and can act as a mechanism for moving
201+
* events out of irq contexts.
202+
*
203+
* @param f Function to execute in the context of the dispatch loop
161204
* @param a0..a4 Arguments to pass to the callback
162205
* @param ms Time to delay in milliseconds
163-
* @return A positive id representing the event in the queue,
164-
* or 0 on failure
206+
* @return A unique id that represents the posted event and can
207+
* be passed to cancel, or an id of 0 if there is not
208+
* enough memory to allocate the event.
165209
*/
166210
template <typename F>
167211
int call_in(int ms, F f) {
@@ -203,11 +247,18 @@ class EventQueue {
203247

204248
/** Post an event to the queue periodically
205249
*
206-
* @param f Function to call on event dispatch
250+
* The specified callback will be executed in the context of the event
251+
* queue's dispatch loop.
252+
*
253+
* The call_every function is irq safe and can act as a mechanism for
254+
* moving events out of irq contexts.
255+
*
256+
* @param f Function to execute in the context of the dispatch loop
207257
* @param a0..a4 Arguments to pass to the callback
208258
* @param ms Period of the event in milliseconds
209-
* @return A positive id representing the event in the queue,
210-
* or 0 on failure
259+
* @return A unique id that represents the posted event and can
260+
* be passed to cancel, or an id of 0 if there is not
261+
* enough memory to allocate the event.
211262
*/
212263
template <typename F>
213264
int call_every(int ms, F f) {

README.md

Lines changed: 63 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
## The Events Library ##
1+
## The mbed-events library ##
22

3-
The events library provides a flexible event queue for scheduling events.
3+
The mbed-events library provides a flexible queue for scheduling events.
44

55
``` cpp
66
#include "mbed_events.h"
@@ -15,57 +15,52 @@ int main() {
1515
queue.call_in(2000, printf, "called in 2 seconds\n");
1616
queue.call_every(1000, printf, "called every 1 seconds\n");
1717

18-
// executed by the dispatch method
18+
// events are executed by the dispatch method
1919
queue.dispatch();
2020
}
2121
```
2222

23+
The mbed-events library can be used as a normal event loop, or it can be
24+
backgrounded on a single hardware timer or even another event loop. It is
25+
both thread and irq safe, and provides functions for easily composing
26+
independent event queues.
27+
28+
The mbed-events library can act as a drop-in scheduler, provide synchronization
29+
between multiple threads, or just act as a mechanism for moving events out of
30+
interrupt contexts.
2331

2432
### Usage ###
2533

26-
The core API of the events library is contained in the
27-
[EventQueue](EventQueue.h) class.
34+
The core of the mbed-events library is the [EventQueue](EventQueue.h) class,
35+
which represents a single event queue. The `EventQueue::dispatch` function
36+
runs the queue, providing the context for executing events.
2837

2938
``` cpp
30-
// Creates an event queue with 2048 bytes of buffer space to use
31-
// for enqueueing events. With no argument, the default buffer is
32-
// allocated with enough space for 32 Callback classes.
33-
EventQueue queue(2048);
34-
35-
// Enqueues events on the underlying event queue
36-
queue.call(printf, "hi!\n");
37-
38-
// The dispatch method acts as the core entry point into the event loop
39-
// A millisecond timeout can be provided to return from the event loop
40-
queue.dispatch(500);
39+
// Creates an event queue enough buffer space for 32 Callbacks. This
40+
// is the default if no argument was provided. Alternatively the size
41+
// can just be specified in bytes.
42+
EventQueue queue(32*EVENTS_EVENT_SIZE);
43+
44+
// Events can be posted to the underlying event queue with dynamic
45+
// context allocated from the specified buffer
46+
queue.call(printf, "hello %d %d %d %d\n", 1, 2, 3, 4);
47+
queue.call(Callback<void()>(&serial, &Serial::printf), "hi\n");
48+
49+
// The dispatch function provides the context for the running the queue
50+
// and can take a millisecond timeout to run for a fixed time or to just
51+
// dispatch any pending events
52+
queue.dispatch();
4153
```
4254
43-
Additionally, the events library provides the [EventLoop](EventLoop.h) class,
44-
which combines the EventQueue with a Thread.
45-
46-
``` cpp
47-
// Creates a high priority event loop.
48-
EventLoop loop(osHighPriority);
49-
50-
// Starts the loop in a separate thread
51-
loop.start();
52-
53-
// Posting events is thread and irq safe
54-
loop.call(doit);
55-
56-
// Stops the event loop cleanly
57-
loop.stop();
58-
```
59-
60-
The EventQueue and EvenLoop classes provide several call functions for
61-
sending events. The call functions are thread and irq safe and don't need
62-
the underlying loop to be running.
55+
The EventQueue class provides several call functions for posting events
56+
to the underlying event queue. The call functions are thread and irq safe,
57+
don't need the underlying loop to be running, and provide an easy mechanism
58+
for moving events out of interrupt contexts.
6359
6460
``` cpp
6561
// Simple call function registers events to be called as soon as possible
6662
queue.call(doit);
6763
queue.call(printf, "called immediately\n");
68-
queue.call(Callback<void(char)>(&serial, &Serial::printf), "hello\n");
6964
7065
// The call_in function registers events to be called after a delay
7166
// specified in milliseconds
@@ -78,30 +73,48 @@ queue.call_every(2000, doit_every_two_seconds);
7873
queue.call_every(400, printf, "called every 0.4 seconds\n");
7974
```
8075

81-
All call calls return an integer id that uniquely represents the event
82-
on the event queue. The call calls can not block, so 0 is returned if
83-
there is no memory or the queue's event size is exceeded.
76+
The call functions return an id that uniquely represents the event in the
77+
the event queue. This id can be passed to `EventQueue::cancel` to cancel
78+
an in-flight event.
8479

8580
``` cpp
86-
// The event id is uniqueue to the queue
81+
// The event id uniquely represents the event in the queue
8782
int id = queue.call_in(100, printf, "will this work?\n");
8883

89-
// An id of 0 indicates an error
84+
// If there was not enough memory necessary to allocate the event,
85+
// an id of 0 is returned from the call functions
9086
if (id) {
9187
error("oh no!");
9288
}
9389

94-
// Events can also be cancelled
90+
// Events can be cancelled as long as they have not been dispatched. If the
91+
// event has already expired, cancel has no side-effects.
9592
queue.cancel(id);
9693
```
9794

95+
Event queuest easily align with module boundaries, where internal state can
96+
be implicitely synchronized through event dispatch. Multiple modules can
97+
use independent event queues, but still be composed through the
98+
`EventQueue::chain` function.
99+
100+
``` cpp
101+
// Create some event queues with pending events
102+
EventQueue a;
103+
a.call(printf, "hello from a!\n");
98104

99-
### Porting ###
105+
EventQueue b;
106+
b.call(printf, "hello from b!\n");
100107

101-
The events library actually provides a C++ and C API. To port to a different
102-
platform, the events library only needs implementations of the following
103-
files:
108+
EventQueue c;
109+
c.call(printf, "hello from c!\n");
110+
111+
// Chain c and b onto a's event queue. Both c and b will be dispatched
112+
// in the context of a's dispatch function.
113+
c.chain(&a);
114+
b.chain(&a);
115+
116+
// Dispatching a will in turn dispatch b and c, printing hello from
117+
// all three queues
118+
a.dispatch();
119+
```
104120

105-
- [events_tick.h](events-c/events_tick.h) - Monotonic counter with millisecond precision
106-
- [events_mutex.h](events-c/events_mutex.h) - IRQ safe critical section
107-
- [events_sema.h](events-c/events_sema.h) - Binary semaphore with timeout

0 commit comments

Comments
 (0)