Skip to content

Commit d5f034b

Browse files
authored
Merge pull request #12319 from maciejbocianski/fix_userallocatedevent_imp
Fix userallocatedevent imp
2 parents f6c6a9c + 83a0783 commit d5f034b

File tree

5 files changed

+116
-53
lines changed

5 files changed

+116
-53
lines changed

TESTS/events/equeue/main.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,23 +1003,24 @@ static void test_equeue_user_allocated_event_post()
10031003

10041004
uint8_t touched = 0;
10051005
user_allocated_event e1 = { { 0, 0, 0, NULL, NULL, NULL, 0, -1, NULL, NULL }, 0 };
1006-
user_allocated_event e2 = { { 0, 0, 0, NULL, NULL, NULL, 1, -1, NULL, NULL }, 0 };
1007-
user_allocated_event e3 = { { 0, 0, 0, NULL, NULL, NULL, 1, -1, NULL, NULL }, 0 };
1008-
user_allocated_event e4 = { { 0, 0, 0, NULL, NULL, NULL, 1, -1, NULL, NULL }, 0 };
1006+
user_allocated_event e2 = { { 0, 0, 0, NULL, NULL, NULL, 10, 10, NULL, NULL }, 0 };
1007+
user_allocated_event e3 = { { 0, 0, 0, NULL, NULL, NULL, 10, 10, NULL, NULL }, 0 };
1008+
user_allocated_event e4 = { { 0, 0, 0, NULL, NULL, NULL, 10, 10, NULL, NULL }, 0 };
10091009
user_allocated_event e5 = { { 0, 0, 0, NULL, NULL, NULL, 0, -1, NULL, NULL }, 0 };
10101010

1011-
TEST_ASSERT_NOT_EQUAL(0, equeue_call(&q, simple_func, &touched));
1012-
TEST_ASSERT_EQUAL_INT(0, equeue_call(&q, simple_func, &touched));
1013-
TEST_ASSERT_EQUAL_INT(0, equeue_call(&q, simple_func, &touched));
1011+
TEST_ASSERT_NOT_EQUAL(0, equeue_call_every(&q, 10, simple_func, &touched));
1012+
TEST_ASSERT_EQUAL_INT(0, equeue_call_every(&q, 10, simple_func, &touched));
1013+
TEST_ASSERT_EQUAL_INT(0, equeue_call_every(&q, 10, simple_func, &touched));
10141014

10151015
equeue_post_user_allocated(&q, simple_func, &e1.e);
10161016
equeue_post_user_allocated(&q, simple_func, &e2.e);
10171017
equeue_post_user_allocated(&q, simple_func, &e3.e);
10181018
equeue_post_user_allocated(&q, simple_func, &e4.e);
10191019
equeue_post_user_allocated(&q, simple_func, &e5.e);
10201020
equeue_cancel_user_allocated(&q, &e3.e);
1021+
equeue_cancel_user_allocated(&q, &e3.e);
10211022

1022-
equeue_dispatch(&q, 1);
1023+
equeue_dispatch(&q, 11);
10231024

10241025
TEST_ASSERT_EQUAL_UINT8(1, touched);
10251026
TEST_ASSERT_EQUAL_UINT8(1, e1.touched);
@@ -1028,13 +1029,16 @@ static void test_equeue_user_allocated_event_post()
10281029
TEST_ASSERT_EQUAL_UINT8(1, e4.touched);
10291030
TEST_ASSERT_EQUAL_UINT8(1, e5.touched);
10301031

1031-
equeue_dispatch(&q, 10);
1032+
e3.e.target = 10; // set target as it's modified by equeue_call
1033+
e3.e.period = 10; // set period as it's reset by equeue_cancel
1034+
equeue_post_user_allocated(&q, simple_func, &e3.e);
1035+
equeue_dispatch(&q, 101);
10321036

1033-
TEST_ASSERT_EQUAL_UINT8(1, touched);
1037+
TEST_ASSERT_EQUAL_UINT8(11, touched);
10341038
TEST_ASSERT_EQUAL_UINT8(1, e1.touched);
1035-
TEST_ASSERT_EQUAL_UINT8(1, e2.touched);
1036-
TEST_ASSERT_EQUAL_UINT8(0, e3.touched);
1037-
TEST_ASSERT_EQUAL_UINT8(1, e4.touched);
1039+
TEST_ASSERT_EQUAL_UINT8(11, e2.touched);
1040+
TEST_ASSERT_EQUAL_UINT8(10, e3.touched);
1041+
TEST_ASSERT_EQUAL_UINT8(11, e4.touched);
10381042
TEST_ASSERT_EQUAL_UINT8(1, e5.touched);
10391043

10401044
equeue_destroy(&q);

TESTS/events/queue/main.cpp

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -363,14 +363,18 @@ void mixed_dynamic_static_events_queue_test()
363363

364364
EventTest e1_test;
365365
Event<void()> e1 = queue.event(&e1_test, &EventTest::f0);
366+
e1.delay(10);
367+
e1.period(10);
366368
int id1 = e1.post();
367369
TEST_ASSERT_NOT_EQUAL(0, id1);
368370
EventTest e2_test;
369371
Event<void()> e2 = queue.event(&e2_test, &EventTest::f1, 3);
372+
e2.period(10);
370373
int id2 = e2.post();
371374
TEST_ASSERT_NOT_EQUAL(0, id2);
372375
EventTest e3_test;
373376
Event<void()> e3 = queue.event(&e3_test, &EventTest::f5, 1, 2, 3, 4, 5);
377+
e3.period(10);
374378
int id3 = e3.post();
375379
TEST_ASSERT_NOT_EQUAL(0, id3);
376380

@@ -391,8 +395,11 @@ void mixed_dynamic_static_events_queue_test()
391395
TEST_ASSERT_EQUAL(false, ue0.try_call());
392396
ue1.call_on(&queue);
393397
TEST_ASSERT_EQUAL(false, ue1.try_call());
398+
ue2.period(10);
394399
ue2.call_on(&queue);
395400
TEST_ASSERT_EQUAL(false, ue2.try_call());
401+
ue3.period(10);
402+
ue3.delay(50);
396403
ue3.call_on(&queue);
397404
TEST_ASSERT_EQUAL(false, ue3.try_call());
398405
ue4.call_on(&queue);
@@ -401,21 +408,36 @@ void mixed_dynamic_static_events_queue_test()
401408
ue4.cancel();
402409
e2.cancel();
403410

404-
queue.dispatch(1);
411+
queue.dispatch(101);
405412

406413
TEST_ASSERT_EQUAL(true, touched);
407414
TEST_ASSERT_EQUAL(1, ue1_test.counter);
408-
TEST_ASSERT_EQUAL(3, ue2_test.counter);
409-
TEST_ASSERT_EQUAL(15, ue3_test.counter);
415+
TEST_ASSERT_EQUAL(33, ue2_test.counter);
416+
TEST_ASSERT_EQUAL(90, ue3_test.counter);
410417
TEST_ASSERT_EQUAL(0, ue4_test.counter);
411-
TEST_ASSERT_EQUAL(1, e1_test.counter);
418+
TEST_ASSERT_EQUAL(10, e1_test.counter);
412419
TEST_ASSERT_EQUAL(0, e2_test.counter);
413-
TEST_ASSERT_EQUAL(15, e3_test.counter);
420+
TEST_ASSERT_EQUAL(165, e3_test.counter);
421+
422+
// user allocated event have to be canceled(removed from the queue) before destruction
423+
// cancel all periodic user events
424+
ue2.cancel();
425+
ue3.cancel();
414426
}
415427
}
416428

417429

418430
static EventQueue g_queue(0);
431+
static auto ue0 = g_queue.make_user_allocated_event(func0);
432+
static EventTest test1;
433+
static auto ue1 = make_user_allocated_event(&test1, &EventTest::f0);
434+
static EventTest test2;
435+
static auto ue2 = g_queue.make_user_allocated_event(&test2, &EventTest::f1, 3);
436+
static EventTest test3;
437+
static auto ue3 = make_user_allocated_event(&test3, &EventTest::f5, 1, 2, 3, 4, 5);
438+
static EventTest test4;
439+
static auto ue4 = g_queue.make_user_allocated_event(&test4, &EventTest::f5, 1, 2, 3, 4, 5);
440+
419441

420442
/** Test that static queue executes user allocated events.
421443
*
@@ -429,15 +451,20 @@ void static_events_queue_test()
429451
Event<void()> e0 = g_queue.event(func0);
430452
TEST_ASSERT_EQUAL(0, e0.post());
431453

432-
auto ue0 = g_queue.make_user_allocated_event(func0);
433-
EventTest test1;
434-
auto ue1 = make_user_allocated_event(&test1, &EventTest::f0);
435-
EventTest test2;
436-
auto ue2 = g_queue.make_user_allocated_event(&test2, &EventTest::f1, 3);
437-
EventTest test3;
438-
auto ue3 = make_user_allocated_event(&test3, &EventTest::f5, 1, 2, 3, 4, 5);
439-
EventTest test4;
440-
auto ue4 = g_queue.make_user_allocated_event(&test4, &EventTest::f5, 1, 2, 3, 4, 5);
454+
ue0.delay(100);
455+
ue0.period(200);
456+
457+
ue1.delay(100);
458+
ue1.period(200);
459+
460+
ue2.delay(100);
461+
ue2.period(200);
462+
463+
ue3.delay(100);
464+
ue3.period(200);
465+
466+
ue4.delay(100);
467+
ue4.period(200);
441468

442469
ue0.call();
443470
TEST_ASSERT_EQUAL(false, ue0.try_call());
@@ -449,16 +476,26 @@ void static_events_queue_test()
449476
TEST_ASSERT_EQUAL(false, ue3.try_call());
450477
ue4.call();
451478
ue4.cancel();
479+
ue4.cancel();
452480
TEST_ASSERT_EQUAL(true, ue4.try_call());
453481
g_queue.cancel(&ue4);
482+
g_queue.cancel(&ue4);
454483

455-
g_queue.dispatch(1);
484+
g_queue.dispatch(400);
456485

457-
TEST_ASSERT_EQUAL(1, test1.counter);
458-
TEST_ASSERT_EQUAL(3, test2.counter);
459-
TEST_ASSERT_EQUAL(15, test3.counter);
486+
TEST_ASSERT_EQUAL(2, test1.counter);
487+
TEST_ASSERT_EQUAL(6, test2.counter);
488+
TEST_ASSERT_EQUAL(30, test3.counter);
460489
TEST_ASSERT_EQUAL(0, test4.counter);
461490

491+
ue4.delay(1);
492+
TEST_ASSERT_EQUAL(true, ue4.try_call());
493+
g_queue.dispatch(1);
494+
495+
TEST_ASSERT_EQUAL(2, test1.counter);
496+
TEST_ASSERT_EQUAL(6, test2.counter);
497+
TEST_ASSERT_EQUAL(30, test3.counter);
498+
TEST_ASSERT_EQUAL(15, test4.counter);
462499
}
463500

464501
// Test setup

UNITTESTS/events/equeue/test_equeue.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,23 +1072,24 @@ TEST_F(TestEqueue, test_equeue_user_allocated_event_post)
10721072

10731073
uint8_t touched = 0;
10741074
user_allocated_event e1 = { { 0, 0, 0, NULL, NULL, NULL, 0, -1, NULL, NULL }, 0 };
1075-
user_allocated_event e2 = { { 0, 0, 0, NULL, NULL, NULL, 1, -1, NULL, NULL }, 0 };
1076-
user_allocated_event e3 = { { 0, 0, 0, NULL, NULL, NULL, 1, -1, NULL, NULL }, 0 };
1077-
user_allocated_event e4 = { { 0, 0, 0, NULL, NULL, NULL, 1, -1, NULL, NULL }, 0 };
1075+
user_allocated_event e2 = { { 0, 0, 0, NULL, NULL, NULL, 10, 10, NULL, NULL }, 0 };
1076+
user_allocated_event e3 = { { 0, 0, 0, NULL, NULL, NULL, 10, 10, NULL, NULL }, 0 };
1077+
user_allocated_event e4 = { { 0, 0, 0, NULL, NULL, NULL, 10, 10, NULL, NULL }, 0 };
10781078
user_allocated_event e5 = { { 0, 0, 0, NULL, NULL, NULL, 0, -1, NULL, NULL }, 0 };
10791079

1080-
EXPECT_NE(0, equeue_call(&q, simple_func, &touched));
1081-
EXPECT_EQ(0, equeue_call(&q, simple_func, &touched));
1082-
EXPECT_EQ(0, equeue_call(&q, simple_func, &touched));
1080+
EXPECT_NE(0, equeue_call_every(&q, 10, simple_func, &touched));
1081+
EXPECT_EQ(0, equeue_call_every(&q, 10, simple_func, &touched));
1082+
EXPECT_EQ(0, equeue_call_every(&q, 10, simple_func, &touched));
10831083

10841084
equeue_post_user_allocated(&q, simple_func, &e1.e);
10851085
equeue_post_user_allocated(&q, simple_func, &e2.e);
10861086
equeue_post_user_allocated(&q, simple_func, &e3.e);
10871087
equeue_post_user_allocated(&q, simple_func, &e4.e);
10881088
equeue_post_user_allocated(&q, simple_func, &e5.e);
10891089
equeue_cancel_user_allocated(&q, &e3.e);
1090+
equeue_cancel_user_allocated(&q, &e3.e);
10901091

1091-
equeue_dispatch(&q, 1);
1092+
equeue_dispatch(&q, 11);
10921093

10931094
EXPECT_EQ(1, touched);
10941095
EXPECT_EQ(1, e1.touched);
@@ -1097,14 +1098,17 @@ TEST_F(TestEqueue, test_equeue_user_allocated_event_post)
10971098
EXPECT_EQ(1, e4.touched);
10981099
EXPECT_EQ(1, e5.touched);
10991100

1100-
equeue_dispatch(&q, 10);
1101-
1102-
EXPECT_EQ(1, touched);
1103-
EXPECT_EQ(1, e1.touched);
1104-
EXPECT_EQ(1, e2.touched);
1105-
EXPECT_EQ(0, e3.touched);
1106-
EXPECT_EQ(1, e4.touched);
1107-
EXPECT_EQ(1, e5.touched);
1101+
e3.e.target = 10; // set target as it's modified by equeue_call
1102+
e3.e.period = 10; // set period as it's reset by equeue_cancel
1103+
equeue_post_user_allocated(&q, simple_func, &e3.e);
1104+
equeue_dispatch(&q, 101);
1105+
1106+
EXPECT_EQ(11, touched);
1107+
EXPECT_EQ(1 , e1.touched);
1108+
EXPECT_EQ(11, e2.touched);
1109+
EXPECT_EQ(10 , e3.touched);
1110+
EXPECT_EQ(11, e4.touched);
1111+
EXPECT_EQ(1 , e5.touched);
11081112

11091113
equeue_destroy(&q);
11101114
}

events/UserAllocatedEvent.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class UserAllocatedEvent<F, void(ArgTs...)> {
8686
* @param f Function to execute when the event is dispatched
8787
* @param args Arguments to bind to the callback
8888
*/
89-
constexpr UserAllocatedEvent(F f, ArgTs... args) : _e(get_default_equeue_event()), _c(f, args...), _equeue(), _post_ref()
89+
constexpr UserAllocatedEvent(F f, ArgTs... args) : _e(get_default_equeue_event()), _c(f, args...), _delay(), _period(-1), _equeue(), _post_ref()
9090
{
9191
}
9292

@@ -100,7 +100,7 @@ class UserAllocatedEvent<F, void(ArgTs...)> {
100100
* @param f Function to execute when the event is dispatched
101101
* @param args Arguments to bind to the callback
102102
*/
103-
constexpr UserAllocatedEvent(EventQueue *queue, F f, ArgTs... args) : _e(get_default_equeue_event()), _c(f, args...), _equeue(&queue->_equeue), _post_ref()
103+
constexpr UserAllocatedEvent(EventQueue *queue, F f, ArgTs... args) : _e(get_default_equeue_event()), _c(f, args...), _delay(), _period(-1), _equeue(&queue->_equeue), _post_ref()
104104
{
105105
}
106106

@@ -215,7 +215,7 @@ class UserAllocatedEvent<F, void(ArgTs...)> {
215215
void delay(int delay)
216216
{
217217
MBED_ASSERT(!_post_ref);
218-
equeue_event_delay(&_e + 1, delay);
218+
_delay = delay;
219219
}
220220

221221
/** Configure the period of an event
@@ -225,7 +225,7 @@ class UserAllocatedEvent<F, void(ArgTs...)> {
225225
void period(int period)
226226
{
227227
MBED_ASSERT(!_post_ref);
228-
equeue_event_period(&_e + 1, period);
228+
_period = period;
229229
}
230230

231231
/** Cancels posted event
@@ -243,14 +243,16 @@ class UserAllocatedEvent<F, void(ArgTs...)> {
243243
*/
244244
bool cancel()
245245
{
246-
return equeue_cancel_user_allocated(_equeue, &_e);
246+
return _post_ref > 0 ? equeue_cancel_user_allocated(_equeue, &_e) : false;
247247
}
248248

249249

250250
private:
251251
friend class EventQueue;
252252
struct equeue_event _e;
253253
C _c;
254+
int _delay;
255+
int _period;
254256
struct equeue *_equeue;
255257
uint8_t _post_ref;
256258

@@ -260,17 +262,22 @@ class UserAllocatedEvent<F, void(ArgTs...)> {
260262
return false;
261263
}
262264
core_util_atomic_incr_u8(&_post_ref, 1);
265+
equeue_event_delay(&_e + 1, _delay);
266+
equeue_event_period(&_e + 1, _period);
263267
equeue_post_user_allocated(_equeue, &EventQueue::function_call<C>, &_e);
264268
return true;
265269
}
266270

267271
bool post_on(EventQueue *queue)
268272
{
273+
MBED_ASSERT(queue);
269274
if (_post_ref) {
270275
return false;
271276
}
272277
_equeue = &(queue->_equeue);
273278
core_util_atomic_incr_u8(&_post_ref, 1);
279+
equeue_event_delay(&_e + 1, _delay);
280+
equeue_event_period(&_e + 1, _period);
274281
equeue_post_user_allocated(_equeue, &EventQueue::function_call<C>, &_e);
275282
return true;
276283
}

events/source/equeue.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
// check if the event is allocaded by user - event address is outside queues internal buffer address range
2525
#define EQUEUE_IS_USER_ALLOCATED_EVENT(e) ((q->buffer == NULL) || ((uintptr_t)(e) < (uintptr_t)q->buffer) || ((uintptr_t)(e) > ((uintptr_t)q->slab.data)))
2626

27+
// for user allocated events use event id to track event state
28+
enum {
29+
EQUEUE_USER_ALLOCATED_EVENT_STATE_INPROGRESS = 1,
30+
EQUEUE_USER_ALLOCATED_EVENT_STATE_DONE = 0 // event canceled or dispatching done
31+
};
32+
2733
// calculate the relative-difference between absolute times while
2834
// correctly handling overflow conditions
2935
static inline int equeue_tickdiff(unsigned a, unsigned b)
@@ -229,7 +235,9 @@ void equeue_dealloc(equeue_t *q, void *p)
229235
e->dtor(e + 1);
230236
}
231237

232-
if (!EQUEUE_IS_USER_ALLOCATED_EVENT(e)) {
238+
if (EQUEUE_IS_USER_ALLOCATED_EVENT(e)) {
239+
e->id = EQUEUE_USER_ALLOCATED_EVENT_STATE_DONE;
240+
} else {
233241
equeue_mem_dealloc(q, e);
234242
}
235243
}
@@ -402,6 +410,7 @@ void equeue_post_user_allocated(equeue_t *q, void (*cb)(void *), void *p)
402410
unsigned tick = equeue_tick();
403411
e->cb = cb;
404412
e->target = tick + e->target;
413+
e->id = EQUEUE_USER_ALLOCATED_EVENT_STATE_INPROGRESS;
405414

406415
equeue_enqueue(q, e, tick);
407416
equeue_sema_signal(&q->eventsema);
@@ -424,7 +433,7 @@ bool equeue_cancel(equeue_t *q, int id)
424433

425434
bool equeue_cancel_user_allocated(equeue_t *q, void *e)
426435
{
427-
if (!e) {
436+
if (!e || ((struct equeue_event *)e)->id == EQUEUE_USER_ALLOCATED_EVENT_STATE_DONE) {
428437
return false;
429438
}
430439

@@ -506,7 +515,9 @@ void equeue_dispatch(equeue_t *q, int ms)
506515
e->target += e->period;
507516
equeue_enqueue(q, e, equeue_tick());
508517
} else {
509-
equeue_incid(q, e);
518+
if (!EQUEUE_IS_USER_ALLOCATED_EVENT(e)) {
519+
equeue_incid(q, e);
520+
}
510521
equeue_dealloc(q, e + 1);
511522
}
512523
}

0 commit comments

Comments
 (0)