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;
|
refs = --tp->p_refs;
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
|
||||||
/* If the references counter reaches zero then the memory can be returned
|
/* If the references counter reaches zero and the thread is in its
|
||||||
to the proper allocator. Of course static threads are not affected.*/
|
terminated state then the memory can be returned to the proper
|
||||||
if (refs == 0) {
|
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) {
|
switch (tp->p_flags & THD_MEM_MODE_MASK) {
|
||||||
#if CH_USE_HEAP
|
#if CH_USE_HEAP
|
||||||
case THD_MEM_MODE_HEAP:
|
case THD_MEM_MODE_HEAP:
|
||||||
|
#if CH_USE_REGISTRY
|
||||||
|
REG_REMOVE(tp);
|
||||||
|
#endif
|
||||||
chHeapFree(tp);
|
chHeapFree(tp);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if CH_USE_MEMPOOLS
|
#if CH_USE_MEMPOOLS
|
||||||
case THD_MEM_MODE_MEMPOOL:
|
case THD_MEM_MODE_MEMPOOL:
|
||||||
|
#if CH_USE_REGISTRY
|
||||||
|
REG_REMOVE(tp);
|
||||||
|
#endif
|
||||||
chPoolFree(tp->p_mpool, tp);
|
chPoolFree(tp->p_mpool, tp);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -342,7 +342,10 @@ void chThdExit(msg_t msg) {
|
||||||
chSchReadyI(list_remove(&tp->p_waiting));
|
chSchReadyI(list_remove(&tp->p_waiting));
|
||||||
#endif
|
#endif
|
||||||
#if CH_USE_REGISTRY
|
#if CH_USE_REGISTRY
|
||||||
REG_REMOVE(tp);
|
/* 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
|
#endif
|
||||||
chSchGoSleepS(THD_STATE_FINAL);
|
chSchGoSleepS(THD_STATE_FINAL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
|
||||||
*** 2.1.4 ***
|
*** 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
|
- FIX: Fixed failure in STM32 ADC driver when a linear buffer mode is used
|
||||||
(bug 3114696).
|
(bug 3114696).
|
||||||
- FIX: Fixed PWM channels going to ACTIVE state when the pulse width is
|
- FIX: Fixed PWM channels going to ACTIVE state when the pulse width is
|
||||||
|
|
|
@ -190,16 +190,16 @@ ROMCONST struct testcase testdyn2 = {
|
||||||
* coverage.
|
* coverage.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static unsigned regscan(void) {
|
static bool_t regfind(Thread *tp) {
|
||||||
Thread *tp;
|
Thread *ftp;
|
||||||
unsigned i = 0;
|
bool_t found = FALSE;
|
||||||
|
|
||||||
tp = chRegFirstThread();
|
ftp = chRegFirstThread();
|
||||||
do {
|
do {
|
||||||
i++;
|
found |= ftp == tp;
|
||||||
tp = chRegNextThread(tp);
|
ftp = chRegNextThread(ftp);
|
||||||
} while (tp != NULL);
|
} while (ftp != NULL);
|
||||||
return i;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyn3_setup(void) {
|
static void dyn3_setup(void) {
|
||||||
|
@ -208,15 +208,9 @@ static void dyn3_setup(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyn3_execute(void) {
|
static void dyn3_execute(void) {
|
||||||
unsigned n1, n2, n3;
|
|
||||||
Thread *tp;
|
Thread *tp;
|
||||||
tprio_t prio = chThdGetPriority();
|
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.*/
|
/* Testing references increase/decrease and final detach.*/
|
||||||
tp = chThdCreateFromHeap(&heap1, WA_SIZE, prio-1, thread, "A");
|
tp = chThdCreateFromHeap(&heap1, WA_SIZE, prio-1, thread, "A");
|
||||||
test_assert(1, tp->p_refs == 1, "wrong initial reference counter");
|
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");
|
test_assert(3, tp->p_refs == 1, "references decrease failure");
|
||||||
|
|
||||||
/* Verify the new threads count.*/
|
/* Verify the new threads count.*/
|
||||||
n2 = regscan();
|
test_assert(4, regfind(tp), "thread missing from registry");
|
||||||
test_assert(4, n1 == n2 - 1, "unexpected threads count");
|
test_assert(5, regfind(tp), "thread disappeared");
|
||||||
|
|
||||||
/* Detach and let the thread execute and terminate.*/
|
/* Detach and let the thread execute and terminate.*/
|
||||||
chThdRelease(tp);
|
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. */
|
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.*/
|
/* Clearing the zombie by scanning the registry.*/
|
||||||
n3 = regscan();
|
test_assert(11, regfind(tp), "thread disappeared");
|
||||||
test_assert(7, n1 == n3, "unexpected threads count");
|
test_assert(12, !regfind(tp), "thread still in registry");
|
||||||
}
|
}
|
||||||
|
|
||||||
ROMCONST struct testcase testdyn3 = {
|
ROMCONST struct testcase testdyn3 = {
|
||||||
|
|
Loading…
Reference in New Issue