/* * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * * HDF is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * See the LICENSE file in the root of this repository for complete details. */ #include "osal_thread.h" #include #include "hdf_base.h" #include "hdf_log.h" #include "osal_mem.h" #ifndef PTHREAD_STACK_MIN #define OSAL_PTHREAD_STACK_MIN 4096 #else #define OSAL_PTHREAD_STACK_MIN PTHREAD_STACK_MIN #endif #define HDF_LOG_TAG osal_thread typedef void *(*PosixEntry)(void *data); struct ThreadWrapper { OsalThreadEntry threadEntry; void *entryPara; pthread_t id; }; #ifdef _LINUX_USER_ enum { OSAL_PRIORITY_LOW = 10, OSAL_PRIORITY_MIDDLE = 50, OSAL_PRIORITY_HIGH = 90, OSAL_PRIORITY_HIGHEST = 99, }; #else enum { OSAL_PRIORITY_HIGHEST = 5, OSAL_PRIORITY_HIGH = 15, OSAL_PRIORITY_MIDDLE = 25, OSAL_PRIORITY_LOW = 30, }; #endif static void OsalThreadRemapSched(int priority, struct sched_param *param) { if (priority == OSAL_THREAD_PRI_HIGHEST) { param->sched_priority = OSAL_PRIORITY_HIGHEST; } else if (priority == OSAL_THREAD_PRI_HIGH) { param->sched_priority = OSAL_PRIORITY_HIGH; } else if (priority == OSAL_THREAD_PRI_DEFAULT) { param->sched_priority = OSAL_PRIORITY_MIDDLE; } else { param->sched_priority = OSAL_PRIORITY_LOW; } } int32_t OsalThreadCreate(struct OsalThread *thread, OsalThreadEntry threadEntry, void *entryPara) { struct ThreadWrapper *para = NULL; if (thread == NULL || threadEntry == NULL) { HDF_LOGE("%s invalid param", __func__); return HDF_ERR_INVALID_PARAM; } thread->realThread = NULL; para = (struct ThreadWrapper *)OsalMemCalloc(sizeof(*para)); if (para == NULL) { HDF_LOGE("%s malloc fail", __func__); return HDF_FAILURE; } para->entryPara = entryPara; para->threadEntry = threadEntry; thread->realThread = para; return HDF_SUCCESS; } int32_t OsalThreadDestroy(struct OsalThread *thread) { if (thread != NULL && thread->realThread != NULL) { OsalMemFree(thread->realThread); thread->realThread = NULL; } return HDF_SUCCESS; } static int OsalCreatePthread(pthread_t *threadId, pthread_attr_t *attribute, struct ThreadWrapper *para) { int resultCode = pthread_create(threadId, attribute, (PosixEntry)para->threadEntry, para->entryPara); if (resultCode != 0) { HDF_LOGE("pthread_create errorno: %d", resultCode); return resultCode; } resultCode = pthread_detach(*threadId); if (resultCode != 0) { HDF_LOGE("pthread_detach errorno: %d", resultCode); return resultCode; } resultCode = pthread_attr_destroy(attribute); if (resultCode != 0) { HDF_LOGE("pthread_attr_destroy errorno: %d", resultCode); return resultCode; } return HDF_SUCCESS; } int32_t OsalThreadStart(struct OsalThread *thread, const struct OsalThreadParam *param) { pthread_attr_t attribute; struct sched_param priorityHolder; if (thread == NULL || thread->realThread == NULL || param == NULL) { HDF_LOGE("%s invalid param", __func__); return HDF_ERR_INVALID_PARAM; } struct ThreadWrapper *para = (struct ThreadWrapper *)thread->realThread; int resultCode = pthread_attr_init(&attribute); if (resultCode != 0) { HDF_LOGE("pthread_attr_init errorno: %d", resultCode); goto DEAL_FAIL; } size_t stackSize = param->stackSize; if (stackSize > 0) { stackSize = (stackSize < OSAL_PTHREAD_STACK_MIN) ? OSAL_PTHREAD_STACK_MIN : stackSize; resultCode = pthread_attr_setstacksize(&attribute, stackSize); if (resultCode != 0) { HDF_LOGE("pthread_attr_setstacksize errorno: %d", resultCode); goto DEAL_FAIL; } } resultCode = pthread_attr_getschedparam(&attribute, &priorityHolder); if (resultCode != 0) { HDF_LOGE("pthread_attr_getschedparam errorno: %d", resultCode); goto DEAL_FAIL; } OsalThreadRemapSched(param->priority, &priorityHolder); resultCode = pthread_attr_setschedparam(&attribute, &priorityHolder); if (resultCode != 0) { HDF_LOGE("pthread_attr_setschedparam errorno: %d", resultCode); goto DEAL_FAIL; } resultCode = OsalCreatePthread(¶->id, &attribute, thread->realThread); if (resultCode != 0) { HDF_LOGE("OsalCreatePthread errorno: %d", resultCode); goto DEAL_FAIL; } return HDF_SUCCESS; DEAL_FAIL: (void)OsalThreadDestroy(thread); return HDF_FAILURE; }