• 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 <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