Mbed OS Reference
Loading...
Searching...
No Matches
Task.h
1/*
2 * Copyright (c) 2018-2019, Arm Limited and affiliates.
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#ifndef MBED_TASK_H
19#define MBED_TASK_H
20
21#include "events/EventQueue.h"
22#include "usb/internal/TaskBase.h"
23#include "platform/mbed_assert.h"
24#include "platform/Callback.h"
25
26namespace events {
27/** \addtogroup drivers-internal-api-usb
28 * @{
29 */
30
31
32template<typename F, typename A1 = void, typename A2 = void, typename A3 = void, typename A4 = void, typename A5 = void>
33struct AllArgs;
34
35template<typename B0>
36struct AllArgs<B0> {
37 typedef AllArgs<B0> Self;
38 B0 b0;
39
40 AllArgs(B0 b0 = B0()): b0(b0) {}
41
42 template <typename T, typename _>
43 struct Operations {
44 static void copy(void *_dest, void *_src)
45 {
46 new (_dest) Self(*(Self *)_src);
47 }
48
49 static void call(void *data)
50 {
51 Self *s = static_cast<Self *>(data);
52 s->b0();
53 s->~Self();
54 }
55 };
56
57 typedef Operations<B0, void> ops;
58};
59
60template<typename B0, typename B1>
61struct AllArgs<B0, B1> {
62 typedef AllArgs<B0, B1> Self;
63 B0 b0;
64 B1 b1;
65
66 AllArgs(B0 b0 = B0(), B1 b1 = B1()): b0(b0), b1(b1) {}
67
68 template <typename T, typename _>
69 struct Operations {
70 static void copy(void *_dest, void *_src)
71 {
72 new (_dest) Self(*(Self *)_src);
73 }
74
75 static void call(void *data)
76 {
77 Self *s = static_cast<Self *>(data);
78 s->b0(s->b1);
79 s->~Self();
80 }
81 };
82
83 template <typename T, typename R, typename U>
84 struct Operations<T *, R(U::*)()> {
85 static void copy(void *_dest, void *_src)
86 {
87 new (_dest) Self(*(Self *)_src);
88 }
89
90 static void call(void *data)
91 {
92 Self *s = static_cast<Self *>(data);
93 ((s->b0)->*(s->b1))();
94 s->~Self();
95 }
96 };
97
98 template <typename T, typename R, typename U>
99 struct Operations<T, R(U::*)() const> {
100 static void copy(void *_dest, void *_src)
101 {
102 new (_dest) Self(*(Self *)_src);
103 }
104
105 static void call(void *data)
106 {
107 Self *s = static_cast<Self *>(data);
108 ((s->b0)->*(s->b1))();
109 s->~Self();
110 }
111 };
112
113 template <typename T, typename R, typename U>
114 struct Operations<T, R(U::*)() volatile> {
115 static void copy(void *_dest, void *_src)
116 {
117 new (_dest) Self(*(Self *)_src);
118 }
119
120 static void call(void *data)
121 {
122 Self *s = static_cast<Self *>(data);
123 ((s->b0)->*(s->b1))();
124 s->~Self();
125 }
126 };
127
128 template <typename T, typename R, typename U>
129 struct Operations<T, R(U::*)() const volatile> {
130 static void copy(void *_dest, void *_src)
131 {
132 new (_dest) Self(*(Self *)_src);
133 }
134
135 static void call(void *data)
136 {
137 Self *s = static_cast<Self *>(data);
138 ((s->b0)->*(s->b1))();
139 s->~Self();
140 }
141 };
142
143 typedef Operations<B0, B1> ops;
144};
145
146template<typename B0, typename B1, typename B2>
147struct AllArgs<B0, B1, B2> {
149 B0 b0;
150 B1 b1;
151 B2 b2;
152
153
154 AllArgs(B0 b0 = B0(), B1 b1 = B1(), B2 b2 = B2()): b0(b0), b1(b1), b2(b2) {}
155
156 template <typename T, typename _>
157 struct Operations {
158 static void copy(void *_dest, void *_src)
159 {
160 new (_dest) Self(*(Self *)_src);
161 }
162
163 static void call(void *data)
164 {
165 Self *s = static_cast<Self *>(data);
166 s->b0(s->b1, s->b2);
167 s->~Self();
168 }
169 };
170
171 template <typename T, typename R, typename U>
172 struct Operations<T *, R(U::*)(B2)> {
173 static void copy(void *_dest, void *_src)
174 {
175 new (_dest) Self(*(Self *)_src);
176 }
177
178 static void call(void *data)
179 {
180 Self *s = static_cast<Self *>(data);
181 ((s->b0)->*(s->b1))(s->b2);
182 s->~Self();
183 }
184 };
185
186 template <typename T, typename R, typename U>
187 struct Operations<T, R(U::*)(B2) const> {
188 static void copy(void *_dest, void *_src)
189 {
190 new (_dest) Self(*(Self *)_src);
191 }
192
193 static void call(void *data)
194 {
195 Self *s = static_cast<Self *>(data);
196 ((s->b0)->*(s->b1))(s->b2);
197 s->~Self();
198 }
199 };
200
201 template <typename T, typename R, typename U>
202 struct Operations<T, R(U::*)(B2) volatile> {
203 static void copy(void *_dest, void *_src)
204 {
205 new (_dest) Self(*(Self *)_src);
206 }
207
208 static void call(void *data)
209 {
210 Self *s = static_cast<Self *>(data);
211 ((s->b0)->*(s->b1))(s->b2);
212 s->~Self();
213 }
214 };
215
216 template <typename T, typename R, typename U>
217 struct Operations<T, R(U::*)(B2) const volatile> {
218 static void copy(void *_dest, void *_src)
219 {
220 new (_dest) Self(*(Self *)_src);
221 }
222
223 static void call(void *data)
224 {
225 Self *s = static_cast<Self *>(data);
226 ((s->b0)->*(s->b1))(s->b2);
227 s->~Self();
228 }
229 };
230
231 typedef Operations<B0, B1> ops;
232};
233
234template<typename B0, typename B1, typename B2, typename B3>
235struct AllArgs<B0, B1, B2, B3> {
237 B0 b0;
238 B1 b1;
239 B2 b2;
240 B3 b3;
241
242
243 AllArgs(B0 b0 = B0(), B1 b1 = B1(), B2 b2 = B2(), B3 b3 = B3()): b0(b0), b1(b1), b2(b2), b3(b3) {}
244
245 template <typename T, typename _>
246 struct Operations {
247 static void copy(void *_dest, void *_src)
248 {
249 new (_dest) Self(*(Self *)_src);
250 }
251
252 static void call(void *data)
253 {
254 Self *s = static_cast<Self *>(data);
255 s->b0(s->b1, s->b2, s->b3);
256 s->~Self();
257 }
258 };
259
260 template <typename T, typename R, typename U>
261 struct Operations<T *, R(U::*)(B2, B3)> {
262 static void copy(void *_dest, void *_src)
263 {
264 new (_dest) Self(*(Self *)_src);
265 }
266
267 static void call(void *data)
268 {
269 Self *s = static_cast<Self *>(data);
270 ((s->b0)->*(s->b1))(s->b2, s->b3);
271 s->~Self();
272 }
273 };
274
275 template <typename T, typename R, typename U>
276 struct Operations<T, R(U::*)(B2, B3) const> {
277 static void copy(void *_dest, void *_src)
278 {
279 new (_dest) Self(*(Self *)_src);
280 }
281
282 static void call(void *data)
283 {
284 Self *s = static_cast<Self *>(data);
285 ((s->b0)->*(s->b1))(s->b2, s->b3);
286 s->~Self();
287 }
288 };
289
290 template <typename T, typename R, typename U>
291 struct Operations<T, R(U::*)(B2, B3) volatile> {
292 static void copy(void *_dest, void *_src)
293 {
294 new (_dest) Self(*(Self *)_src);
295 }
296
297 static void call(void *data)
298 {
299 Self *s = static_cast<Self *>(data);
300 ((s->b0)->*(s->b1))(s->b2, s->b3);
301 s->~Self();
302 }
303 };
304
305 template <typename T, typename R, typename U>
306 struct Operations<T, R(U::*)(B2, B3) const volatile> {
307 static void copy(void *_dest, void *_src)
308 {
309 new (_dest) Self(*(Self *)_src);
310 }
311
312 static void call(void *data)
313 {
314 Self *s = static_cast<Self *>(data);
315 ((s->b0)->*(s->b1))(s->b2, s->b3);
316 s->~Self();
317 }
318 };
319
320 typedef Operations<B0, B1> ops;
321};
322
323template<typename B0, typename B1, typename B2, typename B3, typename B4>
324struct AllArgs<B0, B1, B2, B3, B4> {
326 B0 b0;
327 B1 b1;
328 B2 b2;
329 B3 b3;
330 B4 b4;
331
332
333 AllArgs(B0 b0 = B0(), B1 b1 = B1(), B2 b2 = B2(), B3 b3 = B3(), B4 b4 = B4()): b0(b0), b1(b1), b2(b2), b3(b3), b4(b4) {}
334
335 template <typename T, typename _>
336 struct Operations {
337 static void copy(void *_dest, void *_src)
338 {
339 new (_dest) Self(*(Self *)_src);
340 }
341
342 static void call(void *data)
343 {
344 Self *s = static_cast<Self *>(data);
345 s->b0(s->b1, s->b2, s->b3, s->b4);
346 s->~Self();
347 }
348 };
349
350 template <typename T, typename R, typename U>
351 struct Operations<T *, R(U::*)(B2, B3, B4)> {
352 static void copy(void *_dest, void *_src)
353 {
354 new (_dest) Self(*(Self *)_src);
355 }
356
357 static void call(void *data)
358 {
359 Self *s = static_cast<Self *>(data);
360 ((s->b0)->*(s->b1))(s->b2, s->b3, s->b4);
361 s->~Self();
362 }
363 };
364
365 template <typename T, typename R, typename U>
366 struct Operations<T, R(U::*)(B2, B3, B4) const> {
367 static void copy(void *_dest, void *_src)
368 {
369 new (_dest) Self(*(Self *)_src);
370 }
371
372 static void call(void *data)
373 {
374 Self *s = static_cast<Self *>(data);
375 ((s->b0)->*(s->b1))(s->b2, s->b3, s->b4);
376 s->~Self();
377 }
378 };
379
380 template <typename T, typename R, typename U>
381 struct Operations<T, R(U::*)(B2, B3, B4) volatile> {
382 static void copy(void *_dest, void *_src)
383 {
384 new (_dest) Self(*(Self *)_src);
385 }
386
387 static void call(void *data)
388 {
389 Self *s = static_cast<Self *>(data);
390 ((s->b0)->*(s->b1))(s->b2, s->b3, s->b4);
391 s->~Self();
392 }
393 };
394
395 template <typename T, typename R, typename U>
396 struct Operations<T, R(U::*)(B2, B3, B4) const volatile> {
397 static void copy(void *_dest, void *_src)
398 {
399 new (_dest) Self(*(Self *)_src);
400 }
401
402 static void call(void *data)
403 {
404 Self *s = static_cast<Self *>(data);
405 ((s->b0)->*(s->b1))(s->b2, s->b3, s->b4);
406 s->~Self();
407 }
408 };
409
410 typedef Operations<B0, B1> ops;
411};
412
413template<typename B0, typename B1, typename B2, typename B3, typename B4, typename B5>
414struct AllArgs {
416 B0 b0;
417 B1 b1;
418 B2 b2;
419 B3 b3;
420 B4 b4;
421 B5 b5;
422
423
424 AllArgs(B0 b0 = B0(), B1 b1 = B1(), B2 b2 = B2(), B3 b3 = B3(), B4 b4 = B4(), B5 b5 = B5()): b0(b0), b1(b1), b2(b2), b3(b3), b4(b4), b5(b5) {}
425
426 template <typename T, typename _>
427 struct Operations {
428 static void copy(void *_dest, void *_src)
429 {
430 new (_dest) Self(*(Self *)_src);
431 }
432
433 static void call(void *data)
434 {
435 Self *s = static_cast<Self *>(data);
436 s->b0(s->b1, s->b2, s->b3, s->b4, s->b5);
437 s->~Self();
438 }
439 };
440
441 template <typename T, typename R, typename U>
442 struct Operations<T *, R(U::*)(B2, B3, B4, B5)> {
443 static void copy(void *_dest, void *_src)
444 {
445 new (_dest) Self(*(Self *)_src);
446 }
447
448 static void call(void *data)
449 {
450 Self *s = static_cast<Self *>(data);
451 ((s->b0)->*(s->b1))(s->b2, s->b3, s->b4, s->b5);
452 s->~Self();
453 }
454 };
455
456 template <typename T, typename R, typename U>
457 struct Operations<T, R(U::*)(B2, B3, B4, B5) const> {
458 static void copy(void *_dest, void *_src)
459 {
460 new (_dest) Self(*(Self *)_src);
461 }
462
463 static void call(void *data)
464 {
465 Self *s = static_cast<Self *>(data);
466 ((s->b0)->*(s->b1))(s->b2, s->b3, s->b4, s->b5);
467 s->~Self();
468 }
469 };
470
471 template <typename T, typename R, typename U>
472 struct Operations<T, R(U::*)(B2, B3, B4, B5) volatile> {
473 static void copy(void *_dest, void *_src)
474 {
475 new (_dest) Self(*(Self *)_src);
476 }
477
478 static void call(void *data)
479 {
480 Self *s = static_cast<Self *>(data);
481 ((s->b0)->*(s->b1))(s->b2, s->b3, s->b4, s->b5);
482 s->~Self();
483 }
484 };
485
486 template <typename T, typename R, typename U>
487 struct Operations<T, R(U::*)(B2, B3, B4, B5) const volatile> {
488 static void copy(void *_dest, void *_src)
489 {
490 new (_dest) Self(*(Self *)_src);
491 }
492
493 static void call(void *data)
494 {
495 Self *s = static_cast<Self *>(data);
496 ((s->b0)->*(s->b1))(s->b2, s->b3, s->b4, s->b5);
497 s->~Self();
498 }
499 };
500
501 typedef Operations<B0, B1> ops;
502};
503
504
505template <typename F>
506class Task;
507
508template <typename R>
509class Task<R()>: public TaskBase {
510public:
511
512 Task(TaskQueue *q = NULL, mbed::Callback<R()> cb = mbed::Callback<R()>())
513 : TaskBase(q), _args(cb)
514 {
515 }
516
517 Task &operator=(mbed::Callback<R()> cb)
518 {
519 _args.b0 = cb;
520 return *this;
521 }
522
523 void call()
524 {
525 post();
526 }
527
528protected:
529
530 virtual uint32_t size()
531 {
532 return sizeof(_args);
533 }
534
535 virtual run_callback_t start(void *data, uint32_t max_size)
536 {
537 All::ops::copy(data, (void *)&_args);
538 return &All::ops::call;
539 }
540
541private:
542 typedef AllArgs<mbed::Callback<R()> > All;
543 All _args;
544};
545
546template <typename R, typename A0>
547class Task<R(A0)>: public TaskBase {
548public:
549
550 Task(TaskQueue *q = NULL, mbed::Callback<R(A0)> cb = mbed::Callback<R(A0)>())
551 : TaskBase(q), _args(cb)
552 {
553 }
554
555 Task &operator=(mbed::Callback<R(A0)> cb)
556 {
557 _args.b0 = cb;
558 return *this;
559 }
560
561 void call(A0 a0)
562 {
563 _args.b1 = a0;
564 post();
565 }
566
567protected:
568
569 virtual uint32_t size()
570 {
571 return sizeof(_args);
572 }
573
574 virtual run_callback_t start(void *data, uint32_t max_size)
575 {
576 All::ops::copy(data, (void *)&_args);
577 return &All::ops::call;
578 }
579
580private:
581 typedef AllArgs<mbed::Callback<R(A0)>, A0> All;
582 All _args;
583};
584
585/** Task
586 *
587 * Representation of a postable task
588 */
589template <typename R, typename A0, typename A1>
590class Task<R(A0, A1)>: public TaskBase {
591public:
592
593 /**
594 * Construct a new task
595 *
596 * @param q TaskQueue to post to
597 * @param cb Callback to run
598 */
599 Task(TaskQueue *q = NULL, mbed::Callback<R(A0, A1)> cb = mbed::Callback<R(A0, A1)>())
600 : TaskBase(q), _args(cb)
601 {
602 }
603
604 /**
605 * Set the callback of this task
606 *
607 * @param cb Callback to run
608 */
610 {
611 _args.b0 = cb;
612 return *this;
613 }
614
615 /**
616 * Post this task for execution
617 *
618 * The number of arguments to call should match
619 * the type of the callback. For example Task<void(int, int)>
620 * expects two integers as arguments to call, while Task<void()>
621 * expects no arguments.
622 *
623 * @param a0 First callback parameter
624 * @param a1 Second callback parameter
625 */
626 void call(A0 a0, A1 a1)
627 {
628 _args.b1 = a0;
629 _args.b2 = a1;
630 post();
631 }
632
633protected:
634
635 virtual uint32_t size()
636 {
637 return sizeof(_args);
638 }
639
640 virtual run_callback_t start(void *data, uint32_t max_size)
641 {
642 All::ops::copy(data, (void *)&_args);
643 return &All::ops::call;
644 }
645
646private:
647 typedef AllArgs<mbed::Callback<R(A0, A1)>, A0, A1> All;
648 All _args;
649};
650
651/** @}*/
652
653}
654
655#endif
virtual uint32_t size()
Size of buffer required for TaskBase::start.
Definition: Task.h:530
virtual run_callback_t start(void *data, uint32_t max_size)
Copy any callback data and return a callback to run.
Definition: Task.h:535
virtual uint32_t size()
Size of buffer required for TaskBase::start.
Definition: Task.h:635
Task(TaskQueue *q=NULL, mbed::Callback< R(A0, A1)> cb=mbed::Callback< R(A0, A1)>())
Construct a new task.
Definition: Task.h:599
virtual run_callback_t start(void *data, uint32_t max_size)
Copy any callback data and return a callback to run.
Definition: Task.h:640
Task & operator=(mbed::Callback< R(A0, A1)> cb)
Set the callback of this task.
Definition: Task.h:609
void call(A0 a0, A1 a1)
Post this task for execution.
Definition: Task.h:626
virtual uint32_t size()
Size of buffer required for TaskBase::start.
Definition: Task.h:569
virtual run_callback_t start(void *data, uint32_t max_size)
Copy any callback data and return a callback to run.
Definition: Task.h:574
TaskBase.
Definition: TaskBase.h:43
TaskQueue.
Definition: TaskQueue.h:39
Callback class based on template specialization.
Definition: Callback.h:53