diff --git a/kal/posix/src/pthread.c b/kal/posix/src/pthread.c index cd5d870283e617690c6823c20c54057f478cb743..2389d1262523cd2465cdd9910525ae4cfb5e4c81 100644 --- a/kal/posix/src/pthread.c +++ b/kal/posix/src/pthread.c @@ -232,3 +232,20 @@ int pthread_getname_np(pthread_t thread, char *buf, size_t buflen) } return ERANGE; } + + +int pthread_setspecific(pthread_key_t k, const void *x) +{ + unsigned int ret = LOS_SetSpecific(k, x); + if (ret != LOS_OK) { + return EINVAL; + } + + return 0; +} + +void *pthread_getspecific(pthread_key_t k) +{ + return LOS_GetSpecific(k); +} + diff --git a/kernel/include/los_config.h b/kernel/include/los_config.h index b58fc0669110612f8cb1c69af51d0d87b6d28e55..5ef006cf345337a5a4c8d24ec061409dbf7e2ca4 100644 --- a/kernel/include/los_config.h +++ b/kernel/include/los_config.h @@ -233,6 +233,14 @@ extern "C" { #define LOSCFG_BASE_CORE_EXC_TSK_SWITCH 0 #endif +/** + * @ingroup los_config + * Configuration item for task context switch hook + */ +#ifndef LOSCFG_BASE_CORE_TSK_SWITCH_HOOK +#define LOSCFG_BASE_CORE_TSK_SWITCH_HOOK() +#endif + /** * @ingroup los_config * Define a usable task priority.Highest task priority. diff --git a/kernel/include/los_task.h b/kernel/include/los_task.h index 15cb28c666dc7e3a52c2b98cab1d1ae9deafb9f3..a23a89dac7b2c73b72596336dfa8ded505ab80e4 100644 --- a/kernel/include/los_task.h +++ b/kernel/include/los_task.h @@ -401,6 +401,7 @@ typedef VOID *(*TSK_ENTRY_FUNC)(UINT32 arg); typedef struct tagTskInitParam { TSK_ENTRY_FUNC pfnTaskEntry; /**< Task entrance function */ UINT16 usTaskPrio; /**< Task priority */ + UINT32 keyNum; /**< Number of task private data */ UINT32 uwArg; /**< Task parameters */ UINT32 uwStackSize; /**< Task stack size */ CHAR *pcName; /**< Task name */ @@ -1102,6 +1103,10 @@ extern CHAR* LOS_TaskNameGet(UINT32 taskID); */ extern VOID LOS_UDelay(UINT64 microseconds); +extern UINT32 LOS_SetSpecific(UINT32 key, const VOID *value); + +extern VOID *LOS_GetSpecific(UINT32 key); + /** * @ingroup los_task * Null task ID @@ -1350,6 +1355,7 @@ typedef struct { UINT32 waitTimes; SortLinkList sortList; UINT64 startTime; + UINT32 keyNum; UINT32 stackSize; /**< Task stack size */ UINT32 topOfStack; /**< Task stack top */ UINT32 taskID; /**< Task ID */ diff --git a/kernel/src/los_task.c b/kernel/src/los_task.c index 18ddf34db8043ea81b576a0518e4e0edfeaa711d..068350df0ddec6801e7d6f579dfba54bf9012968 100644 --- a/kernel/src/los_task.c +++ b/kernel/src/los_task.c @@ -581,6 +581,8 @@ LITE_OS_SEC_TEXT VOID OsTaskSwitchCheck(VOID) g_pfnUsrTskSwitchHook(); } + LOSCFG_BASE_CORE_TSK_SWITCH_HOOK(); + #if (LOSCFG_KERNEL_TRACE == 1) LOS_Trace(LOS_TRACE_SWITCH, 0); #endif @@ -663,10 +665,13 @@ LITE_OS_SEC_TEXT_INIT STATIC_INLINE UINT32 OsTaskInitParamCheck(TSK_INIT_PARAM_S LITE_OS_SEC_TEXT_INIT UINT32 OsNewTaskInit(LosTaskCB *taskCB, TSK_INIT_PARAM_S *taskInitParam, VOID *topOfStack) { + UINT32 tsdSize; + taskCB->stackPointer = HalTskStackInit(taskCB->taskID, taskInitParam->uwStackSize, topOfStack); taskCB->arg = taskInitParam->uwArg; taskCB->topOfStack = (UINT32)(UINTPTR)topOfStack; taskCB->stackSize = taskInitParam->uwStackSize; + taskCB->keyNum = taskInitParam->keyNum; taskCB->taskSem = NULL; taskCB->taskMux = NULL; taskCB->taskStatus = OS_TASK_STATUS_SUSPEND; @@ -679,6 +684,10 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsNewTaskInit(LosTaskCB *taskCB, TSK_INIT_PARAM_S * taskCB->taskName = taskInitParam->pcName; taskCB->msg = NULL; SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME); + if (taskCB->keyNum) { + tsdSize = taskCB->keyNum * sizeof(UINTPTR); + (VOID)memset_s((VOID *)(taskCB->topOfStack + taskCB->stackSize), tsdSize, 0, tsdSize); + } return LOS_OK; } @@ -694,6 +703,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S UINT32 intSave; VOID *topOfStack = NULL; LosTaskCB *taskCB = NULL; + UINT32 size; UINT32 retVal; if (taskID == NULL) { @@ -718,13 +728,13 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S LOS_IntRestore(intSave); + size = taskInitParam->uwStackSize + taskInitParam->keyNum * sizeof(UINTPTR); #if (LOSCFG_EXC_HARDWARE_STACK_PROTECTION == 1) - UINTPTR stackPtr = (UINTPTR)LOS_MemAllocAlign(OS_TASK_STACK_ADDR, taskInitParam->uwStackSize + - OS_TASK_STACK_PROTECT_SIZE, OS_TASK_STACK_PROTECT_SIZE); + UINTPTR stackPtr = (UINTPTR)LOS_MemAllocAlign(OS_TASK_STACK_ADDR, size + OS_TASK_STACK_PROTECT_SIZE, + OS_TASK_STACK_PROTECT_SIZE); topOfStack = (VOID *)(stackPtr + OS_TASK_STACK_PROTECT_SIZE); #else - topOfStack = (VOID *)LOS_MemAllocAlign(OS_TASK_STACK_ADDR, taskInitParam->uwStackSize, - LOSCFG_STACK_POINT_ALIGN_SIZE); + topOfStack = (VOID *)LOS_MemAllocAlign(OS_TASK_STACK_ADDR, size, LOSCFG_STACK_POINT_ALIGN_SIZE); #endif if (topOfStack == NULL) { intSave = LOS_IntLock(); @@ -1292,6 +1302,41 @@ LITE_OS_SEC_TEXT CHAR* LOS_TaskNameGet(UINT32 taskID) return taskCB->taskName; } +LITE_OS_SEC_TEXT UINT32 LOS_SetSpecific(UINT32 key, const VOID *value) +{ + UINT32 intSave; + UINT32 *tsd = NULL; + LosTaskCB *taskCB = g_losTask.runTask; + + if (key >= taskCB->keyNum) { + return LOS_NOK; + } + + tsd = (UINT32 *)(taskCB->topOfStack + taskCB->stackSize); + intSave = LOS_IntLock(); + tsd[key] = (UINT32)value; + LOS_IntRestore(intSave); + return LOS_OK; +} + +LITE_OS_SEC_TEXT VOID *LOS_GetSpecific(UINT32 key) +{ + UINT32 intSave; + VOID *value = NULL; + UINT32 *tsd = NULL; + LosTaskCB *taskCB = g_losTask.runTask; + + if (key >= taskCB->keyNum) { + return NULL; + } + + tsd = (UINT32 *)(taskCB->topOfStack + taskCB->stackSize); + intSave = LOS_IntLock(); + value = (VOID *)tsd[key]; + LOS_IntRestore(intSave); + return value; +} + LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 mSecs) { UINT32 interval;