1 /*
2 * Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under 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 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2022-11-15
13 * Description: pthread rwlock功能实现
14 */
15 #include "pthread.h"
16 #include "prt_posix_internal.h"
17 #include "../../core/ipc/rwlock/prt_rwlock_internal.h"
18 #include "prt_mem.h"
19
20 #if defined(OS_POSIX_TYPE_NEWLIB)
21 prt_pthread_rwlock_t g_rwlist_head = {0};
22
OsRwlockGetMagic(pthread_rwlock_t * rwlock)23 OS_SEC_ALW_INLINE INLINE U32 OsRwlockGetMagic(pthread_rwlock_t *rwlock)
24 {
25 return ((*(U32 *)rwlock & 0xffff0000U) >> 16U);
26 }
27
OsRwlockSetMagic(pthread_rwlock_t * rwlock,U32 val)28 OS_SEC_ALW_INLINE INLINE void OsRwlockSetMagic(pthread_rwlock_t *rwlock, U32 val)
29 {
30 *(U32 *)rwlock = (*(U32 *)rwlock & 0xffffU) | (val << 16U);
31 }
32
OsRwlockGetIndex(pthread_rwlock_t * rwlock)33 OS_SEC_ALW_INLINE INLINE U32 OsRwlockGetIndex(pthread_rwlock_t *rwlock)
34 {
35 return (*(U32 *)rwlock & 0xffffU);
36 }
37
OsRwlockSetIndex(pthread_rwlock_t * rwlock,U32 val)38 OS_SEC_ALW_INLINE INLINE void OsRwlockSetIndex(pthread_rwlock_t *rwlock, U32 val)
39 {
40 *(U32 *)rwlock = (*(U32 *)rwlock & 0xffff0000U) | (val & 0xffffU);
41 }
42 #endif
43
OsRwlock2InnerStruct(pthread_rwlock_t * rwl)44 static prt_pthread_rwlock_t *OsRwlock2InnerStruct(pthread_rwlock_t *rwl)
45 {
46 #if defined(OS_POSIX_TYPE_NEWLIB)
47 prt_pthread_rwlock_t *rwlock = NULL;
48 prt_pthread_rwlock_t *ptr = &g_rwlist_head;
49
50 if (rwl == NULL) {
51 return NULL;
52 }
53 if (OsRwlockGetMagic(rwl) != RWLOCK_MAGIC_NUM) {
54 return NULL;
55 }
56 while (ptr != NULL) {
57 if (OsRwlockGetIndex(rwl) == ptr->index) {
58 rwlock = ptr;
59 break;
60 }
61 ptr = ptr->next;
62 }
63
64 return rwlock;
65 #else
66 return (prt_pthread_rwlock_t *)rwl;
67 #endif
68 }
69
70 /*
71 * 初始化读写锁
72 */
PRT_PthreadRwlockInit(prt_pthread_rwlock_t * rwl,const pthread_rwlockattr_t * attr)73 int PRT_PthreadRwlockInit(prt_pthread_rwlock_t *rwl, const pthread_rwlockattr_t *attr)
74 {
75 U32 intSave;
76
77 (void)attr;
78 if (rwl == NULL) {
79 return EINVAL;
80 }
81
82 intSave = PRT_HwiLock();
83 if ((rwl->rw_magic & RWLOCK_COUNT_MASK) == RWLOCK_MAGIC_NUM) {
84 PRT_HwiRestore(intSave);
85 return EBUSY;
86 }
87
88 rwl->rw_count = 0;
89 rwl->rw_owner = NULL;
90 INIT_LIST_OBJECT(&(rwl->rw_read));
91 INIT_LIST_OBJECT(&(rwl->rw_write));
92 rwl->rw_magic = RWLOCK_MAGIC_NUM;
93 PRT_HwiRestore(intSave);
94
95 return OS_OK;
96 }
97
pthread_rwlock_init(pthread_rwlock_t * rwl,const pthread_rwlockattr_t * attr)98 int pthread_rwlock_init(pthread_rwlock_t *rwl, const pthread_rwlockattr_t *attr)
99 {
100 #if defined(OS_POSIX_TYPE_NEWLIB)
101 prt_pthread_rwlock_t *rwlock;
102 prt_pthread_rwlock_t *ptr = &g_rwlist_head;
103 U16 index = 0;
104
105 if (rwl == NULL) {
106 return EINVAL;
107 }
108 if (OsRwlockGetMagic(rwl) == RWLOCK_MAGIC_NUM) {
109 return EBUSY;
110 }
111 rwlock = PRT_MemAlloc(0, 0, sizeof(prt_pthread_rwlock_t));
112 if (rwlock == NULL) {
113 return ENOMEM;
114 }
115 while (ptr->next != NULL) {
116 if ((index + 1) != ptr->index) {
117 break;
118 }
119 index = ptr->index;
120 ptr = ptr->next;
121 }
122 rwlock->index = index + 1;
123 OsRwlockSetMagic(rwl, RWLOCK_MAGIC_NUM);
124 OsRwlockSetIndex(rwl, index + 1);
125 rwlock->next = ptr->next;
126 ptr->next = rwlock;
127
128 return PRT_PthreadRwlockInit(rwlock, attr);
129 #else
130 return PRT_PthreadRwlockInit((prt_pthread_rwlock_t *)rwl, attr);
131 #endif
132 }
133
134 /*
135 * 销毁读写锁
136 */
PRT_PthreadRwlockDestroy(prt_pthread_rwlock_t * rwl)137 int PRT_PthreadRwlockDestroy(prt_pthread_rwlock_t *rwl)
138 {
139 U32 intSave;
140
141 if (rwl == NULL) {
142 return EINVAL;
143 }
144
145 intSave = PRT_HwiLock();
146 if ((rwl->rw_magic & RWLOCK_COUNT_MASK) != RWLOCK_MAGIC_NUM) {
147 PRT_HwiRestore(intSave);
148 return EINVAL;
149 }
150
151 if (rwl->rw_count != 0) {
152 PRT_HwiRestore(intSave);
153 return EBUSY;
154 }
155
156 (void)memset_s(rwl, sizeof(prt_pthread_rwlock_t), 0, sizeof(prt_pthread_rwlock_t));
157 PRT_HwiRestore(intSave);
158
159 return OS_OK;
160 }
161
pthread_rwlock_destroy(pthread_rwlock_t * rwl)162 int pthread_rwlock_destroy(pthread_rwlock_t *rwl)
163 {
164 #if defined(OS_POSIX_TYPE_NEWLIB)
165 prt_pthread_rwlock_t *rwlock = NULL;
166 prt_pthread_rwlock_t *ptr = &g_rwlist_head;
167 U32 ret;
168
169 if (rwl == NULL) {
170 return EINVAL;
171 }
172 if (OsRwlockGetMagic(rwl) != RWLOCK_MAGIC_NUM) {
173 return EINVAL;
174 }
175 while (ptr != NULL) {
176 if (OsRwlockGetIndex(rwl) == ptr->index) {
177 rwlock = ptr;
178 break;
179 }
180 ptr = ptr->next;
181 }
182
183 ret = PRT_PthreadRwlockDestroy(rwlock);
184 if (ret != OS_OK) {
185 return (int)ret;
186 }
187 OsRwlockSetIndex(rwl, 0);
188 OsRwlockSetMagic(rwl, 0);
189 ptr->next = rwlock->next;
190 rwlock->next = NULL;
191
192 ret = PRT_MemFree(0, rwlock);
193 if (ret != OS_OK) {
194 OsErrRecord(ret);
195 }
196 return OS_OK;
197 #else
198 return PRT_PthreadRwlockDestroy((prt_pthread_rwlock_t *)rwl);
199 #endif
200 }
201
202 /*
203 * 阻塞获取读锁
204 */
pthread_rwlock_rdlock(pthread_rwlock_t * rwl)205 int pthread_rwlock_rdlock(pthread_rwlock_t *rwl)
206 {
207 prt_pthread_rwlock_t *rwlock = OsRwlock2InnerStruct(rwl);
208
209 return (int)OsRwLockRdPend(rwlock, OS_WAIT_FOREVER, RWLOCK_RD);
210 }
211
212 /*
213 * 非阻塞获取读锁
214 */
pthread_rwlock_tryrdlock(pthread_rwlock_t * rwl)215 int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwl)
216 {
217 prt_pthread_rwlock_t *rwlock = OsRwlock2InnerStruct(rwl);
218
219 return (int)OsRwLockRdPend(rwlock, 0, RWLOCK_TRYRD);
220 }
221
222 /*
223 * 带超时获取读锁
224 */
pthread_rwlock_timedrdlock(pthread_rwlock_t * rwl,const struct timespec * time)225 int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwl, const struct timespec *time)
226 {
227 U32 ret;
228 U32 ticks;
229 prt_pthread_rwlock_t *rwlock = OsRwlock2InnerStruct(rwl);
230
231 if (time == NULL) {
232 return EINVAL;
233 }
234
235 ret = OsTimeOut2Ticks(time, &ticks);
236 if (ret != OS_OK) {
237 return (int)ret;
238 }
239
240 return (int)OsRwLockRdPend(rwlock, ticks, RWLOCK_TIMERD);
241 }
242
243 /*
244 * 阻塞获取写锁
245 */
pthread_rwlock_wrlock(pthread_rwlock_t * rwl)246 int pthread_rwlock_wrlock(pthread_rwlock_t *rwl)
247 {
248 prt_pthread_rwlock_t *rwlock = OsRwlock2InnerStruct(rwl);
249
250 return (int)OsRwLockWrPend(rwlock, OS_WAIT_FOREVER, RWLOCK_WR);
251 }
252
253 /*
254 * 非阻塞获取写锁
255 */
pthread_rwlock_trywrlock(pthread_rwlock_t * rwl)256 int pthread_rwlock_trywrlock(pthread_rwlock_t *rwl)
257 {
258 prt_pthread_rwlock_t *rwlock = OsRwlock2InnerStruct(rwl);
259
260 return (int)OsRwLockWrPend(rwlock, 0, RWLOCK_TRYWR);
261 }
262
263 /*
264 * 带超时获取写锁
265 */
pthread_rwlock_timedwrlock(pthread_rwlock_t * rwl,const struct timespec * time)266 int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwl, const struct timespec *time)
267 {
268 U32 ret;
269 U32 ticks;
270 prt_pthread_rwlock_t *rwlock = OsRwlock2InnerStruct(rwl);
271
272 if (time == NULL) {
273 return EINVAL;
274 }
275
276 ret = OsTimeOut2Ticks(time, &ticks);
277 if (ret != OS_OK) {
278 return (int)ret;
279 }
280
281 return (int)OsRwLockWrPend(rwlock, ticks, RWLOCK_TIMEWR);
282 }
283
284 /*
285 * 读写锁解锁
286 */
pthread_rwlock_unlock(pthread_rwlock_t * rwl)287 int pthread_rwlock_unlock(pthread_rwlock_t *rwl)
288 {
289 U32 ret;
290 U32 intSave;
291 bool needSched = FALSE;
292 prt_pthread_rwlock_t *rwlock = OsRwlock2InnerStruct(rwl);
293
294 intSave = PRT_HwiLock();
295 ret = OsRwLockUnlock(rwlock, &needSched);
296 if (ret != OS_OK) {
297 PRT_HwiRestore(intSave);
298 return (int)ret;
299 }
300
301 PRT_HwiRestore(intSave);
302 if (needSched == TRUE) {
303 OsTskSchedule();
304 }
305
306 return (int)ret;
307 }
308
309 /*
310 * 读写锁属性销毁
311 */
pthread_rwlockattr_destroy(pthread_rwlockattr_t * attr)312 int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
313 {
314 (void)attr;
315
316 return OS_OK;
317 }
318
319 /*
320 * 读写锁属性初始化
321 */
pthread_rwlockattr_init(pthread_rwlockattr_t * attr)322 int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
323 {
324 (void)attr;
325
326 return OS_OK;
327 }
328
329