Skip to content

Commit 990da08

Browse files
author
Kimmo Vaisanen
committed
Introduce API to query how much time is left for delayed event
If user has initiated a delayed event (either with call_in or call_every), user might need to know how much time is left until the event is due to be dispatched. Added time_left() function can be used to get the remaining time.
1 parent 80e1093 commit 990da08

File tree

5 files changed

+97
-0
lines changed

5 files changed

+97
-0
lines changed

TESTS/events/queue/main.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,46 @@ void event_inference_test() {
250250
TEST_ASSERT_EQUAL(counter, 60);
251251
}
252252

253+
int timeleft_events[2];
254+
255+
void check_time_left(EventQueue* queue, int index, int expected) {
256+
const int event_id = timeleft_events[index];
257+
TEST_ASSERT_INT_WITHIN(2, expected, queue->time_left(event_id));
258+
touched = true;
259+
}
260+
261+
void time_left(EventQueue* queue, int index) {
262+
const int event_id = timeleft_events[index];
263+
TEST_ASSERT_EQUAL(0, queue->time_left(event_id));
264+
}
265+
266+
void time_left_test() {
267+
EventQueue queue(TEST_EQUEUE_SIZE);
268+
269+
// Enque check events
270+
TEST_ASSERT(queue.call_in(50, check_time_left, &queue, 0, 100-50));
271+
TEST_ASSERT(queue.call_in(200, check_time_left, &queue, 1, 200-200));
272+
273+
// Enque events to be checked
274+
timeleft_events[0] = queue.call_in(100, time_left, &queue, 0);
275+
timeleft_events[1] = queue.call_in(200, time_left, &queue, 1);
276+
TEST_ASSERT(timeleft_events[0]);
277+
TEST_ASSERT(timeleft_events[1]);
278+
279+
queue.dispatch(300);
280+
281+
// Ensure check was called
282+
TEST_ASSERT(touched);
283+
touched = false;
284+
285+
int id = queue.call(func0);
286+
TEST_ASSERT(id);
287+
TEST_ASSERT_EQUAL(0, queue.time_left(id));
288+
queue.dispatch(10);
289+
290+
// Test invalid event id
291+
TEST_ASSERT_EQUAL(-1, queue.time_left(0));
292+
}
253293

254294
// Test setup
255295
utest::v1::status_t test_setup(const size_t number_of_cases) {
@@ -274,6 +314,8 @@ const Case cases[] = {
274314
Case("Testing the event class", event_class_test),
275315
Case("Testing the event class helpers", event_class_helper_test),
276316
Case("Testing the event inference", event_inference_test),
317+
318+
Case("Testing time_left", time_left_test),
277319
};
278320

279321
Specification specification(test_setup, cases);

events/EventQueue.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ void EventQueue::cancel(int id) {
4747
return equeue_cancel(&_equeue, id);
4848
}
4949

50+
int EventQueue::time_left(int id) {
51+
return equeue_timeleft(&_equeue, id);
52+
}
53+
5054
void EventQueue::background(Callback<void(int)> update) {
5155
_update = update;
5256

events/EventQueue.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
114114
* one of the call functions. It is safe to call cancel after an event
115115
* has already been dispatched.
116116
*
117+
* id must be valid i.e. event must have not finished executing.
118+
*
117119
* The cancel function is irq safe.
118120
*
119121
* If called while the event queue's dispatch loop is active, the cancel
@@ -124,6 +126,25 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
124126
*/
125127
void cancel(int id);
126128

129+
/** Query how much time is left for delayed event
130+
*
131+
* If the event is delayed, this function can be used to query how much time
132+
* is left until the event is due to be dispatched.
133+
*
134+
* id must be valid i.e. event must have not finished executing.
135+
*
136+
* This function is irq safe.
137+
*
138+
* @param id Unique id of the event
139+
*
140+
* @return Remaining time in milliseconds or
141+
* 0 if event is already due to be dispatched or
142+
* is currently executing.
143+
* Undefined if id is invalid.
144+
*
145+
*/
146+
int time_left(int id);
147+
127148
/** Background an event queue onto a single-shot timer-interrupt
128149
*
129150
* When updated, the event queue will call the provided update function
@@ -171,6 +192,8 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
171192
* @return A unique id that represents the posted event and can
172193
* be passed to cancel, or an id of 0 if there is not
173194
* enough memory to allocate the event.
195+
* Returned id will remain valid until event has finished
196+
* executing.
174197
*/
175198
template <typename F>
176199
int call(F f) {

events/equeue/equeue.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,25 @@ void equeue_cancel(equeue_t *q, int id) {
364364
}
365365
}
366366

367+
int equeue_timeleft(equeue_t *q, int id) {
368+
int ret = -1;
369+
370+
if (!id) {
371+
return -1;
372+
}
373+
374+
// decode event from unique id and check that the local id matches
375+
struct equeue_event *e = (struct equeue_event *)
376+
&q->buffer[id & ((1 << q->npw2)-1)];
377+
378+
equeue_mutex_lock(&q->queuelock);
379+
if (e->id == id >> q->npw2) {
380+
ret = equeue_clampdiff(e->target, equeue_tick());
381+
}
382+
equeue_mutex_unlock(&q->queuelock);
383+
return ret;
384+
}
385+
367386
void equeue_break(equeue_t *q) {
368387
equeue_mutex_lock(&q->queuelock);
369388
q->break_requested = true;

events/equeue/equeue.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,15 @@ int equeue_post(equeue_t *queue, void (*cb)(void *), void *event);
187187
// the event may have already begun executing.
188188
void equeue_cancel(equeue_t *queue, int id);
189189

190+
// Query how much time is left for delayed event
191+
//
192+
// If event is delayed, this function can be used to query how much time
193+
// is left until the event is due to be dispatched.
194+
//
195+
// This function is irq safe.
196+
//
197+
int equeue_timeleft(equeue_t *q, int id);
198+
190199
// Background an event queue onto a single-shot timer
191200
//
192201
// The provided update function will be called to indicate when the queue

0 commit comments

Comments
 (0)