• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #include <pthread.h>
17 #include <unistd.h>
18 #include "hitls_build.h"
19 #include "bsl_errno.h"
20 #include "bsl_sal.h"
21 
22 #if defined(HITLS_BSL_SAL_LINUX) && defined(HITLS_BSL_SAL_LOCK)
23 // Used for DEFAULT lock implementation
24 typedef struct {
25     pthread_rwlock_t rwlock;
26 } BslOsalRWLock;
27 
SAL_RwLockNew(BSL_SAL_ThreadLockHandle * lock)28 int32_t SAL_RwLockNew(BSL_SAL_ThreadLockHandle *lock)
29 {
30     if (lock == NULL) {
31         return BSL_SAL_ERR_BAD_PARAM;
32     }
33     BslOsalRWLock *newLock = (BslOsalRWLock *)BSL_SAL_Calloc(1, sizeof(BslOsalRWLock));
34     if (newLock == NULL) {
35         return BSL_MALLOC_FAIL;
36     }
37 
38     if (pthread_rwlock_init(&newLock->rwlock, (const pthread_rwlockattr_t *)NULL) != 0) {
39         BSL_SAL_FREE(newLock);
40         return BSL_SAL_ERR_UNKNOWN;
41     }
42     *lock = newLock;
43     return BSL_SUCCESS;
44 }
45 
SAL_RwReadLock(BSL_SAL_ThreadLockHandle rwLock)46 int32_t SAL_RwReadLock(BSL_SAL_ThreadLockHandle rwLock)
47 {
48     BslOsalRWLock *lock = (BslOsalRWLock *)rwLock;
49     if (lock == NULL) {
50         return BSL_SAL_ERR_BAD_PARAM;
51     }
52     if (pthread_rwlock_rdlock(&lock->rwlock) != 0) {
53         return BSL_SAL_ERR_UNKNOWN;
54     }
55     return BSL_SUCCESS;
56 }
57 
SAL_RwWriteLock(BSL_SAL_ThreadLockHandle rwLock)58 int32_t SAL_RwWriteLock(BSL_SAL_ThreadLockHandle rwLock)
59 {
60     BslOsalRWLock *lock = (BslOsalRWLock *)rwLock;
61     if (lock == NULL) {
62         return BSL_SAL_ERR_BAD_PARAM;
63     }
64     if (pthread_rwlock_wrlock(&lock->rwlock) != 0) {
65         return BSL_SAL_ERR_UNKNOWN;
66     }
67     return BSL_SUCCESS;
68 }
69 
SAL_RwUnlock(BSL_SAL_ThreadLockHandle rwLock)70 int32_t SAL_RwUnlock(BSL_SAL_ThreadLockHandle rwLock)
71 {
72     BslOsalRWLock *lock = (BslOsalRWLock *)rwLock;
73     if (lock == NULL) {
74         return BSL_SAL_ERR_BAD_PARAM;
75     }
76 
77     if (pthread_rwlock_unlock(&lock->rwlock) != 0) {
78         return BSL_SAL_ERR_UNKNOWN;
79     }
80     return BSL_SUCCESS;
81 }
82 
SAL_RwLockFree(BSL_SAL_ThreadLockHandle rwLock)83 void SAL_RwLockFree(BSL_SAL_ThreadLockHandle rwLock)
84 {
85     BslOsalRWLock *lock = (BslOsalRWLock *)rwLock;
86     if (lock != NULL) {
87         (void)pthread_rwlock_destroy(&(lock->rwlock));
88         BSL_SAL_FREE(lock);
89     }
90 }
91 #endif
92 
93 #if defined(HITLS_BSL_SAL_LINUX) && defined(HITLS_BSL_SAL_THREAD)
SAL_GetPid(void)94 uint64_t SAL_GetPid(void)
95 {
96     // By default, gettid is not used to obtain the global tid corresponding to the thread
97     // because other thread functions use the pthread library.
98     // Use pthread_self to obtain the PID used by pthread_create in this process.
99     // However, the pids of the parent and child processes may be the same.
100     return (uint64_t)pthread_self();
101 }
102 
SAL_PthreadRunOnce(uint32_t * onceControl,BSL_SAL_ThreadInitRoutine initFunc)103 int32_t SAL_PthreadRunOnce(uint32_t *onceControl, BSL_SAL_ThreadInitRoutine initFunc)
104 {
105     if (onceControl == NULL || initFunc == NULL) {
106         return BSL_SAL_ERR_BAD_PARAM;
107     }
108 
109     pthread_once_t *tmpOnce = (pthread_once_t *)onceControl;
110     if (pthread_once(tmpOnce, initFunc) != 0) {
111         return BSL_SAL_ERR_UNKNOWN;
112     }
113     return BSL_SUCCESS;
114 }
115 
BSL_SAL_ThreadCreate(BSL_SAL_ThreadId * thread,void * (* startFunc)(void *),void * arg)116 int32_t BSL_SAL_ThreadCreate(BSL_SAL_ThreadId *thread, void *(*startFunc)(void *), void *arg)
117 {
118     if (thread == NULL || startFunc == NULL) {
119         return BSL_SAL_ERR_BAD_PARAM;
120     }
121     int32_t ret = pthread_create((pthread_t *)thread, NULL, startFunc, arg);
122     if (ret != 0) {
123         return BSL_SAL_ERR_UNKNOWN;
124     }
125     return BSL_SUCCESS;
126 }
127 
BSL_SAL_ThreadClose(BSL_SAL_ThreadId thread)128 void BSL_SAL_ThreadClose(BSL_SAL_ThreadId thread)
129 {
130     if (thread == NULL) {
131         return;
132     }
133     (void)pthread_join((pthread_t)(uintptr_t)thread, NULL);
134 }
135 
BSL_SAL_CreateCondVar(BSL_SAL_CondVar * condVar)136 int32_t BSL_SAL_CreateCondVar(BSL_SAL_CondVar *condVar)
137 {
138     if (condVar == NULL) {
139         return BSL_SAL_ERR_BAD_PARAM;
140     }
141     pthread_cond_t *cond = (pthread_cond_t *)BSL_SAL_Malloc(sizeof(pthread_cond_t));
142     if (cond == NULL) {
143         return BSL_MALLOC_FAIL;
144     }
145     if (pthread_cond_init(cond, NULL) != 0) {
146         BSL_SAL_FREE(cond);
147         return BSL_SAL_ERR_UNKNOWN;
148     }
149     *condVar = cond;
150     return BSL_SUCCESS;
151 }
152 
BSL_SAL_CondSignal(BSL_SAL_CondVar condVar)153 int32_t BSL_SAL_CondSignal(BSL_SAL_CondVar condVar)
154 {
155     if (condVar == NULL) {
156         return BSL_SAL_ERR_BAD_PARAM;
157     }
158     if (pthread_cond_signal(condVar) != 0) {
159         return BSL_SAL_ERR_UNKNOWN;
160     }
161     return BSL_SUCCESS;
162 }
163 
164 #define SAL_SECS_IN_NS 1000000000  // 1s = 1000000000ns
165 #define SAL_SECS_IN_MS 1000        // 1s = 1000ms
166 #define SAL_MS_IN_NS 1000000       // 1ms = 1000000ns
167 
BSL_SAL_CondTimedwaitMs(BSL_SAL_Mutex condMutex,BSL_SAL_CondVar condVar,int32_t timeout)168 int32_t BSL_SAL_CondTimedwaitMs(BSL_SAL_Mutex condMutex, BSL_SAL_CondVar condVar, int32_t timeout)
169 {
170     struct timespec stm = {0};
171     struct timespec etm = {0};
172     long int endNs;  // nanosecond
173     long int endSecs;  // second
174     if (condMutex == NULL || condVar == NULL) {
175         return BSL_SAL_ERR_BAD_PARAM;
176     }
177     pthread_mutex_lock(condMutex);
178 
179     clock_gettime(CLOCK_REALTIME, &stm);
180     endSecs = stm.tv_sec + timeout / SAL_SECS_IN_MS;
181     endNs = stm.tv_nsec + (timeout % SAL_SECS_IN_MS) * SAL_MS_IN_NS;
182     endSecs += endNs / SAL_SECS_IN_NS;
183     endNs %= SAL_SECS_IN_NS;
184     etm.tv_sec = endSecs;
185     etm.tv_nsec = endNs;
186 
187     int32_t ret = pthread_cond_timedwait(condVar, condMutex, &etm);
188     pthread_mutex_unlock(condMutex);
189     if (ret != 0) {
190         return BSL_SAL_ERR_UNKNOWN;
191     }
192     return BSL_SUCCESS;
193 }
194 
BSL_SAL_DeleteCondVar(BSL_SAL_CondVar condVar)195 int32_t BSL_SAL_DeleteCondVar(BSL_SAL_CondVar condVar)
196 {
197     if (condVar == NULL) {
198         return BSL_SAL_ERR_BAD_PARAM;
199     }
200     int32_t ret = pthread_cond_destroy((pthread_cond_t *)condVar);
201     BSL_SAL_FREE(condVar);
202     if (ret != 0) {
203         return BSL_SAL_ERR_UNKNOWN;
204     }
205     return BSL_SUCCESS;
206 }
207 #endif
208