Skip to content

Commit 071098d

Browse files
author
Bogdan Marinescu
committed
Added Event and EventLoop
Event is a callback that executes either immediately, like a regular callback, or is posted in an event queue for defered execution. EventLoop is a queue of events, built on top of the DynamicMail object. It runs in its own thread and dispatches events as they arrive in the mail.
1 parent a4b33c0 commit 071098d

File tree

6 files changed

+980
-0
lines changed

6 files changed

+980
-0
lines changed

TESTS/mbed_drivers/event/main.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2016 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES Ovoid CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "mbed.h"
18+
#include "greentea-client/test_env.h"
19+
#include "unity/unity.h"
20+
#include "utest/utest.h"
21+
#include "EventLoop.h"
22+
#include "Event.h"
23+
#include <stdio.h>
24+
25+
using namespace utest::v1;
26+
27+
static EventLoop queue(16);
28+
static osThreadId main_thread_id;
29+
static osThreadId expected_thread_id;
30+
static volatile uint32_t call_count;
31+
32+
static void test_func() {
33+
if (expected_thread_id == NULL) {
34+
// We're testing the event queue, so save the queue thread ID for subsequent
35+
// tests (and make sure that we're not running in the main context).
36+
TEST_ASSERT_NOT_EQUAL((uint32_t)expected_thread_id, (uint32_t)main_thread_id);
37+
expected_thread_id = Thread::gettid();
38+
} else {
39+
TEST_ASSERT_EQUAL((uint32_t)expected_thread_id, (uint32_t)Thread::gettid());
40+
}
41+
call_count ++;
42+
}
43+
44+
static void test_immediate_events() {
45+
expected_thread_id = main_thread_id;
46+
call_count = 0;
47+
// Post 10 "regular" events (they'll execute immediately in
48+
// the context of the main thread)
49+
for (unsigned i = 0; i < 10; i ++) {
50+
event(test_func, NULL).call();
51+
TEST_ASSERT_EQUAL_UINT32(call_count, i + 1);
52+
}
53+
}
54+
55+
static void test_queued_events() {
56+
// We don't know the event thread ID. it'll be set by the first call to test_func
57+
expected_thread_id = NULL;
58+
call_count = 0;
59+
// Start event thread now
60+
queue.start();
61+
// Post 10 events that will be queued
62+
for (unsigned i = 0; i < 10; i ++) {
63+
event(test_func, &queue).call();
64+
}
65+
// Wait for them to finish
66+
while (call_count < 10) {
67+
wait_ms(10);
68+
}
69+
// Wait a bit more and check count again to check that no more events are executed
70+
wait_ms(200);
71+
TEST_ASSERT_EQUAL_UINT32(call_count, 10);
72+
}
73+
74+
static Case cases[] = {
75+
Case("Test immediate events", test_immediate_events),
76+
Case("Test queued events", test_queued_events)
77+
};
78+
79+
static status_t greentea_test_setup(const size_t number_of_cases) {
80+
GREENTEA_SETUP(20, "default_auto");
81+
return greentea_test_setup_handler(number_of_cases);
82+
}
83+
84+
static Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
85+
86+
int main() {
87+
main_thread_id = Thread::gettid();
88+
// Run tests
89+
Harness::run(specification);
90+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2016 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES Ovoid CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "mbed.h"
18+
#include "greentea-client/test_env.h"
19+
#include "unity/unity.h"
20+
#include "utest/utest.h"
21+
#include "EventLoop.h"
22+
#include "Callback.h"
23+
#include <stdio.h>
24+
25+
using namespace utest::v1;
26+
27+
static EventLoop loop(16);
28+
static osThreadId main_thread_id;
29+
static osThreadId other_thread_id;
30+
static volatile uint32_t cb_count;
31+
32+
static void cb1() {
33+
if (cb_count == 0) {
34+
// Check that we don't run in the main thread context
35+
TEST_ASSERT_NOT_EQUAL((uint32_t)Thread::gettid(), (uint32_t)main_thread_id);
36+
// And save current running context
37+
other_thread_id = Thread::gettid();
38+
} else {
39+
// Check that we're running in the same context as before
40+
TEST_ASSERT_EQUAL((uint32_t)Thread::gettid(), (uint32_t)other_thread_id);
41+
}
42+
cb_count ++;
43+
}
44+
45+
static void test_event_loop_callbacks() {
46+
// Post 10 callbacks
47+
for (unsigned i = 0; i < 10; i ++) {
48+
loop.post(callback(cb1));
49+
}
50+
// Wait for all callbacks to finish
51+
while (cb_count < 10) {
52+
wait_ms(10);
53+
}
54+
// Wait a bit more and check count again to check that no more events are executed
55+
wait_ms(200);
56+
TEST_ASSERT_EQUAL_UINT32(cb_count, 10);
57+
}
58+
59+
static Case cases[] = {
60+
Case("Test event loop callbacks", test_event_loop_callbacks)
61+
};
62+
63+
static status_t greentea_test_setup(const size_t number_of_cases) {
64+
GREENTEA_SETUP(20, "default_auto");
65+
return greentea_test_setup_handler(number_of_cases);
66+
}
67+
68+
static Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
69+
70+
int main() {
71+
// Start event thread
72+
main_thread_id = Thread::gettid();
73+
loop.start();
74+
// Run tests
75+
Harness::run(specification);
76+
}

0 commit comments

Comments
 (0)