mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #6901 from kivaisan/eventqueue_time_left
events: Introduce API to query how much time is left for delayed eventpull/6869/merge
commit
86d04d7b15
|
@ -250,6 +250,46 @@ void event_inference_test() {
|
|||
TEST_ASSERT_EQUAL(counter, 60);
|
||||
}
|
||||
|
||||
int timeleft_events[2];
|
||||
|
||||
void check_time_left(EventQueue* queue, int index, int expected) {
|
||||
const int event_id = timeleft_events[index];
|
||||
TEST_ASSERT_INT_WITHIN(2, expected, queue->time_left(event_id));
|
||||
touched = true;
|
||||
}
|
||||
|
||||
void time_left(EventQueue* queue, int index) {
|
||||
const int event_id = timeleft_events[index];
|
||||
TEST_ASSERT_EQUAL(0, queue->time_left(event_id));
|
||||
}
|
||||
|
||||
void time_left_test() {
|
||||
EventQueue queue(TEST_EQUEUE_SIZE);
|
||||
|
||||
// Enque check events
|
||||
TEST_ASSERT(queue.call_in(50, check_time_left, &queue, 0, 100-50));
|
||||
TEST_ASSERT(queue.call_in(200, check_time_left, &queue, 1, 200-200));
|
||||
|
||||
// Enque events to be checked
|
||||
timeleft_events[0] = queue.call_in(100, time_left, &queue, 0);
|
||||
timeleft_events[1] = queue.call_in(200, time_left, &queue, 1);
|
||||
TEST_ASSERT(timeleft_events[0]);
|
||||
TEST_ASSERT(timeleft_events[1]);
|
||||
|
||||
queue.dispatch(300);
|
||||
|
||||
// Ensure check was called
|
||||
TEST_ASSERT(touched);
|
||||
touched = false;
|
||||
|
||||
int id = queue.call(func0);
|
||||
TEST_ASSERT(id);
|
||||
TEST_ASSERT_EQUAL(0, queue.time_left(id));
|
||||
queue.dispatch(10);
|
||||
|
||||
// Test invalid event id
|
||||
TEST_ASSERT_EQUAL(-1, queue.time_left(0));
|
||||
}
|
||||
|
||||
// Test setup
|
||||
utest::v1::status_t test_setup(const size_t number_of_cases) {
|
||||
|
@ -274,6 +314,8 @@ const Case cases[] = {
|
|||
Case("Testing the event class", event_class_test),
|
||||
Case("Testing the event class helpers", event_class_helper_test),
|
||||
Case("Testing the event inference", event_inference_test),
|
||||
|
||||
Case("Testing time_left", time_left_test),
|
||||
};
|
||||
|
||||
Specification specification(test_setup, cases);
|
||||
|
|
|
@ -47,6 +47,10 @@ void EventQueue::cancel(int id) {
|
|||
return equeue_cancel(&_equeue, id);
|
||||
}
|
||||
|
||||
int EventQueue::time_left(int id) {
|
||||
return equeue_timeleft(&_equeue, id);
|
||||
}
|
||||
|
||||
void EventQueue::background(Callback<void(int)> update) {
|
||||
_update = update;
|
||||
|
||||
|
|
|
@ -114,6 +114,8 @@ public:
|
|||
* one of the call functions. It is safe to call cancel after an event
|
||||
* has already been dispatched.
|
||||
*
|
||||
* id must be valid i.e. event must have not finished executing.
|
||||
*
|
||||
* The cancel function is irq safe.
|
||||
*
|
||||
* If called while the event queue's dispatch loop is active, the cancel
|
||||
|
@ -124,6 +126,25 @@ public:
|
|||
*/
|
||||
void cancel(int id);
|
||||
|
||||
/** Query how much time is left for delayed event
|
||||
*
|
||||
* If the event is delayed, this function can be used to query how much time
|
||||
* is left until the event is due to be dispatched.
|
||||
*
|
||||
* id must be valid i.e. event must have not finished executing.
|
||||
*
|
||||
* This function is irq safe.
|
||||
*
|
||||
* @param id Unique id of the event
|
||||
*
|
||||
* @return Remaining time in milliseconds or
|
||||
* 0 if event is already due to be dispatched or
|
||||
* is currently executing.
|
||||
* Undefined if id is invalid.
|
||||
*
|
||||
*/
|
||||
int time_left(int id);
|
||||
|
||||
/** Background an event queue onto a single-shot timer-interrupt
|
||||
*
|
||||
* When updated, the event queue will call the provided update function
|
||||
|
@ -171,6 +192,8 @@ public:
|
|||
* @return A unique id that represents the posted event and can
|
||||
* be passed to cancel, or an id of 0 if there is not
|
||||
* enough memory to allocate the event.
|
||||
* Returned id will remain valid until event has finished
|
||||
* executing.
|
||||
*/
|
||||
template <typename F>
|
||||
int call(F f) {
|
||||
|
|
|
@ -364,6 +364,25 @@ void equeue_cancel(equeue_t *q, int id) {
|
|||
}
|
||||
}
|
||||
|
||||
int equeue_timeleft(equeue_t *q, int id) {
|
||||
int ret = -1;
|
||||
|
||||
if (!id) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// decode event from unique id and check that the local id matches
|
||||
struct equeue_event *e = (struct equeue_event *)
|
||||
&q->buffer[id & ((1 << q->npw2)-1)];
|
||||
|
||||
equeue_mutex_lock(&q->queuelock);
|
||||
if (e->id == id >> q->npw2) {
|
||||
ret = equeue_clampdiff(e->target, equeue_tick());
|
||||
}
|
||||
equeue_mutex_unlock(&q->queuelock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void equeue_break(equeue_t *q) {
|
||||
equeue_mutex_lock(&q->queuelock);
|
||||
q->break_requested = true;
|
||||
|
|
|
@ -187,6 +187,15 @@ int equeue_post(equeue_t *queue, void (*cb)(void *), void *event);
|
|||
// the event may have already begun executing.
|
||||
void equeue_cancel(equeue_t *queue, int id);
|
||||
|
||||
// Query how much time is left for delayed event
|
||||
//
|
||||
// If event is delayed, this function can be used to query how much time
|
||||
// is left until the event is due to be dispatched.
|
||||
//
|
||||
// This function is irq safe.
|
||||
//
|
||||
int equeue_timeleft(equeue_t *q, int id);
|
||||
|
||||
// Background an event queue onto a single-shot timer
|
||||
//
|
||||
// The provided update function will be called to indicate when the queue
|
||||
|
|
Loading…
Reference in New Issue