Skip to content

Update EventQueue API to use chrono times #13975

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions events/include/events/EventQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
*/
~EventQueue();

/** Dispatch events
*
* Executes events for the specified number of milliseconds.
*
* The dispatch_for() function is guaranteed to terminate after the elapsed wait.
*
* @param ms Time to wait for events in milliseconds, expressed as a
* Chrono duration.
*/
void dispatch_for(duration ms);

/** Dispatch events
*
* Executes events until the specified milliseconds have passed.
Expand All @@ -96,23 +107,32 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
* to terminate. When called with a timeout of 0, the dispatch function
* does not wait and is IRQ safe.
*
* NOTE: Since the majority of the event library was updated to use
* Chrono types (as part of the Mbed 6 release), this function will not
* function as expected. Please update to use the new dispatch functions
* to ensure correct functionality.
*
* @param ms Time to wait for events in milliseconds, a negative
* value will dispatch events indefinitely
* (default to -1)
*/
MBED_DEPRECATED_SINCE("mbed-os-6.7.0", "Use dispatch_for() to pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
void dispatch(int ms = -1);

/** Dispatch events without a timeout
*
* This is equivalent to EventQueue::dispatch with no arguments, but
* avoids overload ambiguities when passed as a callback.
* Executes events indefinitely unless the dispatch loop is forcibly broken.
* @See break_dispatch()
*
* @see EventQueue::dispatch
*/
void dispatch_forever()
{
dispatch();
}
void dispatch_forever();

/** Dispatch currently queued events only and then terminate
*
* In this case the dispatch function does not wait.
*
*/
void dispatch_once();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I lost my comment for that item.

@kjbracey-arm The implementation doesn't do exactly this. It may not break immediately out of the loop if the next tick hasn't been reached. Do you think we should patch the implementation ?
The change is trivial, we just have to return if ms is equal to 0.

int deadline = -1;
tick = equeue_tick();
// check if we should stop dispatching soon
if (ms >= 0) {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not seeing what you're seeing here. If ms == 0, then it computes tickdiff(timeout, tick), ie entry_tick + 0 - tick, and that's got to be <= 0, so it exits immediately. Right?

BTW the name here feels perilously close to dispatch_one(), but I guess it's okay...


/** Break out of a running event loop
*
Expand Down
15 changes: 15 additions & 0 deletions events/source/EventQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,26 @@ EventQueue::~EventQueue()
equeue_destroy(&_equeue);
}

void EventQueue::dispatch_for(duration ms)
{
return equeue_dispatch(&_equeue, ms.count());
}

void EventQueue::dispatch(int ms)
{
return equeue_dispatch(&_equeue, ms);
}

void EventQueue::dispatch_forever()
{
return equeue_dispatch(&_equeue, -1);
}

void EventQueue::dispatch_once()
{
return equeue_dispatch(&_equeue, 0);
}

void EventQueue::break_dispatch()
{
return equeue_break(&_equeue);
Expand Down
40 changes: 20 additions & 20 deletions events/tests/TESTS/events/queue/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,17 @@ void simple_posts_test##i() { \
\
touched = false; \
queue.call(func##i,##__VA_ARGS__); \
queue.dispatch(0); \
queue.dispatch_once(); \
TEST_ASSERT(touched); \
\
touched = false; \
queue.call_in(1ms, func##i,##__VA_ARGS__); \
queue.dispatch(2); \
queue.call_in(1ms, func##i,##__VA_ARGS__); \
queue.dispatch_for(2ms); \
TEST_ASSERT(touched); \
\
touched = false; \
queue.call_every(1ms, func##i,##__VA_ARGS__); \
queue.dispatch(2); \
queue.call_every(1ms, func##i,##__VA_ARGS__); \
queue.dispatch_for(2ms); \
TEST_ASSERT(touched); \
}

Expand Down Expand Up @@ -129,7 +129,7 @@ void call_in_test()
queue.call_in((i + 1) * 100ms, time_func, &tickers[i], (i + 1) * 100);
}

queue.dispatch(N * 100);
queue.dispatch_for(N * 100ms);
}

template <int N>
Expand All @@ -144,7 +144,7 @@ void call_every_test()
queue.call_every((i + 1) * 100ms, time_func, &tickers[i], (i + 1) * 100);
}

queue.dispatch(N * 100);
queue.dispatch_for(N * 100ms);
}

void allocate_failure_test()
Expand Down Expand Up @@ -179,7 +179,7 @@ void cancel_test1()
queue.cancel(ids[i]);
}

queue.dispatch(0);
queue.dispatch_once();
}


Expand Down Expand Up @@ -235,7 +235,7 @@ void event_class_test()
e1.post(1);
e0.post();

queue.dispatch(0);
queue.dispatch_once();

TEST_ASSERT_EQUAL(counter, 30);
}
Expand All @@ -259,7 +259,7 @@ void event_class_helper_test()
e1.post();
e0.post();

queue.dispatch(0);
queue.dispatch_once();

TEST_ASSERT_EQUAL(counter, 15);
}
Expand All @@ -283,7 +283,7 @@ void event_inference_test()
queue.event(callback(count5), 1).post(1, 1, 1, 1);
queue.event(callback(count5)).post(1, 1, 1, 1, 1);

queue.dispatch(0);
queue.dispatch_once();

TEST_ASSERT_EQUAL(counter, 60);
}
Expand Down Expand Up @@ -317,7 +317,7 @@ void time_left_test()
TEST_ASSERT(timeleft_events[0]);
TEST_ASSERT(timeleft_events[1]);

queue.dispatch(300);
queue.dispatch_for(300ms);

// Ensure check was called
TEST_ASSERT(touched);
Expand All @@ -326,7 +326,7 @@ void time_left_test()
int id = queue.call(func0);
TEST_ASSERT(id);
TEST_ASSERT_EQUAL(0, queue.time_left(id));
queue.dispatch(10);
queue.dispatch_for(10ms);

// Test invalid event id
TEST_ASSERT_EQUAL(-1, queue.time_left(0));
Expand Down Expand Up @@ -418,7 +418,7 @@ void mixed_dynamic_static_events_queue_test()
ue4.cancel();
e2.cancel();

queue.dispatch(101);
queue.dispatch_for(101ms);

TEST_ASSERT_EQUAL(true, touched);
TEST_ASSERT_EQUAL(1, ue1_test.counter);
Expand Down Expand Up @@ -491,7 +491,7 @@ void static_events_queue_test()
g_queue.cancel(&ue4);
g_queue.cancel(&ue4);

g_queue.dispatch(400);
g_queue.dispatch_for(400ms);

TEST_ASSERT_EQUAL(2, test1.counter);
TEST_ASSERT_EQUAL(6, test2.counter);
Expand All @@ -500,7 +500,7 @@ void static_events_queue_test()

ue4.delay(1);
TEST_ASSERT_EQUAL(true, ue4.try_call());
g_queue.dispatch(1);
g_queue.dispatch_for(1ms);

TEST_ASSERT_EQUAL(2, test1.counter);
TEST_ASSERT_EQUAL(6, test2.counter);
Expand All @@ -525,7 +525,7 @@ void event_period_tests()
event1.delay(10ms);
event1.period(events::non_periodic);
event1.post();
period_tests_queue.dispatch(80);
period_tests_queue.dispatch_for(80ms);

// Wait 100ms and check the event execution status
wait_us(100 * 1000);
Expand All @@ -543,7 +543,7 @@ void event_period_tests()
event2.delay(10ms);
event2.period(-10ms);
event2.post();
period_tests_queue.dispatch(80);
period_tests_queue.dispatch_for(80ms);

// Wait 100ms and check the event execution status
wait_us(100 * 1000);
Expand All @@ -561,7 +561,7 @@ void event_period_tests()
event3.delay(10ms);
event3.period(0ms);
event3.post();
period_tests_queue.dispatch(80);
period_tests_queue.dispatch_for(80ms);

// Wait 100ms and check the event execution status
wait_us(100 * 1000);
Expand All @@ -578,7 +578,7 @@ void event_period_tests()
event4.delay(10ms);
event4.period(20ms);
event4.post();
period_tests_queue.dispatch(80);
period_tests_queue.dispatch_for(80ms);

// Wait 100ms and check the event execution status
wait_us(100 * 1000);
Expand Down