• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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