diff --git a/demos/ARMCM3-STM32F103-FATFS-GCC/main.c b/demos/ARMCM3-STM32F103-FATFS-GCC/main.c index ddd85c8fc..cfe5fde8b 100644 --- a/demos/ARMCM3-STM32F103-FATFS-GCC/main.c +++ b/demos/ARMCM3-STM32F103-FATFS-GCC/main.c @@ -113,7 +113,7 @@ static void cmd_mem(BaseChannel *chp, int argc, char *argv[]) { return; } n = chHeapStatus(NULL, &size); - siprintf(buf, "core free memory : %lu bytes", chCoreFree()); + siprintf(buf, "core free memory : %lu bytes", chCoreStatus()); shellPrintLine(chp, buf); siprintf(buf, "heap fragments : %lu", n); shellPrintLine(chp, buf); diff --git a/demos/PPC-SPC563-GCC/main.c b/demos/PPC-SPC563-GCC/main.c index f2101c130..6e65e2263 100644 --- a/demos/PPC-SPC563-GCC/main.c +++ b/demos/PPC-SPC563-GCC/main.c @@ -37,7 +37,7 @@ static void cmd_mem(BaseChannel *chp, int argc, char *argv[]) { return; } n = chHeapStatus(NULL, &size); - siprintf(buf, "core free memory : %i bytes", chCoreFree()); + siprintf(buf, "core free memory : %i bytes", chCoreStatus()); shellPrintLine(chp, buf); siprintf(buf, "heap fragments : %i", n); shellPrintLine(chp, buf); diff --git a/demos/Win32-MinGW/main.c b/demos/Win32-MinGW/main.c index 1418b70ec..aa6d29716 100644 --- a/demos/Win32-MinGW/main.c +++ b/demos/Win32-MinGW/main.c @@ -42,7 +42,7 @@ static void cmd_mem(BaseChannel *chp, int argc, char *argv[]) { return; } n = chHeapStatus(NULL, &size); - sprintf(buf, "core free memory : %i bytes", chCoreFree()); + sprintf(buf, "core free memory : %i bytes", chCoreStatus()); shellPrintLine(chp, buf); sprintf(buf, "heap fragments : %i", n); shellPrintLine(chp, buf); diff --git a/os/kernel/include/chmemcore.h b/os/kernel/include/chmemcore.h index 7888222b3..4870c79f1 100644 --- a/os/kernel/include/chmemcore.h +++ b/os/kernel/include/chmemcore.h @@ -59,7 +59,7 @@ extern "C" { void core_init(void); void *chCoreAlloc(size_t size); void *chCoreAllocI(size_t size); - size_t chCoreFree(void); + size_t chCoreStatus(void); #ifdef __cplusplus } #endif diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index d0c657a48..f835e2111 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -109,11 +109,11 @@ void *chCoreAllocI(size_t size) { } /** - * @brief Core memory left. + * @brief Core memory status. * * @return The size, in bytes, of the free core memory. */ -size_t chCoreFree(void) { +size_t chCoreStatus(void) { return (size_t)(endmem - nextmem); } diff --git a/readme.txt b/readme.txt index c05ba2de7..54600c1d4 100644 --- a/readme.txt +++ b/readme.txt @@ -77,10 +77,15 @@ - CHANGE: Modified the STM32 FatFs demo, now it spawns a command shell or the serial port SD2, type "help" for the available commands. More commands can be easily added. +- CHANGE: Renamed the chCoreFree() function in chCoreStatus() because it + might be mistaken for a function that frees memory. - Various documentation fixes, added an article covering debugging under ChibiOS/RT, updated the article about interrupt handlers to cover also fast interrupt sources. - Long overdue test code cleanup and documentation. +- Added new test cases, now the coverage is again up to 100% except for the + debug module that would require triggering system terminating tests (panics), + the uncovered code is minimal and extremely simple anyway. *** 1.5.5 *** - FIX: Removed some "dead" code in the old ARMv7-M files (there are new diff --git a/test/testdyn.c b/test/testdyn.c index 2d05f346b..dcd2d951e 100644 --- a/test/testdyn.c +++ b/test/testdyn.c @@ -44,6 +44,7 @@ *

Test Cases

* - @subpage test_dynamic_001 * - @subpage test_dynamic_002 + * - @subpage test_dynamic_003 * . * @file testdyn.c * @brief Dynamic thread APIs test source file @@ -189,6 +190,77 @@ const struct testcase testdyn2 = { }; #endif /* CH_USE_MEMPOOLS */ +#if CH_USE_HEAP +/** + * @page test_dynamic_003 Registry and References test + * + *

Description

+ * Registry and Thread References APIs are tested for functionality and + * coverage. + */ + +static unsigned regscan(void) { + Thread *tp; + unsigned i = 0; + + tp = chRegFirstThread(); + do { + i++; + tp = chRegNextThread(tp); + } while (tp != NULL); + return i; +} + +static char *dyn3_gettest(void) { + + return "Dynamic APIs, registry and references"; +} + +static void dyn3_setup(void) { + + chHeapInit(&heap1, test.buffer, sizeof(union test_buffers)); +} + +static void dyn3_execute(void) { + unsigned n1, n2, n3; + tprio_t prio = chThdGetPriority(); + + /* Current number of threads in the system, two times just in case some + external detached thread terminated.*/ + (void)regscan(); + n1 = regscan(); + + /* Testing references increase/decrease and final detach.*/ + threads[0] = chThdCreateFromHeap(&heap1, THD_WA_SIZE(THREADS_STACK_SIZE), + prio-1, thread, "A"); + test_assert(1, threads[0]->p_refs == 1, "wrong initial reference counter"); + chThdAddRef(threads[0]); + test_assert(2, threads[0]->p_refs == 2, "references increase failure"); + chThdRelease(threads[0]); + test_assert(3, threads[0]->p_refs == 1, "references decrease failure"); + + /* Verify the new threads count.*/ + n2 = regscan(); + test_assert(4, n1 == n2 - 1, "unexpected threads count"); + + /* Detach and let the thread execute and terminate.*/ + chThdRelease(threads[0]); + test_assert(5, threads[0]->p_refs == 0, "detach failure"); + chThdSleepMilliseconds(50); /* The thread just terminates. */ + test_assert(6, threads[0]->p_state == THD_STATE_FINAL, "invalid state"); + + /* Clearing the zombie by scanning the registry.*/ + n3 = regscan(); + test_assert(7, n1 == n3, "unexpected threads count"); +} + +const struct testcase testdyn3 = { + dyn3_gettest, + dyn3_setup, + NULL, + dyn3_execute +}; +#endif /* CH_USE_HEAP */ #endif /* CH_USE_DYNAMIC */ /** @@ -202,6 +274,9 @@ const struct testcase * const patterndyn[] = { #if CH_USE_MEMPOOLS &testdyn2, #endif +#if CH_USE_HEAP + &testdyn3, +#endif #endif NULL }; diff --git a/test/testheap.c b/test/testheap.c index 2f4998be6..eb81f77ed 100644 --- a/test/testheap.c +++ b/test/testheap.c @@ -78,6 +78,9 @@ static void heap1_execute(void) { void *p1, *p2, *p3; size_t n, sz; + /* Unrelated, for coverage only.*/ + (void)chCoreStatus(); + /* * Test on the default heap in order to cover the core allocator at * least one time. diff --git a/test/testpools.c b/test/testpools.c index 75b26d50f..af4999547 100644 --- a/test/testpools.c +++ b/test/testpools.c @@ -60,6 +60,11 @@ static MEMORYPOOL_DECL(mp1, THD_WA_SIZE(THREADS_STACK_SIZE), NULL); * operation. */ +static void *null_provider(size_t size) { + + return NULL; +} + static char *pools1_gettest(void) { return "Memory Pools, queue/dequeue"; @@ -83,6 +88,10 @@ static void pools1_execute(void) { /* Now must be empty. */ test_assert(2, chPoolAlloc(&mp1) == NULL, "list not empty"); + + /* Covering the case where a provider is unable to return more memory.*/ + chPoolInit(&mp1, 16, null_provider); + test_assert(3, chPoolAlloc(&mp1) == NULL, "provider returned memory"); } const struct testcase testpools1 = {