Fixed bug 3116888.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2425 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
a5bdf86e5b
commit
d973c3f25a
|
@ -71,17 +71,24 @@ void chThdRelease(Thread *tp) {
|
|||
refs = --tp->p_refs;
|
||||
chSysUnlock();
|
||||
|
||||
/* If the references counter reaches zero then the memory can be returned
|
||||
to the proper allocator. Of course static threads are not affected.*/
|
||||
if (refs == 0) {
|
||||
/* If the references counter reaches zero and the thread is in its
|
||||
terminated state then the memory can be returned to the proper
|
||||
allocator. Of course static threads are not affected.*/
|
||||
if ((refs == 0) && (tp->p_state == THD_STATE_FINAL)) {
|
||||
switch (tp->p_flags & THD_MEM_MODE_MASK) {
|
||||
#if CH_USE_HEAP
|
||||
case THD_MEM_MODE_HEAP:
|
||||
#if CH_USE_REGISTRY
|
||||
REG_REMOVE(tp);
|
||||
#endif
|
||||
chHeapFree(tp);
|
||||
break;
|
||||
#endif
|
||||
#if CH_USE_MEMPOOLS
|
||||
case THD_MEM_MODE_MEMPOOL:
|
||||
#if CH_USE_REGISTRY
|
||||
REG_REMOVE(tp);
|
||||
#endif
|
||||
chPoolFree(tp->p_mpool, tp);
|
||||
break;
|
||||
#endif
|
||||
|
|
|
@ -342,6 +342,9 @@ void chThdExit(msg_t msg) {
|
|||
chSchReadyI(list_remove(&tp->p_waiting));
|
||||
#endif
|
||||
#if CH_USE_REGISTRY
|
||||
/* Static threads are immediately removed from the registry because
|
||||
there is no memory to recover.*/
|
||||
if ((tp->p_flags & THD_MEM_MODE_MASK) == THD_MEM_MODE_STATIC)
|
||||
REG_REMOVE(tp);
|
||||
#endif
|
||||
chSchGoSleepS(THD_STATE_FINAL);
|
||||
|
|
|
@ -65,6 +65,8 @@
|
|||
*****************************************************************************
|
||||
|
||||
*** 2.1.4 ***
|
||||
- FIX: Fixed failed memory recovery by registry scan, improved the related
|
||||
test case (bug 3116888)(backported to 2.0.8).
|
||||
- FIX: Fixed failure in STM32 ADC driver when a linear buffer mode is used
|
||||
(bug 3114696).
|
||||
- FIX: Fixed PWM channels going to ACTIVE state when the pulse width is
|
||||
|
|
|
@ -190,16 +190,16 @@ ROMCONST struct testcase testdyn2 = {
|
|||
* coverage.
|
||||
*/
|
||||
|
||||
static unsigned regscan(void) {
|
||||
Thread *tp;
|
||||
unsigned i = 0;
|
||||
static bool_t regfind(Thread *tp) {
|
||||
Thread *ftp;
|
||||
bool_t found = FALSE;
|
||||
|
||||
tp = chRegFirstThread();
|
||||
ftp = chRegFirstThread();
|
||||
do {
|
||||
i++;
|
||||
tp = chRegNextThread(tp);
|
||||
} while (tp != NULL);
|
||||
return i;
|
||||
found |= ftp == tp;
|
||||
ftp = chRegNextThread(ftp);
|
||||
} while (ftp != NULL);
|
||||
return found;
|
||||
}
|
||||
|
||||
static void dyn3_setup(void) {
|
||||
|
@ -208,15 +208,9 @@ static void dyn3_setup(void) {
|
|||
}
|
||||
|
||||
static void dyn3_execute(void) {
|
||||
unsigned n1, n2, n3;
|
||||
Thread *tp;
|
||||
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.*/
|
||||
tp = chThdCreateFromHeap(&heap1, WA_SIZE, prio-1, thread, "A");
|
||||
test_assert(1, tp->p_refs == 1, "wrong initial reference counter");
|
||||
|
@ -226,18 +220,21 @@ static void dyn3_execute(void) {
|
|||
test_assert(3, tp->p_refs == 1, "references decrease failure");
|
||||
|
||||
/* Verify the new threads count.*/
|
||||
n2 = regscan();
|
||||
test_assert(4, n1 == n2 - 1, "unexpected threads count");
|
||||
test_assert(4, regfind(tp), "thread missing from registry");
|
||||
test_assert(5, regfind(tp), "thread disappeared");
|
||||
|
||||
/* Detach and let the thread execute and terminate.*/
|
||||
chThdRelease(tp);
|
||||
test_assert(5, tp->p_refs == 0, "detach failure");
|
||||
test_assert(6, tp->p_refs == 0, "detach failure");
|
||||
test_assert(7, tp->p_state == THD_STATE_READY, "invalid state");
|
||||
test_assert(8, regfind(tp), "thread disappeared");
|
||||
test_assert(9, regfind(tp), "thread disappeared");
|
||||
chThdSleepMilliseconds(50); /* The thread just terminates. */
|
||||
test_assert(6, tp->p_state == THD_STATE_FINAL, "invalid state");
|
||||
test_assert(10, tp->p_state == THD_STATE_FINAL, "invalid state");
|
||||
|
||||
/* Clearing the zombie by scanning the registry.*/
|
||||
n3 = regscan();
|
||||
test_assert(7, n1 == n3, "unexpected threads count");
|
||||
test_assert(11, regfind(tp), "thread disappeared");
|
||||
test_assert(12, !regfind(tp), "thread still in registry");
|
||||
}
|
||||
|
||||
ROMCONST struct testcase testdyn3 = {
|
||||
|
|
Loading…
Reference in New Issue