@@ -45,6 +45,8 @@ namespace events {
45
45
// Predeclared classes
46
46
template <typename F>
47
47
class Event ;
48
+ template <typename F, typename A>
49
+ class UserAllocatedEvent ;
48
50
49
51
/* *
50
52
* \defgroup events_EventQueue EventQueue class
@@ -60,10 +62,17 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
60
62
/* * Create an EventQueue
61
63
*
62
64
* Create an event queue. The event queue either allocates a buffer of
63
- * the specified size with malloc or uses the user provided buffer.
65
+ * the specified size with malloc or uses the user provided buffer or
66
+ * uses 1B dummy buffer if 0 size passed.
67
+ *
68
+ * 0 size queue is a special purpose queue to dispatch static events
69
+ * only (see UserAllocatedEvent). Such a queue gives the guarantee
70
+ * that no dynamic memory allocation will take place while queue
71
+ * creation and events posting & dispatching.
64
72
*
65
73
* @param size Size of buffer to use for events in bytes
66
74
* (default to EVENTS_QUEUE_SIZE)
75
+ * If 0 provided then 1B dummy buffer is used
67
76
* @param buffer Pointer to buffer to use for events
68
77
* (default to NULL)
69
78
*/
@@ -139,6 +148,34 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
139
148
*/
140
149
bool cancel (int id);
141
150
151
+ /* * Cancel an in-flight user allocated event
152
+ *
153
+ * Attempts to cancel an UserAllocatedEvent referenced by its address
154
+ * It is safe to call cancel after an event has already been dispatched.
155
+ *
156
+ * Event must be valid i.e. event must have not finished executing
157
+ * and must have been bound to this queue.
158
+ *
159
+ * The cancel function is IRQ safe.
160
+ *
161
+ * If called while the event queue's dispatch loop is active in another thread,
162
+ * the cancel function does not guarantee that the event will not execute after it
163
+ * returns, as the event may have already begun executing. A call made from
164
+ * the same thread as the dispatch loop will always succeed with a valid id.
165
+ *
166
+ * @param event Address of the event
167
+ * @return true if event was successfully cancelled
168
+ * false if event was not cancelled (invalid queue or executing already begun)
169
+ */
170
+ template <typename ... Args>
171
+ bool cancel (UserAllocatedEvent<Args...> *event)
172
+ {
173
+ if (event->_equeue != &_equeue) {
174
+ return false ;
175
+ }
176
+ return equeue_cancel_user_allocated (&_equeue, event);
177
+ }
178
+
142
179
/* * Query how much time is left for delayed event
143
180
*
144
181
* If the event is delayed, this function can be used to query how much time
@@ -158,6 +195,33 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
158
195
*/
159
196
int time_left (int id);
160
197
198
+ /* * Query how much time is left for delayed UserAllocatedEvent
199
+ *
200
+ * If the event is delayed, this function can be used to query how much time
201
+ * is left until the event is due to be dispatched.
202
+ *
203
+ * Event must be valid i.e. event must have not finished executing
204
+ * and must have been bound to this queue.
205
+ *
206
+ * This function is IRQ safe.
207
+ *
208
+ * @param event Address of the event
209
+ *
210
+ * @return Remaining time in milliseconds or
211
+ * 0 if event is already due to be dispatched or
212
+ * is currently executing.
213
+ * Undefined if id is invalid.
214
+ *
215
+ */
216
+ template <typename ... Args>
217
+ int time_left (UserAllocatedEvent<Args...> *event)
218
+ {
219
+ if (event && event->_equeue != &_equeue) {
220
+ return -1 ;
221
+ }
222
+ return equeue_timeleft_user_allocated (&_equeue, &event->_e );
223
+ }
224
+
161
225
/* * Background an event queue onto a single-shot timer-interrupt
162
226
*
163
227
* When updated, the event queue will call the provided update function
@@ -597,6 +661,53 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
597
661
template <typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args>
598
662
Event<void (Args...)> event (mbed::Callback<R(BoundArgs..., Args...)> cb, ContextArgs ...context_args);
599
663
664
+ /* * Creates an user allocated event bound to the event queue
665
+ *
666
+ * Constructs an user allocated event bound to the specified event queue.
667
+ * The specified callback acts as the target for the event and is executed
668
+ * in the context of the event queue's dispatch loop once posted.
669
+ *
670
+ * @code
671
+ * #include "mbed.h"
672
+ *
673
+ * void handler(int data) { ... }
674
+ *
675
+ * class Device {
676
+ * public:
677
+ * void handler(int data) { ... }
678
+ * };
679
+ *
680
+ * Device dev;
681
+ *
682
+ * // queue with not internal storage for dynamic events
683
+ * // accepts only user allocated events
684
+ * static EventQueue queue(0);
685
+ * // Create events
686
+ * static auto e1 = make_user_allocated_event(&dev, Device::handler, 2);
687
+ * static auto e2 = queue.make_user_allocated_event(handler, 3);
688
+ *
689
+ * int main()
690
+ * {
691
+ * e1.call_on(&queue);
692
+ * e2.call();
693
+ *
694
+ * queue.dispatch(1);
695
+ * }
696
+ * @endcode
697
+ *
698
+ * @param f Function to execute when the event is dispatched
699
+ * @return Event that will dispatch on the specific queue
700
+ */
701
+ template <typename F, typename ... ArgTs>
702
+ UserAllocatedEvent<F, void (ArgTs...)> make_user_allocated_event (F f, ArgTs... args);
703
+
704
+ /* * Creates an user allocated event bound to the event queue
705
+ * @see EventQueue::make_user_allocated_event
706
+ */
707
+ template <typename T, typename R, typename ... ArgTs>
708
+ UserAllocatedEvent<mbed::Callback<void (ArgTs...)>, void (ArgTs...)> make_user_allocated_event (T *obj, R(T::*method)(ArgTs... args), ArgTs... args);
709
+
710
+
600
711
#else
601
712
602
713
/* * Calls an event on the queue
@@ -1068,12 +1179,50 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
1068
1179
*/
1069
1180
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename ... ArgTs>
1070
1181
Event<void (ArgTs...)> event (mbed::Callback<R(B0, B1, B2, B3, B4, ArgTs...)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
1182
+
1183
+ /* * Creates an user allocated event bound to the event queue
1184
+ *
1185
+ * Constructs an user allocated event bound to the specified event queue.
1186
+ * The specified callback acts as the target for the event and is executed
1187
+ * in the context of the event queue's dispatch loop once posted.
1188
+ *
1189
+ * @param f Function to execute when the event is dispatched
1190
+ * @return Event that will dispatch on the specific queue
1191
+ */
1192
+ template <typename F, typename ... ArgTs>
1193
+ UserAllocatedEvent<F, void (ArgTs...)> make_user_allocated_event (F f, ArgTs... args);
1194
+
1195
+ /* * Creates an user allocated event bound to the event queue
1196
+ * @see EventQueue::make_user_allocated_event
1197
+ */
1198
+ template <typename T, typename R, typename ... ArgTs>
1199
+ UserAllocatedEvent<mbed::Callback<void (ArgTs...)>, void (ArgTs...)> make_user_allocated_event (T *obj, R(T::*method)(ArgTs... args), ArgTs... args);
1200
+
1201
+ /* * Creates an user allocated event bound to the event queue
1202
+ * @see EventQueue::make_user_allocated_event
1203
+ */
1204
+ template <typename T, typename R, typename ... ArgTs>
1205
+ UserAllocatedEvent<mbed::Callback<void (ArgTs...)>, void (ArgTs...)> make_user_allocated_event (const T *obj, R(T::*method)(ArgTs... args) const , ArgTs... args);
1206
+
1207
+ /* * Creates an user allocated event bound to the event queue
1208
+ * @see EventQueue::make_user_allocated_event
1209
+ */
1210
+ template <typename T, typename R, typename ... ArgTs>
1211
+ UserAllocatedEvent<mbed::Callback<void (ArgTs...)>, void (ArgTs...)> make_user_allocated_event (volatile T *obj, R(T::*method)(ArgTs... args) volatile, ArgTs... args);
1212
+
1213
+ /* * Creates an user allocated event bound to the event queue
1214
+ * @see EventQueue::make_user_allocated_event
1215
+ */
1216
+ template <typename T, typename R, typename ... ArgTs>
1217
+ UserAllocatedEvent<mbed::Callback<void (ArgTs...)>, void (ArgTs...)> make_user_allocated_event (const volatile T *obj, R(T::*method)(ArgTs... args) const volatile, ArgTs... args);
1071
1218
#endif
1072
1219
1073
1220
protected:
1074
1221
#if !defined(DOXYGEN_ONLY)
1075
1222
template <typename F>
1076
1223
friend class Event ;
1224
+ template <typename F, typename A>
1225
+ friend class UserAllocatedEvent ;
1077
1226
struct equeue _equeue;
1078
1227
mbed::Callback<void (int )> _update;
1079
1228
@@ -1098,7 +1247,7 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
1098
1247
struct context <F> {
1099
1248
F f;
1100
1249
1101
- context (F f)
1250
+ constexpr context (F f)
1102
1251
: f(f) {}
1103
1252
1104
1253
template <typename ... ArgTs>
@@ -1113,7 +1262,7 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
1113
1262
F f;
1114
1263
C0 c0;
1115
1264
1116
- context (F f, C0 c0)
1265
+ constexpr context (F f, C0 c0)
1117
1266
: f(f), c0(c0) {}
1118
1267
1119
1268
template <typename ... ArgTs>
@@ -1129,7 +1278,7 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
1129
1278
C0 c0;
1130
1279
C1 c1;
1131
1280
1132
- context (F f, C0 c0, C1 c1)
1281
+ constexpr context (F f, C0 c0, C1 c1)
1133
1282
: f(f), c0(c0), c1(c1) {}
1134
1283
1135
1284
template <typename ... ArgTs>
@@ -1146,7 +1295,7 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
1146
1295
C1 c1;
1147
1296
C2 c2;
1148
1297
1149
- context (F f, C0 c0, C1 c1, C2 c2)
1298
+ constexpr context (F f, C0 c0, C1 c1, C2 c2)
1150
1299
: f(f), c0(c0), c1(c1), c2(c2) {}
1151
1300
1152
1301
template <typename ... ArgTs>
@@ -1164,7 +1313,7 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
1164
1313
C2 c2;
1165
1314
C3 c3;
1166
1315
1167
- context (F f, C0 c0, C1 c1, C2 c2, C3 c3)
1316
+ constexpr context (F f, C0 c0, C1 c1, C2 c2, C3 c3)
1168
1317
: f(f), c0(c0), c1(c1), c2(c2), c3(c3) {}
1169
1318
1170
1319
template <typename ... ArgTs>
@@ -1183,7 +1332,7 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
1183
1332
C3 c3;
1184
1333
C4 c4;
1185
1334
1186
- context (F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4)
1335
+ constexpr context (F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4)
1187
1336
: f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {}
1188
1337
1189
1338
template <typename ... ArgTs>
0 commit comments