aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--readme.txt10
-rw-r--r--test/testevt.c159
-rw-r--r--test/testheap.c31
-rw-r--r--test/testsem.c47
-rw-r--r--test/testthd.c10
5 files changed, 222 insertions, 35 deletions
diff --git a/readme.txt b/readme.txt
index 9fb3876be..e8b31e4b5 100644
--- a/readme.txt
+++ b/readme.txt
@@ -84,11 +84,11 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process,
- FIX: Removed usused list functions (bug 2755230)(backported in stable
branch).
- NEW: Added a code coverage analysis application under ./tests/coverage.
-- Added more test cases in order to improve the test suite code coverage (it
- was 74% in version 1.2.0).
-- Added a new "naked" context switch benchmark that better defines the
- real context switch time, for the STM32 the context switch is performed
- under 1.48uS.
+- NEW: Added more test cases in order to improve the test suite code coverage
+ (it was 74% in version 1.2.0).
+- NEW: Added a new "naked" context switch benchmark that better defines the
+ real context switch time, previous benchmarks introduced too much overhead
+ to the measurement. The STM32 performs the context switch in under 1.48uS.
*** 1.2.0 ***
- Added license exception text to the 1.2.0 branch.
diff --git a/test/testevt.c b/test/testevt.c
index 9c6f7bf6e..3987a41e8 100644
--- a/test/testevt.c
+++ b/test/testevt.c
@@ -29,7 +29,7 @@ static EventSource es1, es2;
static char *evt1_gettest(void) {
- return "Events, wait and broadcast";
+ return "Events, registration and dispatch";
}
static void evt1_setup(void) {
@@ -37,7 +37,58 @@ static void evt1_setup(void) {
chEvtClear(ALL_EVENTS);
}
-static msg_t thread(void *p) {
+static void h1(eventid_t id) {test_emit_token('A');}
+static void h2(eventid_t id) {test_emit_token('B');}
+static void h3(eventid_t id) {test_emit_token('C');}
+static const evhandler_t evhndl[] = {h1, h2, h3};
+
+static void evt1_execute(void) {
+ EventListener el1, el2;
+
+ /*
+ * Testing chEvtRegisterMask() and chEvtUnregister().
+ */
+ chEvtInit(&es1);
+ chEvtRegisterMask(&es1, &el1, 1);
+ chEvtRegisterMask(&es1, &el2, 2);
+ test_assert(chEvtIsListening(&es1), "#1"); /* Must not be empty */
+ chEvtUnregister(&es1, &el1);
+ test_assert(chEvtIsListening(&es1), "#2"); /* Must not be empty */
+ chEvtUnregister(&es1, &el2);
+ test_assert(!chEvtIsListening(&es1), "#3"); /* Stuck listener.*/
+
+ /*
+ * Testing chEvtDispatch().
+ */
+ chEvtDispatch(evhndl, 7);
+ test_assert_sequence("ABC");
+}
+
+const struct testcase testevt1 = {
+ evt1_gettest,
+ evt1_setup,
+ NULL,
+ evt1_execute
+};
+
+static char *evt2_gettest(void) {
+
+ return "Events, wait and broadcast";
+}
+
+static void evt2_setup(void) {
+
+ chEvtClear(ALL_EVENTS);
+}
+
+static msg_t thread1(void *p) {
+
+ chThdSleepMilliseconds(50);
+ chEvtSignal((Thread *)p, 1);
+ return 0;
+}
+
+static msg_t thread2(void *p) {
chEvtBroadcast(&es1);
chThdSleepMilliseconds(50);
@@ -45,13 +96,13 @@ static msg_t thread(void *p) {
return 0;
}
-static void evt1_execute(void) {
+static void evt2_execute(void) {
eventmask_t m;
EventListener el1, el2;
systime_t target_time;
/*
- * Test on chEvtWaitOne().
+ * Test on chEvtWaitOne() without wait.
*/
chEvtPend(5);
m = chEvtWaitOne(ALL_EVENTS);
@@ -59,43 +110,111 @@ static void evt1_execute(void) {
m = chEvtWaitOne(ALL_EVENTS);
test_assert(m == 4, "#2"); /* Single bit error.*/
m = chEvtClear(0);
- test_assert(m == 0, "#3"); /* Stuck event.*/
+ test_assert(m == 0, "#3"); /* Stuck bit.*/
+
+ /*
+ * Test on chEvtWaitOne() with wait.
+ */
+ test_wait_tick();
+ target_time = chTimeNow() + MS2ST(50);
+ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority() - 1,
+ thread1, chThdSelf());
+ m = chEvtWaitOne(ALL_EVENTS);
+ test_assert_time_window(target_time, target_time + ALLOWED_DELAY);
+ test_assert(m == 1, "#5"); /* Single bit error.*/
+ m = chEvtClear(0);
+ test_assert(m == 0, "#6"); /* Stuck bit.*/
+ test_wait_threads();
/*
- * Test on chEvtWaitAny().
+ * Test on chEvtWaitAny() without wait.
*/
chEvtPend(5);
m = chEvtWaitAny(ALL_EVENTS);
- test_assert(m == 5, "#4"); /* Unexpected pending.*/
+ test_assert(m == 5, "#7"); /* Unexpected pending bit.*/
m = chEvtClear(0);
- test_assert(m == 0, "#5"); /* Stuck event.*/
+ test_assert(m == 0, "#8"); /* Stuck bit.*/
/*
- * Test on chEvtWaitAll(), chEvtRegisterMask() and chEvtUnregister().
+ * Test on chEvtWaitAny() with wait.
+ */
+ test_wait_tick();
+ target_time = chTimeNow() + MS2ST(50);
+ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority() - 1,
+ thread1, chThdSelf());
+ m = chEvtWaitAny(ALL_EVENTS);
+ test_assert_time_window(target_time, target_time + ALLOWED_DELAY);
+ test_assert(m == 1, "#9"); /* Single bit error.*/
+ m = chEvtClear(0);
+ test_assert(m == 0, "#10"); /* Stuck bit.*/
+ test_wait_threads();
+
+ /*
+ * Test on chEvtWaitAll().
*/
chEvtInit(&es1);
chEvtInit(&es2);
chEvtRegisterMask(&es1, &el1, 1);
chEvtRegisterMask(&es2, &el2, 4);
+ test_wait_tick();
target_time = chTimeNow() + MS2ST(50);
- threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority()-1, thread, "A");
+ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority() - 1,
+ thread2, "A");
m = chEvtWaitAll(5);
test_assert_time_window(target_time, target_time + ALLOWED_DELAY);
m = chEvtClear(0);
- test_assert(m == 0, "#6"); /* Stuck event.*/
-
+ test_assert(m == 0, "#11"); /* Stuck event.*/
test_wait_threads();
chEvtUnregister(&es1, &el1);
chEvtUnregister(&es2, &el2);
- test_assert(!chEvtIsListening(&es1), "#7"); /* Stuck listener.*/
- test_assert(!chEvtIsListening(&es2), "#8"); /* Stuck listener.*/
+ test_assert(!chEvtIsListening(&es1), "#12"); /* Stuck listener.*/
+ test_assert(!chEvtIsListening(&es2), "#13"); /* Stuck listener.*/
}
-const struct testcase testevt1 = {
- evt1_gettest,
- evt1_setup,
+const struct testcase testevt2 = {
+ evt2_gettest,
+ evt2_setup,
NULL,
- evt1_execute
+ evt2_execute
+};
+
+#if CH_USE_EVENTS_TIMEOUT
+static char *evt3_gettest(void) {
+
+ return "Events, timeouts";
+}
+
+static void evt3_setup(void) {
+
+ chEvtClear(ALL_EVENTS);
+}
+
+static void evt3_execute(void) {
+ eventmask_t m;
+
+ /*
+ * Tests various timeout situations.
+ */
+ m = chEvtWaitOneTimeout(ALL_EVENTS, TIME_IMMEDIATE);
+ test_assert(m == 0, "#1");
+ m = chEvtWaitAnyTimeout(ALL_EVENTS, TIME_IMMEDIATE);
+ test_assert(m == 0, "#2");
+ m = chEvtWaitAllTimeout(ALL_EVENTS, TIME_IMMEDIATE);
+ test_assert(m == 0, "#3");
+ m = chEvtWaitOneTimeout(ALL_EVENTS, 10);
+ test_assert(m == 0, "#4");
+ m = chEvtWaitAnyTimeout(ALL_EVENTS, 10);
+ test_assert(m == 0, "#5");
+ m = chEvtWaitAllTimeout(ALL_EVENTS, 10);
+ test_assert(m == 0, "#6");
+#endif
+}
+
+const struct testcase testevt3 = {
+ evt3_gettest,
+ evt3_setup,
+ NULL,
+ evt3_execute
};
#endif /* CH_USE_EVENTS */
@@ -106,6 +225,10 @@ const struct testcase testevt1 = {
const struct testcase * const patternevt[] = {
#if CH_USE_EVENTS
&testevt1,
+ &testevt2,
+#if CH_USE_EVENTS_TIMEOUT
+ &testevt3,
+#endif
#endif
NULL
};
diff --git a/test/testheap.c b/test/testheap.c
index a72bad6bb..2740f8a9e 100644
--- a/test/testheap.c
+++ b/test/testheap.c
@@ -44,21 +44,38 @@ static void heap1_execute(void) {
p1 = chHeapAlloc(SIZE);
p2 = chHeapAlloc(SIZE);
p3 = chHeapAlloc(SIZE);
- chHeapFree(p1); /* Does not merge */
- chHeapFree(p2); /* Merges backward */
- chHeapFree(p3); /* Merges both sides */
+ chHeapFree(p1); /* Does not merge */
+ chHeapFree(p2); /* Merges backward */
+ chHeapFree(p3); /* Merges both sides */
test_assert(chHeapStatus(&n) == 1, "#1"); /* Heap fragmented.*/
/* Reverse order */
p1 = chHeapAlloc(SIZE);
p2 = chHeapAlloc(SIZE);
p3 = chHeapAlloc(SIZE);
- chHeapFree(p3); /* Merges forward */
- chHeapFree(p2); /* Merges forward */
- chHeapFree(p1); /* Merges forward */
+ chHeapFree(p3); /* Merges forward */
+ chHeapFree(p2); /* Merges forward */
+ chHeapFree(p1); /* Merges forward */
test_assert(chHeapStatus(&n) == 1, "#2"); /* Heap fragmented.*/
- test_assert(n == sz, "#3"); /* Heap size changed.*/
+ /* Small fragments handling */
+ p1 = chHeapAlloc(SIZE + 1);
+ p2 = chHeapAlloc(SIZE);
+ chHeapFree(p1);
+ test_assert(chHeapStatus(&n) == 2, "#3"); /* Heap must contain 2 blocks.*/
+ p1 = chHeapAlloc(SIZE);
+ test_assert(chHeapStatus(&n) == 1, "#4"); /* Heap fragmented.*/
+ chHeapFree(p2);
+ chHeapFree(p1);
+
+ /* Allocate all handling */
+ (void)chHeapStatus(&n);
+ p1 = chHeapAlloc(n);
+ test_assert(chHeapStatus(&n) == 0, "#5"); /* Heap must be empty.*/
+ chHeapFree(p1);
+
+ test_assert(chHeapStatus(&n) == 1, "#6"); /* Heap fragmented.*/
+ test_assert(n == sz, "#7"); /* Heap size changed.*/
}
else {
test_print("--- Size : ");
diff --git a/test/testsem.c b/test/testsem.c
index d6e432a36..eac0e041b 100644
--- a/test/testsem.c
+++ b/test/testsem.c
@@ -85,7 +85,10 @@ static void sem2_setup(void) {
static msg_t thread2(void *p) {
chThdSleepMilliseconds(50);
- chSemSignal(&sem1);
+ chSysLock();
+ chSemSignalI(&sem1); /* For coverage reasons */
+ chSchRescheduleS();
+ chSysUnlock();
return 0;
}
@@ -115,6 +118,7 @@ static void sem2_execute(void) {
/*
* Testing timeout condition.
*/
+ test_wait_tick();
target_time = chTimeNow() + MS2ST(5 * 500);
for (i = 0; i < 5; i++) {
test_emit_token('A' + i);
@@ -134,6 +138,44 @@ const struct testcase testsem2 = {
sem2_execute
};
#endif /* CH_USE_SEMAPHORES_TIMEOUT */
+
+#if CH_USE_SEMSW
+static char *sem3_gettest(void) {
+
+ return "Semaphores, atomic signal-wait";
+}
+
+static void sem3_setup(void) {
+
+ chSemInit(&sem1, 0);
+}
+
+static msg_t thread3(void *p) {
+
+ chSemWait(&sem1);
+ chSemSignal(&sem1);
+ return 0;
+}
+
+static void sem3_execute(void) {
+
+ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority()+1, thread3, "A");
+ chSemSignalWait(&sem1, &sem1);
+ test_assert(isempty(&sem1.s_queue), "#1"); /* Queue not empty */
+ test_assert(sem1.s_cnt == 0, "#2"); /* Counter not zero */
+
+ chSemSignalWait(&sem1, &sem1);
+ test_assert(isempty(&sem1.s_queue), "#3"); /* Queue not empty */
+ test_assert(sem1.s_cnt == 0, "#4"); /* Counter not zero */
+}
+
+const struct testcase testsem3 = {
+ sem3_gettest,
+ sem3_setup,
+ NULL,
+ sem3_execute
+};
+#endif /* CH_USE_SEMSW */
#endif /* CH_USE_SEMAPHORES */
/*
@@ -145,6 +187,9 @@ const struct testcase * const patternsem[] = {
#if CH_USE_SEMAPHORES_TIMEOUT
&testsem2,
#endif
+#if CH_USE_SEMSW
+ &testsem3,
+#endif
#endif
NULL
};
diff --git a/test/testthd.c b/test/testthd.c
index cac77a43a..e5964f17f 100644
--- a/test/testthd.c
+++ b/test/testthd.c
@@ -130,25 +130,27 @@ static char *thd4_gettest(void) {
static void thd4_execute(void) {
systime_t time;
+ test_wait_tick();
+
/* Timeouts in microseconds.*/
time = chTimeNow();
chThdSleepMicroseconds(100000);
- test_assert(chTimeIsWithin(time + US2ST(100000), time + US2ST(100000) + 1), "#1");
+ test_assert_time_window(time + US2ST(100000), time + US2ST(100000) + 1);
/* Timeouts in milliseconds.*/
time = chTimeNow();
chThdSleepMilliseconds(100);
- test_assert(chTimeIsWithin(time + MS2ST(100), time + MS2ST(100) + 1), "#2");
+ test_assert_time_window(time + MS2ST(100), time + MS2ST(100) + 1);
/* Timeouts in seconds.*/
time = chTimeNow();
chThdSleepSeconds(1);
- test_assert(chTimeIsWithin(time + S2ST(1), time + S2ST(1) + 1), "#3");
+ test_assert_time_window(time + S2ST(1), time + S2ST(1) + 1);
/* Absolute timelines.*/
time = chTimeNow() + MS2ST(100);
chThdSleepUntil(time);
- test_assert(chTimeIsWithin(time, time + 1), "#4");
+ test_assert_time_window(time, time + 1);
}
const struct testcase testthd4 = {