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