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