aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2016-02-26 10:28:00 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2016-02-26 10:28:00 +0000
commita6eed37d26ba0ca617e8e1f3b3eca31449a26fdb (patch)
tree12c26c9f611a6194e640b9283d28c261fa2c67b1 /os
parente628eeb8528f8d23d47ca5bf04ab0ee4fe3238ca (diff)
downloadChibiOS-a6eed37d26ba0ca617e8e1f3b3eca31449a26fdb.tar.gz
ChibiOS-a6eed37d26ba0ca617e8e1f3b3eca31449a26fdb.tar.bz2
ChibiOS-a6eed37d26ba0ca617e8e1f3b3eca31449a26fdb.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8950 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/common/abstractions/nasa_osal/src/osapi.c22
-rw-r--r--os/rt/src/chthreads.c21
2 files changed, 31 insertions, 12 deletions
diff --git a/os/common/abstractions/nasa_osal/src/osapi.c b/os/common/abstractions/nasa_osal/src/osapi.c
index a367c339b..0a805a99a 100644
--- a/os/common/abstractions/nasa_osal/src/osapi.c
+++ b/os/common/abstractions/nasa_osal/src/osapi.c
@@ -1311,7 +1311,8 @@ int32 OS_TaskCreate(uint32 *task_id,
/* 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
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.*/
chThdRelease(tp);
return OS_ERR_NO_FREE_IDS;
@@ -1339,8 +1340,10 @@ int32 OS_TaskCreate(uint32 *task_id,
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);
+ chThdRelease(tp);
/* Storing the task id.*/
*task_id = (uint32)tp;
@@ -1377,8 +1380,9 @@ int32 OS_TaskInstallDeleteHandler(void *function_pointer) {
*/
int32 OS_TaskDelete(uint32 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) {
return OS_ERR_INVALID_ID;
}
@@ -1386,17 +1390,17 @@ int32 OS_TaskDelete(uint32 task_id) {
/* Asking for thread termination.*/
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);
/* Calling the delete handler, if defined.*/
- if (tp->osal_delete_handler != NULL) {
- ((funcptr_t)(tp->osal_delete_handler))();
+ if (fp != NULL) {
+ fp();
}
- /* Releasing the thread reference.*/
- chThdRelease(tp);
-
return OS_SUCCESS;
}
diff --git a/os/rt/src/chthreads.c b/os/rt/src/chthreads.c
index e809fbb13..943ca7d7c 100644
--- a/os/rt/src/chthreads.c
+++ b/os/rt/src/chthreads.c
@@ -462,9 +462,9 @@ void chThdExit(msg_t msg) {
* @details The thread goes in the @p CH_STATE_FINAL state holding the
* specified exit status code, other threads can retrieve the
* exit status code by invoking the function @p chThdWait().
- * @post Exiting a thread that does not have references (detached)
- * causes the thread to remain in the registry. It can only
- * be removed by performing a registry scan operation.
+ * @post Exiting a non-static thread that does not have references
+ * (detached) causes the thread to remain in the registry.
+ * It can only be removed by performing a registry scan operation.
* @post Eventual code after this function will never be executed,
* this function never returns. The compiler has no way to
* know this so do not assume that the compiler would remove
@@ -490,6 +490,21 @@ void chThdExitS(msg_t msg) {
}
#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.*/
chSchGoSleepS(CH_STATE_FINAL);