1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef _GNU_SOURCE
16 #define _GNU_SOURCE
17 #endif
18
19 #include "softbus_adapter_thread.h"
20
21 #include <pthread.h>
22 #include <securec.h>
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "softbus_adapter_log.h"
27 #include "softbus_adapter_mem.h"
28 #include "softbus_def.h"
29 #include "softbus_errcode.h"
30
31 /* mutex */
SoftBusMutexAttrInit(SoftBusMutexAttr * mutexAttr)32 int32_t SoftBusMutexAttrInit(SoftBusMutexAttr *mutexAttr)
33 {
34 if (mutexAttr == NULL) {
35 HILOG_ERROR(SOFTBUS_HILOG_ID, "mutexAttr is null");
36 return SOFTBUS_INVALID_PARAM;
37 }
38
39 mutexAttr->type = SOFTBUS_MUTEX_NORMAL;
40 return SOFTBUS_OK;
41 }
42
SoftBusMutexInit(SoftBusMutex * mutex,SoftBusMutexAttr * mutexAttr)43 int32_t SoftBusMutexInit(SoftBusMutex *mutex, SoftBusMutexAttr *mutexAttr)
44 {
45 if (mutex == NULL) {
46 HILOG_ERROR(SOFTBUS_HILOG_ID, "mutex is null");
47 return SOFTBUS_INVALID_PARAM;
48 }
49
50 pthread_mutex_t *tempMutex;
51 tempMutex = (pthread_mutex_t *)SoftBusCalloc(sizeof(pthread_mutex_t));
52 if (tempMutex == NULL) {
53 HILOG_ERROR(SOFTBUS_HILOG_ID, "tempMutex is null");
54 return SOFTBUS_INVALID_PARAM;
55 }
56
57 int ret;
58 pthread_mutexattr_t attr;
59 pthread_mutexattr_init(&attr);
60 if (mutexAttr == NULL) {
61 #ifndef __LITEOS_M__
62 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
63 #else
64 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
65 #endif
66 } else if (mutexAttr->type == SOFTBUS_MUTEX_NORMAL) {
67 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
68 } else if (mutexAttr->type == SOFTBUS_MUTEX_RECURSIVE) {
69 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
70 }
71
72 ret = pthread_mutex_init(tempMutex, &attr);
73 if (ret != 0) {
74 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftBusMutexInit failed, ret[%{public}d]", ret);
75 SoftBusFree(tempMutex);
76 tempMutex = NULL;
77 return SOFTBUS_ERR;
78 }
79
80 *mutex = (SoftBusMutex)tempMutex;
81 return SOFTBUS_OK;
82 }
83
SoftBusMutexLock(SoftBusMutex * mutex)84 int32_t SoftBusMutexLock(SoftBusMutex *mutex)
85 {
86 if ((mutex == NULL) || ((void *)(*mutex) == NULL)) {
87 HILOG_ERROR(SOFTBUS_HILOG_ID, "mutex is null");
88 return SOFTBUS_INVALID_PARAM;
89 }
90
91 int ret;
92 ret = pthread_mutex_lock((pthread_mutex_t *)*mutex);
93 if (ret != 0) {
94 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftBusMutexLock failed, ret[%{public}d]", ret);
95 return SOFTBUS_ERR;
96 }
97 return SOFTBUS_OK;
98 }
99
SoftBusMutexUnlock(SoftBusMutex * mutex)100 int32_t SoftBusMutexUnlock(SoftBusMutex *mutex)
101 {
102 if ((mutex == NULL) || ((void *)(*mutex) == NULL)) {
103 HILOG_ERROR(SOFTBUS_HILOG_ID, "mutex is null");
104 return SOFTBUS_INVALID_PARAM;
105 }
106
107 int ret;
108 ret = pthread_mutex_unlock((pthread_mutex_t *)*mutex);
109 if (ret != 0) {
110 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftBusMutexUnlock failed, ret[%{public}d]", ret);
111 return SOFTBUS_ERR;
112 }
113
114 return SOFTBUS_OK;
115 }
116
SoftBusMutexDestroy(SoftBusMutex * mutex)117 int32_t SoftBusMutexDestroy(SoftBusMutex *mutex)
118 {
119 if ((mutex == NULL) || ((void *)(*mutex) == NULL)) {
120 HILOG_ERROR(SOFTBUS_HILOG_ID, "mutex is null");
121 return SOFTBUS_INVALID_PARAM;
122 }
123
124 int ret;
125 ret = pthread_mutex_destroy((pthread_mutex_t *)*mutex);
126 if (ret != 0) {
127 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftBusMutexDestroy failed, ret[%{public}d]", ret);
128 SoftBusFree((void *)*mutex);
129 *mutex = (SoftBusMutex)NULL;
130 return SOFTBUS_ERR;
131 }
132
133 SoftBusFree((void *)*mutex);
134 *mutex = (SoftBusMutex)NULL;
135 return SOFTBUS_OK;
136 }
137
138 /* pthread */
SoftBusThreadAttrInit(SoftBusThreadAttr * threadAttr)139 int32_t SoftBusThreadAttrInit(SoftBusThreadAttr *threadAttr)
140 {
141 if (threadAttr == NULL) {
142 HILOG_ERROR(SOFTBUS_HILOG_ID, "threadAttr is null");
143 return SOFTBUS_INVALID_PARAM;
144 }
145
146 #ifndef __LITEOS_M__
147 threadAttr->policy = SOFTBUS_SCHED_OTHER;
148 #else
149 threadAttr->policy = SOFTBUS_SCHED_RR;
150 #endif
151 threadAttr->detachState = SOFTBUS_THREAD_JOINABLE;
152 threadAttr->stackSize = 0;
153 threadAttr->prior = SOFTBUS_PRIORITY_DEFAULT;
154
155 threadAttr->taskName = NULL;
156
157 return SOFTBUS_OK;
158 }
159
SoftbusSetThreadPolicy(SoftBusThreadAttr * threadAttr,pthread_attr_t * attr)160 static int32_t SoftbusSetThreadPolicy(SoftBusThreadAttr *threadAttr, pthread_attr_t *attr)
161 {
162 if (threadAttr->policy == SOFTBUS_SCHED_OTHER) {
163 pthread_attr_setschedpolicy(attr, SCHED_OTHER);
164 } else if (threadAttr->policy == SOFTBUS_SCHED_RR) {
165 pthread_attr_setschedpolicy(attr, SCHED_RR);
166 } else {
167 HILOG_ERROR(SOFTBUS_HILOG_ID, "set policy error");
168 return SOFTBUS_INVALID_PARAM;
169 }
170
171 return SOFTBUS_OK;
172 }
173
SoftbusSetThreadDetachState(SoftBusThreadAttr * threadAttr,pthread_attr_t * attr)174 static int32_t SoftbusSetThreadDetachState(SoftBusThreadAttr *threadAttr, pthread_attr_t *attr)
175 {
176 if (threadAttr->detachState == SOFTBUS_THREAD_JOINABLE) {
177 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_JOINABLE);
178 } else if (threadAttr->detachState == SOFTBUS_THREAD_DETACH) {
179 pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
180 } else {
181 HILOG_ERROR(SOFTBUS_HILOG_ID, "set detachState error");
182 return SOFTBUS_INVALID_PARAM;
183 }
184
185 return SOFTBUS_OK;
186 }
187
SoftbusSetThreadPeriority(SoftBusThreadAttr * threadAttr,pthread_attr_t * attr)188 static int32_t SoftbusSetThreadPeriority(SoftBusThreadAttr *threadAttr, pthread_attr_t *attr)
189 {
190 #ifdef __linux__
191 /* periorityParam is between 1 and 99 in linux */
192 #define PTHREAD_PERIOR_LOWEST 1
193 #define PTHREAD_PERIOR_LOW 33
194 #define PTHREAD_PERIOR_HIGH 66
195 #define PTHREAD_PERIOR_HIGHEST 99
196 #else
197 /* periorityParam is between 0 and 31 in liteOS */
198 #define PTHREAD_PERIOR_LOWEST 30
199 #define PTHREAD_PERIOR_LOW 20
200 #define PTHREAD_PERIOR_HIGH 10
201 #define PTHREAD_PERIOR_HIGHEST 0
202 #endif
203
204 struct sched_param periorityParam;
205 (void)memset_s(&periorityParam, sizeof(pthread_attr_setschedparam), 0, sizeof(pthread_attr_setschedparam));
206 struct sched_param defaultPeri;
207 pthread_attr_getschedparam(attr, &defaultPeri);
208 switch (threadAttr->prior) {
209 case SOFTBUS_PRIORITY_DEFAULT:
210 periorityParam.sched_priority = defaultPeri.sched_priority;
211 break;
212 case SOFTBUS_PRIORITY_LOWEST:
213 periorityParam.sched_priority = PTHREAD_PERIOR_LOWEST;
214 break;
215 case SOFTBUS_PRIORITY_LOW:
216 periorityParam.sched_priority = PTHREAD_PERIOR_LOW;
217 break;
218 case SOFTBUS_PRIORITY_HIGH:
219 periorityParam.sched_priority = PTHREAD_PERIOR_HIGH;
220 break;
221 case SOFTBUS_PRIORITY_HIGHEST:
222 periorityParam.sched_priority = PTHREAD_PERIOR_HIGHEST;
223 break;
224 default:
225 periorityParam.sched_priority = defaultPeri.sched_priority;
226 break;
227 }
228 pthread_attr_setschedparam(attr, &periorityParam);
229
230 return SOFTBUS_OK;
231 }
232
SoftBusConfTransPthreadAttr(SoftBusThreadAttr * threadAttr,pthread_attr_t * attr)233 static int32_t SoftBusConfTransPthreadAttr(SoftBusThreadAttr *threadAttr, pthread_attr_t *attr)
234 {
235 int ret;
236 if ((threadAttr == NULL) || (attr == NULL)) {
237 HILOG_ERROR(SOFTBUS_HILOG_ID, "threadAttr or attr is null");
238 return SOFTBUS_INVALID_PARAM;
239 }
240
241 ret = SoftbusSetThreadPolicy(threadAttr, attr);
242 if (ret != SOFTBUS_OK) {
243 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftbusSetThreadPolicy failed, ret[%{public}d]", ret);
244 return SOFTBUS_ERR;
245 }
246
247 ret = SoftbusSetThreadDetachState(threadAttr, attr);
248 if (ret != SOFTBUS_OK) {
249 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftbusSetThreadDetachState failed, ret[%{public}d]", ret);
250 return SOFTBUS_ERR;
251 }
252
253 ret = SoftbusSetThreadPeriority(threadAttr, attr);
254 if (ret != SOFTBUS_OK) {
255 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftbusSetThreadPeriority failed, ret[%{public}d]", ret);
256 return SOFTBUS_ERR;
257 }
258
259 uint64_t stackSize = threadAttr->stackSize;
260 if (stackSize != 0) {
261 ret = pthread_attr_setstacksize(attr, stackSize);
262 if (ret != 0) {
263 HILOG_ERROR(SOFTBUS_HILOG_ID, "pthread_attr_setstacksize failed, ret[%{public}d]", ret);
264 return SOFTBUS_ERR;
265 }
266 }
267
268 return SOFTBUS_OK;
269 }
270
SoftBusThreadCreate(SoftBusThread * thread,SoftBusThreadAttr * threadAttr,void * (* threadEntry)(void *),void * arg)271 int32_t SoftBusThreadCreate(SoftBusThread *thread, SoftBusThreadAttr *threadAttr, void *(*threadEntry) (void *),
272 void *arg)
273 {
274 if (thread == NULL) {
275 HILOG_ERROR(SOFTBUS_HILOG_ID, "thread is null");
276 return SOFTBUS_INVALID_PARAM;
277 }
278
279 int32_t ret;
280 if (threadAttr == NULL) {
281 ret = pthread_create((pthread_t *)thread, NULL, threadEntry, arg);
282 if (ret != 0) {
283 HILOG_ERROR(SOFTBUS_HILOG_ID, "Thread create failed, ret[%{public}d]", ret);
284 return SOFTBUS_ERR;
285 }
286 } else {
287 pthread_attr_t attr;
288 ret = pthread_attr_init(&attr);
289 if (ret != 0) {
290 HILOG_ERROR(SOFTBUS_HILOG_ID, "pthread_attr_init failed, ret[%{public}d]", ret);
291 return SOFTBUS_ERR;
292 }
293 ret = SoftBusConfTransPthreadAttr(threadAttr, &attr);
294 if (ret != 0) {
295 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftBusConfTransPthreadAttr failed, ret[%{public}d]", ret);
296 return SOFTBUS_ERR;
297 }
298 ret = pthread_create((pthread_t *)thread, &attr, threadEntry, arg);
299 if (ret != 0) {
300 HILOG_ERROR(SOFTBUS_HILOG_ID, "Thread create failed, ret[%{public}d]", ret);
301 return SOFTBUS_ERR;
302 }
303
304 if (threadAttr->taskName != NULL) {
305 ret = SoftBusThreadSetName(*thread, threadAttr->taskName);
306 if (ret != 0) {
307 HILOG_ERROR(SOFTBUS_HILOG_ID, "Thread set name failed, ret[%{public}d]", ret);
308 return SOFTBUS_ERR;
309 }
310 }
311 }
312
313 return SOFTBUS_OK;
314 }
315
SoftBusThreadJoin(SoftBusThread thread,void ** value)316 int32_t SoftBusThreadJoin(SoftBusThread thread, void **value)
317 {
318 if (thread <= 0) {
319 HILOG_ERROR(SOFTBUS_HILOG_ID, "thread is invalid");
320 return SOFTBUS_INVALID_PARAM;
321 }
322
323 int32_t ret = pthread_join((pthread_t)thread, value);
324 if (ret != 0) {
325 HILOG_ERROR(SOFTBUS_HILOG_ID, "Thread join failed, ret[%{public}d]", ret);
326 return SOFTBUS_ERR;
327 }
328
329 return SOFTBUS_OK;
330 }
331
SoftBusThreadSetName(SoftBusThread thread,const char * name)332 int32_t SoftBusThreadSetName(SoftBusThread thread, const char *name)
333 {
334 if (thread <= 0) {
335 HILOG_ERROR(SOFTBUS_HILOG_ID, "thread is invalid");
336 return SOFTBUS_INVALID_PARAM;
337 }
338
339 if (name == NULL) {
340 HILOG_ERROR(SOFTBUS_HILOG_ID, "name is null");
341 return SOFTBUS_INVALID_PARAM;
342 }
343
344 if (strlen(name) >= TASK_NAME_MAX_LEN) {
345 HILOG_ERROR(SOFTBUS_HILOG_ID, "set thread name length >= TASK_NAME_MAX_LEN");
346 return SOFTBUS_INVALID_PARAM;
347 }
348 int32_t ret = pthread_setname_np((pthread_t)thread, name);
349 if (ret != 0) {
350 HILOG_ERROR(SOFTBUS_HILOG_ID, "Thread set name failed, ret[%{public}d]", ret);
351 return SOFTBUS_ERR;
352 }
353
354 return SOFTBUS_OK;
355 }
356
SoftBusThreadGetSelf(void)357 SoftBusThread SoftBusThreadGetSelf(void)
358 {
359 return (SoftBusThread)pthread_self();
360 }
361
362 /* cond */
SoftBusCondInit(SoftBusCond * cond)363 int32_t SoftBusCondInit(SoftBusCond *cond)
364 {
365 if (cond == NULL) {
366 HILOG_ERROR(SOFTBUS_HILOG_ID, "cond is null");
367 return SOFTBUS_INVALID_PARAM;
368 }
369
370 pthread_cond_t *tempCond = (pthread_cond_t *)SoftBusCalloc(sizeof(pthread_cond_t));
371 if (tempCond == NULL) {
372 HILOG_ERROR(SOFTBUS_HILOG_ID, "tempCond is null");
373 return SOFTBUS_ERR;
374 }
375 int ret;
376 ret = pthread_cond_init(tempCond, NULL);
377 if (ret != 0) {
378 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftBusCondInit failed, ret[%{public}d]", ret);
379 SoftBusFree(tempCond);
380 tempCond = NULL;
381 return SOFTBUS_ERR;
382 }
383
384 *cond = (SoftBusCond)tempCond;
385 return SOFTBUS_OK;
386 }
387
SoftBusCondSignal(SoftBusCond * cond)388 int32_t SoftBusCondSignal(SoftBusCond *cond)
389 {
390 if ((cond == NULL) || ((void *)(*cond) == NULL)) {
391 HILOG_ERROR(SOFTBUS_HILOG_ID, "cond is null");
392 return SOFTBUS_INVALID_PARAM;
393 }
394
395 int ret;
396 ret = pthread_cond_signal((pthread_cond_t *)*cond);
397 if (ret != 0) {
398 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftBusCondSignal failed, ret[%{public}d]", ret);
399 return SOFTBUS_ERR;
400 }
401
402 return SOFTBUS_OK;
403 }
404
SoftBusCondBroadcast(SoftBusCond * cond)405 int32_t SoftBusCondBroadcast(SoftBusCond *cond)
406 {
407 if ((cond == NULL) || ((void *)(*cond) == NULL)) {
408 HILOG_ERROR(SOFTBUS_HILOG_ID, "cond is null");
409 return SOFTBUS_INVALID_PARAM;
410 }
411
412 int ret;
413 ret = pthread_cond_broadcast((pthread_cond_t *)*cond);
414 if (ret != 0) {
415 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftBusCondBroadcast failed, ret[%{public}d]", ret);
416 return SOFTBUS_ERR;
417 }
418
419 return SOFTBUS_OK;
420 }
421
SoftBusCondWait(SoftBusCond * cond,SoftBusMutex * mutex,SoftBusSysTime * time)422 int32_t SoftBusCondWait(SoftBusCond *cond, SoftBusMutex *mutex, SoftBusSysTime *time)
423 {
424 if ((cond == NULL) || ((void *)(*cond) == NULL)) {
425 HILOG_ERROR(SOFTBUS_HILOG_ID, "cond is null");
426 return SOFTBUS_INVALID_PARAM;
427 }
428
429 if ((mutex == NULL) || ((void *)(*mutex) == NULL)) {
430 HILOG_ERROR(SOFTBUS_HILOG_ID, "mutex is null");
431 return SOFTBUS_INVALID_PARAM;
432 }
433
434 int ret;
435 if (time == NULL) {
436 ret = pthread_cond_wait((pthread_cond_t *)*cond, (pthread_mutex_t *)*mutex);
437 if (ret != 0) {
438 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftBusCondWait failed, ret[%{public}d]", ret);
439 return SOFTBUS_ERR;
440 }
441 } else {
442 struct timespec tv;
443 tv.tv_sec = time->sec;
444 tv.tv_nsec = time->usec;
445 ret = pthread_cond_timedwait((pthread_cond_t *)*cond, (pthread_mutex_t *)*mutex, &tv);
446 if (ret != 0 && ret != ETIMEDOUT) {
447 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftBusCondTimedWait failed, ret[%{public}d]", ret);
448 return SOFTBUS_ERR;
449 }
450 }
451
452 return SOFTBUS_OK;
453 }
454
SoftBusCondDestroy(SoftBusCond * cond)455 int32_t SoftBusCondDestroy(SoftBusCond *cond)
456 {
457 if ((cond == NULL) || ((void *)(*cond) == NULL)) {
458 HILOG_ERROR(SOFTBUS_HILOG_ID, "cond is null");
459 return SOFTBUS_INVALID_PARAM;
460 }
461
462 int ret;
463 ret = pthread_cond_destroy((pthread_cond_t *)*cond);
464 if (ret != 0) {
465 HILOG_ERROR(SOFTBUS_HILOG_ID, "SoftBusCondDestroy failed, ret[%{public}d]", ret);
466 SoftBusFree((void *)*cond);
467 *cond = (SoftBusCond)NULL;
468 return SOFTBUS_ERR;
469 }
470
471 SoftBusFree((void *)*cond);
472 *cond = (SoftBusCond)NULL;
473 return SOFTBUS_OK;
474 }
475