git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8950 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
Giovanni Di Sirio 2016-02-26 10:28:00 +00:00
parent e628eeb852
commit a6eed37d26
2 changed files with 31 additions and 12 deletions

View File

@ -1311,7 +1311,8 @@ int32 OS_TaskCreate(uint32 *task_id,
/* Checking if this working area is already in use by some thread, the /* Checking if this working area is already in use by some thread, the
error code is not very appropriate but this case seems to not be error code is not very appropriate but this case seems to not be
coveded by the specification.*/ coveded by the specification.*/
if ((tp = chRegFindThreadByWorkingArea((stkalign_t *)stack_pointer)) != NULL) { tp = chRegFindThreadByWorkingArea((stkalign_t *)stack_pointer);
if (tp != NULL) {
/* Releasing the thread reference.*/ /* Releasing the thread reference.*/
chThdRelease(tp); chThdRelease(tp);
return OS_ERR_NO_FREE_IDS; return OS_ERR_NO_FREE_IDS;
@ -1339,8 +1340,10 @@ int32 OS_TaskCreate(uint32 *task_id,
NULL NULL
}; };
/* Creating the task.*/ /* Creating the task and detaching it, other APIs will have to gain a
reference using the registry API.*/
tp = chThdCreate(&td); tp = chThdCreate(&td);
chThdRelease(tp);
/* Storing the task id.*/ /* Storing the task id.*/
*task_id = (uint32)tp; *task_id = (uint32)tp;
@ -1377,8 +1380,9 @@ int32 OS_TaskInstallDeleteHandler(void *function_pointer) {
*/ */
int32 OS_TaskDelete(uint32 task_id) { int32 OS_TaskDelete(uint32 task_id) {
thread_t *tp = (thread_t *)task_id; thread_t *tp = (thread_t *)task_id;
funcptr_t fp;
/* Check for thread validity.*/ /* Check for thread validity, getting a reference.*/
if (chRegFindThreadByPointer(tp) == NULL) { if (chRegFindThreadByPointer(tp) == NULL) {
return OS_ERR_INVALID_ID; return OS_ERR_INVALID_ID;
} }
@ -1386,17 +1390,17 @@ int32 OS_TaskDelete(uint32 task_id) {
/* Asking for thread termination.*/ /* Asking for thread termination.*/
chThdTerminate(tp); chThdTerminate(tp);
/* Waiting for termination.*/ /* Getting the delete handler while the thread is still referenced.*/
fp = (funcptr_t)tp->osal_delete_handler;
/* Waiting for termination, releasing the reference.*/
chThdWait(tp); chThdWait(tp);
/* Calling the delete handler, if defined.*/ /* Calling the delete handler, if defined.*/
if (tp->osal_delete_handler != NULL) { if (fp != NULL) {
((funcptr_t)(tp->osal_delete_handler))(); fp();
} }
/* Releasing the thread reference.*/
chThdRelease(tp);
return OS_SUCCESS; return OS_SUCCESS;
} }

View File

@ -462,9 +462,9 @@ void chThdExit(msg_t msg) {
* @details The thread goes in the @p CH_STATE_FINAL state holding the * @details The thread goes in the @p CH_STATE_FINAL state holding the
* specified exit status code, other threads can retrieve the * specified exit status code, other threads can retrieve the
* exit status code by invoking the function @p chThdWait(). * exit status code by invoking the function @p chThdWait().
* @post Exiting a thread that does not have references (detached) * @post Exiting a non-static thread that does not have references
* causes the thread to remain in the registry. It can only * (detached) causes the thread to remain in the registry.
* be removed by performing a registry scan operation. * It can only be removed by performing a registry scan operation.
* @post Eventual code after this function will never be executed, * @post Eventual code after this function will never be executed,
* this function never returns. The compiler has no way to * this function never returns. The compiler has no way to
* know this so do not assume that the compiler would remove * know this so do not assume that the compiler would remove
@ -490,6 +490,21 @@ void chThdExitS(msg_t msg) {
} }
#endif #endif
#if CH_CFG_USE_REGISTRY == TRUE
/* Static threads with no references are immediately removed from the
registry because there is no memory to recover.*/
#if CH_CFG_USE_DYNAMIC == TRUE
if ((tp->refs == (trefs_t)0) &&
(tp->flags & CH_FLAG_MODE_MASK) == CH_FLAG_MODE_STATIC) {
REG_REMOVE(tp);
}
#else
if (tp->refs == (trefs_t)0) {
REG_REMOVE(tp);
}
#endif
#endif
/* Going into final state.*/ /* Going into final state.*/
chSchGoSleepS(CH_STATE_FINAL); chSchGoSleepS(CH_STATE_FINAL);