1 /*
2 * Copyright (c) 2020 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 #include "thread_adapter.h"
16 #include <pthread.h>
17 #include <unistd.h>
18 #include "common.h"
19 #include "memory_adapter.h"
20 #define PRI_BUTT 39
21 #define MIN_STACK_SIZE 0x8000
22 static int g_threadCount = 0;
23 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
24 static pthread_key_t g_localKey = -1;
25 static pthread_once_t g_localKeyOnce = PTHREAD_ONCE_INIT;
26
MUTEX_InitValue()27 MutexId MUTEX_InitValue()
28 {
29 pthread_mutex_t *mutex = SAMGR_Malloc(sizeof(pthread_mutex_t));
30 if (mutex == NULL) {
31 return NULL;
32 }
33 (void)pthread_mutex_init(mutex, NULL);
34 return (MutexId)mutex;
35 }
36
MUTEX_Lock(MutexId mutex)37 void MUTEX_Lock(MutexId mutex)
38 {
39 if (mutex == NULL) {
40 return;
41 }
42 pthread_mutex_lock((pthread_mutex_t *)mutex);
43 }
44
MUTEX_Unlock(MutexId mutex)45 void MUTEX_Unlock(MutexId mutex)
46 {
47 if (mutex == NULL) {
48 return;
49 }
50 pthread_mutex_unlock((pthread_mutex_t *)mutex);
51 }
52
MUTEX_GlobalLock(void)53 void MUTEX_GlobalLock(void)
54 {
55 pthread_mutex_lock(&g_mutex);
56 }
57
MUTEX_GlobalUnlock(void)58 void MUTEX_GlobalUnlock(void)
59 {
60 pthread_mutex_unlock(&g_mutex);
61 }
62
KeyCreate()63 static void KeyCreate()
64 {
65 (void) pthread_key_create(&g_localKey, NULL);
66 }
67
THREAD_Create(Runnable run,void * argv,const ThreadAttr * attr)68 ThreadId THREAD_Create(Runnable run, void *argv, const ThreadAttr *attr)
69 {
70 pthread_attr_t threadAttr;
71 pthread_attr_init(&threadAttr);
72 pthread_attr_setstacksize(&threadAttr, (attr->stackSize | MIN_STACK_SIZE));
73 #ifdef SAMGR_LINUX_ADAPTER
74 struct sched_param sched = {attr->priority};
75 #else
76 struct sched_param sched = {PRI_BUTT - attr->priority};
77 #endif
78 pthread_attr_setinheritsched(&threadAttr, PTHREAD_EXPLICIT_SCHED);
79 pthread_attr_setschedpolicy(&threadAttr, SCHED_RR);
80 pthread_attr_setschedparam(&threadAttr, &sched);
81 (void) pthread_once(&g_localKeyOnce, KeyCreate);
82 pthread_t threadId = 0;
83 int errno = pthread_create(&threadId, &threadAttr, run, argv);
84 if (errno != 0) {
85 return NULL;
86 }
87
88 MUTEX_GlobalLock();
89 g_threadCount++;
90 MUTEX_GlobalUnlock();
91 return (ThreadId)threadId;
92 }
93
THREAD_Total(void)94 int THREAD_Total(void)
95 {
96 return g_threadCount;
97 }
98
THREAD_GetThreadLocal(void)99 void *THREAD_GetThreadLocal(void)
100 {
101 return pthread_getspecific(g_localKey);
102 }
103
THREAD_SetThreadLocal(const void * local)104 void THREAD_SetThreadLocal(const void *local)
105 {
106 pthread_setspecific(g_localKey, local);
107 }
108