• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "osal_thread.h"
10 #include <pthread.h>
11 #include "hdf_base.h"
12 #include "hdf_log.h"
13 #include "osal_mem.h"
14 #ifndef PTHREAD_STACK_MIN
15 #define OSAL_PTHREAD_STACK_MIN 4096
16 #else
17 #define OSAL_PTHREAD_STACK_MIN PTHREAD_STACK_MIN
18 #endif
19 
20 #define HDF_LOG_TAG osal_thread
21 
22 typedef void *(*PosixEntry)(void *data);
23 
24 struct ThreadWrapper {
25     OsalThreadEntry threadEntry;
26     void *entryPara;
27     pthread_t id;
28 };
29 #ifdef _LINUX_USER_
30 enum {
31     OSAL_PRIORITY_LOW      = 10,
32     OSAL_PRIORITY_MIDDLE   = 50,
33     OSAL_PRIORITY_HIGH     = 90,
34     OSAL_PRIORITY_HIGHEST  = 99,
35 };
36 #else
37 enum {
38     OSAL_PRIORITY_HIGHEST  = 5,
39     OSAL_PRIORITY_HIGH     = 15,
40     OSAL_PRIORITY_MIDDLE   = 25,
41     OSAL_PRIORITY_LOW      = 30,
42 };
43 #endif
44 
OsalThreadRemapSched(int priority,struct sched_param * param)45 static void OsalThreadRemapSched(int priority, struct sched_param *param)
46 {
47     if (priority == OSAL_THREAD_PRI_HIGHEST) {
48         param->sched_priority = OSAL_PRIORITY_HIGHEST;
49     } else if (priority == OSAL_THREAD_PRI_HIGH) {
50         param->sched_priority = OSAL_PRIORITY_HIGH;
51     } else if (priority == OSAL_THREAD_PRI_DEFAULT) {
52         param->sched_priority = OSAL_PRIORITY_MIDDLE;
53     } else {
54         param->sched_priority = OSAL_PRIORITY_LOW;
55     }
56 }
57 
OsalThreadCreate(struct OsalThread * thread,OsalThreadEntry threadEntry,void * entryPara)58 int32_t OsalThreadCreate(struct OsalThread *thread, OsalThreadEntry threadEntry, void *entryPara)
59 {
60     struct ThreadWrapper *para = NULL;
61 
62     if (thread == NULL || threadEntry == NULL) {
63         HDF_LOGE("%s invalid param", __func__);
64         return HDF_ERR_INVALID_PARAM;
65     }
66 
67     thread->realThread = NULL;
68     para = (struct ThreadWrapper *)OsalMemCalloc(sizeof(*para));
69     if (para == NULL) {
70         HDF_LOGE("%s malloc fail", __func__);
71         return HDF_FAILURE;
72     }
73 
74     para->entryPara = entryPara;
75     para->threadEntry = threadEntry;
76     thread->realThread = para;
77 
78     return HDF_SUCCESS;
79 }
80 
OsalThreadDestroy(struct OsalThread * thread)81 int32_t OsalThreadDestroy(struct OsalThread *thread)
82 {
83     if (thread != NULL && thread->realThread != NULL) {
84         OsalMemFree(thread->realThread);
85         thread->realThread = NULL;
86     }
87     return HDF_SUCCESS;
88 }
89 
OsalCreatePthread(pthread_t * threadId,pthread_attr_t * attribute,struct ThreadWrapper * para)90 static int OsalCreatePthread(pthread_t *threadId, pthread_attr_t *attribute, struct ThreadWrapper *para)
91 {
92     int resultCode = pthread_create(threadId, attribute, (PosixEntry)para->threadEntry, para->entryPara);
93     if (resultCode != 0) {
94         HDF_LOGE("pthread_create errorno: %d", resultCode);
95         return resultCode;
96     }
97     resultCode = pthread_detach(*threadId);
98     if (resultCode != 0) {
99         HDF_LOGE("pthread_detach errorno: %d", resultCode);
100         return resultCode;
101     }
102     resultCode = pthread_attr_destroy(attribute);
103     if (resultCode != 0) {
104         HDF_LOGE("pthread_attr_destroy errorno: %d", resultCode);
105         return resultCode;
106     }
107     return HDF_SUCCESS;
108 }
109 
OsalThreadStart(struct OsalThread * thread,const struct OsalThreadParam * param)110 int32_t OsalThreadStart(struct OsalThread *thread, const struct OsalThreadParam *param)
111 {
112     pthread_attr_t attribute;
113     struct sched_param priorityHolder;
114 
115     if (thread == NULL || thread->realThread == NULL || param == NULL) {
116         HDF_LOGE("%s invalid param", __func__);
117         return HDF_ERR_INVALID_PARAM;
118     }
119 
120     struct ThreadWrapper *para = (struct ThreadWrapper *)thread->realThread;
121 
122     int resultCode = pthread_attr_init(&attribute);
123     if (resultCode != 0) {
124         HDF_LOGE("pthread_attr_init errorno: %d", resultCode);
125         goto DEAL_FAIL;
126     }
127 
128     size_t stackSize = param->stackSize;
129     if (stackSize > 0) {
130         stackSize = (stackSize < OSAL_PTHREAD_STACK_MIN) ? OSAL_PTHREAD_STACK_MIN : stackSize;
131         resultCode = pthread_attr_setstacksize(&attribute, stackSize);
132         if (resultCode != 0) {
133             HDF_LOGE("pthread_attr_setstacksize errorno: %d", resultCode);
134             goto DEAL_FAIL;
135         }
136     }
137 
138     resultCode = pthread_attr_getschedparam(&attribute, &priorityHolder);
139     if (resultCode != 0) {
140         HDF_LOGE("pthread_attr_getschedparam errorno: %d", resultCode);
141         goto DEAL_FAIL;
142     }
143 
144     OsalThreadRemapSched(param->priority, &priorityHolder);
145 
146     resultCode = pthread_attr_setschedparam(&attribute, &priorityHolder);
147     if (resultCode != 0) {
148         HDF_LOGE("pthread_attr_setschedparam errorno: %d", resultCode);
149         goto DEAL_FAIL;
150     }
151 
152     resultCode = OsalCreatePthread(&para->id, &attribute, thread->realThread);
153     if (resultCode != 0) {
154         HDF_LOGE("OsalCreatePthread errorno: %d", resultCode);
155         goto DEAL_FAIL;
156     }
157     return HDF_SUCCESS;
158 
159 DEAL_FAIL:
160     (void)OsalThreadDestroy(thread);
161     return HDF_FAILURE;
162 }
163 
164