From fde2a2cc60934f77816a4d2200b97127cdb3a6d2 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 25 Feb 2016 10:37:07 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8946 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/common/abstractions/nasa_osal/src/osapi.c | 44 ++++++++++---------- os/rt/include/chregistry.h | 1 + os/rt/src/chregistry.c | 27 ++++++++++++ 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/os/common/abstractions/nasa_osal/src/osapi.c b/os/common/abstractions/nasa_osal/src/osapi.c index bbbbd045c..f192a35e0 100644 --- a/os/common/abstractions/nasa_osal/src/osapi.c +++ b/os/common/abstractions/nasa_osal/src/osapi.c @@ -61,10 +61,6 @@ #error "NASA OSAL requires CH_CFG_USE_MEMPOOLS" #endif -#if CH_CFG_USE_DYNAMIC == FALSE -#error "NASA OSAL requires CH_CFG_USE_DYNAMIC" -#endif - /*===========================================================================*/ /* Module local definitions. */ /*===========================================================================*/ @@ -1312,17 +1308,35 @@ int32 OS_TaskCreate(uint32 *task_id, return OS_INVALID_INT_NUM; } + /* 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) { + return OS_ERR_NO_FREE_IDS; + } + + /* Checking if the name is already in use.*/ + if ((tp = chRegFindThreadByName(task_name)) != NULL) { + return OS_ERR_NAME_TAKEN; + } + /* Converting priority to RT type.*/ rt_prio = (tprio_t)256 - (tprio_t)priority; if (rt_prio == 1) { rt_prio = 2; } - tp = chThdCreateFromHeap(NULL, (size_t)stack_size, task_name, - rt_prio, (tfunc_t)function_pointer, NULL); - if (tp == NULL) { - return OS_ERR_NO_FREE_IDS; - } + thread_descriptor_t td = { + task_name, + (stkalign_t *)stack_pointer, + (stkalign_t *)((uint8_t *)stack_pointer + stack_size), + rt_prio, + (tfunc_t)function_pointer, + NULL + }; + + /* Creating the task.*/ + tp = chThdCreate(&td); /* Storing the task id.*/ *task_id = (uint32)tp; @@ -1376,9 +1390,6 @@ int32 OS_TaskDelete(uint32 task_id) { ((funcptr_t)(tp->osal_delete_handler))(); } - /* Releasing the thread reference.*/ - chThdRelease(tp); - return OS_SUCCESS; } @@ -1479,9 +1490,6 @@ int32 OS_TaskSetPriority(uint32 task_id, uint32 new_priority) { chSchRescheduleS(); chSysUnlock(); - /* Releasing the thread reference.*/ - chThdRelease(tp); - return OS_SUCCESS; } @@ -1541,9 +1549,6 @@ int32 OS_TaskGetIdByName(uint32 *task_id, const char *task_name) { *task_id = (uint32)tp; - /* Releasing the thread reference.*/ - chThdRelease(tp); - return OS_SUCCESS; } @@ -1580,9 +1585,6 @@ int32 OS_TaskGetInfo(uint32 task_id, OS_task_prop_t *task_prop) { task_prop->priority = (uint32)256U - (uint32)tp->realprio; task_prop->OStask_id = task_id; - /* Releasing the thread reference.*/ - chThdRelease(tp); - return OS_SUCCESS; } diff --git a/os/rt/include/chregistry.h b/os/rt/include/chregistry.h index a786e93a0..f60b1b2c3 100644 --- a/os/rt/include/chregistry.h +++ b/os/rt/include/chregistry.h @@ -110,6 +110,7 @@ extern "C" { thread_t *chRegNextThread(thread_t *tp); thread_t *chRegFindThreadByName(const char *name); thread_t *chRegFindThreadByPointer(thread_t *tp); + thread_t *chRegFindThreadByWorkingArea(stkalign_t *wa); #ifdef __cplusplus } #endif diff --git a/os/rt/src/chregistry.c b/os/rt/src/chregistry.c index ec90b4168..24246c012 100644 --- a/os/rt/src/chregistry.c +++ b/os/rt/src/chregistry.c @@ -233,6 +233,33 @@ thread_t *chRegFindThreadByPointer(thread_t *tp) { return NULL; } +/** + * @brief Confirms that a working area is being used by some active thread. + * @note The reference counter of the found thread is increased by one so + * it cannot be disposed incidentally after the pointer has been + * returned. + * + * @param[in] wa pointer to a static working area + * @return A pointer to the found thread. + * @retval NULL if a matching thread has not been found. + * + * @api + */ +thread_t *chRegFindThreadByWorkingArea(stkalign_t *wa) { + thread_t *ctp; + + /* Scanning registry.*/ + ctp = chRegFirstThread(); + do { + if (ctp->stklimit == wa) { + return ctp; + } + ctp = chRegNextThread(ctp); + } while (ctp != NULL); + + return NULL; +} + #endif /* CH_CFG_USE_REGISTRY == TRUE */ /** @} */