Deleted Added
full compact
thr_rwlock.c (195403) thr_rwlock.c (213241)
1/*-
2 * Copyright (c) 1998 Alex Nash
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 1998 Alex Nash
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/lib/libthr/thread/thr_rwlock.c 195403 2009-07-06 09:31:04Z attilio $
26 * $FreeBSD: head/lib/libthr/thread/thr_rwlock.c 213241 2010-09-28 04:57:56Z davidxu $
27 */
28
29#include <errno.h>
30#include <limits.h>
31#include <stdlib.h>
32
33#include "namespace.h"
34#include <pthread.h>

--- 5 unchanged lines hidden (view full) ---

40__weak_reference(_pthread_rwlock_rdlock, pthread_rwlock_rdlock);
41__weak_reference(_pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock);
42__weak_reference(_pthread_rwlock_tryrdlock, pthread_rwlock_tryrdlock);
43__weak_reference(_pthread_rwlock_trywrlock, pthread_rwlock_trywrlock);
44__weak_reference(_pthread_rwlock_unlock, pthread_rwlock_unlock);
45__weak_reference(_pthread_rwlock_wrlock, pthread_rwlock_wrlock);
46__weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock);
47
27 */
28
29#include <errno.h>
30#include <limits.h>
31#include <stdlib.h>
32
33#include "namespace.h"
34#include <pthread.h>

--- 5 unchanged lines hidden (view full) ---

40__weak_reference(_pthread_rwlock_rdlock, pthread_rwlock_rdlock);
41__weak_reference(_pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock);
42__weak_reference(_pthread_rwlock_tryrdlock, pthread_rwlock_tryrdlock);
43__weak_reference(_pthread_rwlock_trywrlock, pthread_rwlock_trywrlock);
44__weak_reference(_pthread_rwlock_unlock, pthread_rwlock_unlock);
45__weak_reference(_pthread_rwlock_wrlock, pthread_rwlock_wrlock);
46__weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock);
47
48#define CHECK_AND_INIT_RWLOCK \
49 if (__predict_false((prwlock = (*rwlock)) <= THR_RWLOCK_DESTROYED)) { \
50 if (prwlock == THR_RWLOCK_INITIALIZER) { \
51 int ret; \
52 ret = init_static(_get_curthread(), rwlock); \
53 if (ret) \
54 return (ret); \
55 } else if (prwlock == THR_RWLOCK_DESTROYED) { \
56 return (EINVAL); \
57 } \
58 prwlock = *rwlock; \
59 }
60
48/*
49 * Prototypes
50 */
51
52static int
53rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr __unused)
54{
55 pthread_rwlock_t prwlock;
56
57 prwlock = (pthread_rwlock_t)calloc(1, sizeof(struct pthread_rwlock));
58 if (prwlock == NULL)
59 return (ENOMEM);
60 *rwlock = prwlock;
61 return (0);
62}
63
64int
65_pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
66{
61/*
62 * Prototypes
63 */
64
65static int
66rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr __unused)
67{
68 pthread_rwlock_t prwlock;
69
70 prwlock = (pthread_rwlock_t)calloc(1, sizeof(struct pthread_rwlock));
71 if (prwlock == NULL)
72 return (ENOMEM);
73 *rwlock = prwlock;
74 return (0);
75}
76
77int
78_pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
79{
80 pthread_rwlock_t prwlock;
67 int ret;
68
81 int ret;
82
69 if (rwlock == NULL)
83 prwlock = *rwlock;
84 if (prwlock == THR_RWLOCK_INITIALIZER)
85 ret = 0;
86 else if (prwlock == THR_RWLOCK_DESTROYED)
70 ret = EINVAL;
71 else {
87 ret = EINVAL;
88 else {
72 pthread_rwlock_t prwlock;
89 *rwlock = THR_RWLOCK_DESTROYED;
73
90
74 prwlock = *rwlock;
75 *rwlock = NULL;
76
77 free(prwlock);
78 ret = 0;
79 }
80 return (ret);
81}
82
83static int
84init_static(struct pthread *thread, pthread_rwlock_t *rwlock)
85{
86 int ret;
87
88 THR_LOCK_ACQUIRE(thread, &_rwlock_static_lock);
89
91 free(prwlock);
92 ret = 0;
93 }
94 return (ret);
95}
96
97static int
98init_static(struct pthread *thread, pthread_rwlock_t *rwlock)
99{
100 int ret;
101
102 THR_LOCK_ACQUIRE(thread, &_rwlock_static_lock);
103
90 if (*rwlock == NULL)
104 if (*rwlock == THR_RWLOCK_INITIALIZER)
91 ret = rwlock_init(rwlock, NULL);
92 else
93 ret = 0;
94
95 THR_LOCK_RELEASE(thread, &_rwlock_static_lock);
96
97 return (ret);
98}

--- 9 unchanged lines hidden (view full) ---

108rwlock_rdlock_common(pthread_rwlock_t *rwlock, const struct timespec *abstime)
109{
110 struct pthread *curthread = _get_curthread();
111 pthread_rwlock_t prwlock;
112 struct timespec ts, ts2, *tsp;
113 int flags;
114 int ret;
115
105 ret = rwlock_init(rwlock, NULL);
106 else
107 ret = 0;
108
109 THR_LOCK_RELEASE(thread, &_rwlock_static_lock);
110
111 return (ret);
112}

--- 9 unchanged lines hidden (view full) ---

122rwlock_rdlock_common(pthread_rwlock_t *rwlock, const struct timespec *abstime)
123{
124 struct pthread *curthread = _get_curthread();
125 pthread_rwlock_t prwlock;
126 struct timespec ts, ts2, *tsp;
127 int flags;
128 int ret;
129
116 if (__predict_false(rwlock == NULL))
117 return (EINVAL);
130 CHECK_AND_INIT_RWLOCK
118
131
119 prwlock = *rwlock;
120
121 /* check for static initialization */
122 if (__predict_false(prwlock == NULL)) {
123 if ((ret = init_static(curthread, rwlock)) != 0)
124 return (ret);
125
126 prwlock = *rwlock;
127 }
128
129 if (curthread->rdlock_count) {
130 /*
131 * To avoid having to track all the rdlocks held by
132 * a thread or all of the threads that hold a rdlock,
133 * we keep a simple count of all the rdlocks held by
134 * a thread. If a thread holds any rdlocks it is
135 * possible that it is attempting to take a recursive
136 * rdlock. If there are blocked writers and precedence

--- 64 unchanged lines hidden (view full) ---

201int
202_pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
203{
204 struct pthread *curthread = _get_curthread();
205 pthread_rwlock_t prwlock;
206 int flags;
207 int ret;
208
132 if (curthread->rdlock_count) {
133 /*
134 * To avoid having to track all the rdlocks held by
135 * a thread or all of the threads that hold a rdlock,
136 * we keep a simple count of all the rdlocks held by
137 * a thread. If a thread holds any rdlocks it is
138 * possible that it is attempting to take a recursive
139 * rdlock. If there are blocked writers and precedence

--- 64 unchanged lines hidden (view full) ---

204int
205_pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
206{
207 struct pthread *curthread = _get_curthread();
208 pthread_rwlock_t prwlock;
209 int flags;
210 int ret;
211
209 if (__predict_false(rwlock == NULL))
210 return (EINVAL);
212 CHECK_AND_INIT_RWLOCK
211
213
212 prwlock = *rwlock;
213
214 /* check for static initialization */
215 if (__predict_false(prwlock == NULL)) {
216 if ((ret = init_static(curthread, rwlock)) != 0)
217 return (ret);
218
219 prwlock = *rwlock;
220 }
221
222 if (curthread->rdlock_count) {
223 /*
224 * To avoid having to track all the rdlocks held by
225 * a thread or all of the threads that hold a rdlock,
226 * we keep a simple count of all the rdlocks held by
227 * a thread. If a thread holds any rdlocks it is
228 * possible that it is attempting to take a recursive
229 * rdlock. If there are blocked writers and precedence

--- 15 unchanged lines hidden (view full) ---

245
246int
247_pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
248{
249 struct pthread *curthread = _get_curthread();
250 pthread_rwlock_t prwlock;
251 int ret;
252
214 if (curthread->rdlock_count) {
215 /*
216 * To avoid having to track all the rdlocks held by
217 * a thread or all of the threads that hold a rdlock,
218 * we keep a simple count of all the rdlocks held by
219 * a thread. If a thread holds any rdlocks it is
220 * possible that it is attempting to take a recursive
221 * rdlock. If there are blocked writers and precedence

--- 15 unchanged lines hidden (view full) ---

237
238int
239_pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
240{
241 struct pthread *curthread = _get_curthread();
242 pthread_rwlock_t prwlock;
243 int ret;
244
253 if (__predict_false(rwlock == NULL))
254 return (EINVAL);
245 CHECK_AND_INIT_RWLOCK
255
246
256 prwlock = *rwlock;
257
258 /* check for static initialization */
259 if (__predict_false(prwlock == NULL)) {
260 if ((ret = init_static(curthread, rwlock)) != 0)
261 return (ret);
262
263 prwlock = *rwlock;
264 }
265
266 ret = _thr_rwlock_trywrlock(&prwlock->lock);
267 if (ret == 0)
268 prwlock->owner = curthread;
269 return (ret);
270}
271
272static int
273rwlock_wrlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime)
274{
275 struct pthread *curthread = _get_curthread();
276 pthread_rwlock_t prwlock;
277 struct timespec ts, ts2, *tsp;
278 int ret;
279
247 ret = _thr_rwlock_trywrlock(&prwlock->lock);
248 if (ret == 0)
249 prwlock->owner = curthread;
250 return (ret);
251}
252
253static int
254rwlock_wrlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime)
255{
256 struct pthread *curthread = _get_curthread();
257 pthread_rwlock_t prwlock;
258 struct timespec ts, ts2, *tsp;
259 int ret;
260
280 if (__predict_false(rwlock == NULL))
281 return (EINVAL);
261 CHECK_AND_INIT_RWLOCK
282
262
283 prwlock = *rwlock;
284
285 /* check for static initialization */
286 if (__predict_false(prwlock == NULL)) {
287 if ((ret = init_static(curthread, rwlock)) != 0)
288 return (ret);
289
290 prwlock = *rwlock;
291 }
292
293 /*
294 * POSIX said the validity of the abstimeout parameter need
295 * not be checked if the lock can be immediately acquired.
296 */
297 ret = _thr_rwlock_trywrlock(&prwlock->lock);
298 if (ret == 0) {
299 prwlock->owner = curthread;
300 return (ret);

--- 50 unchanged lines hidden (view full) ---

351int
352_pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
353{
354 struct pthread *curthread = _get_curthread();
355 pthread_rwlock_t prwlock;
356 int ret;
357 int32_t state;
358
263 /*
264 * POSIX said the validity of the abstimeout parameter need
265 * not be checked if the lock can be immediately acquired.
266 */
267 ret = _thr_rwlock_trywrlock(&prwlock->lock);
268 if (ret == 0) {
269 prwlock->owner = curthread;
270 return (ret);

--- 50 unchanged lines hidden (view full) ---

321int
322_pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
323{
324 struct pthread *curthread = _get_curthread();
325 pthread_rwlock_t prwlock;
326 int ret;
327 int32_t state;
328
359 if (__predict_false(rwlock == NULL))
360 return (EINVAL);
361
362 prwlock = *rwlock;
363
329 prwlock = *rwlock;
330
364 if (__predict_false(prwlock == NULL))
331 if (__predict_false(prwlock <= THR_RWLOCK_DESTROYED))
365 return (EINVAL);
366
367 state = prwlock->lock.rw_state;
368 if (state & URWLOCK_WRITE_OWNER) {
369 if (__predict_false(prwlock->owner != curthread))
370 return (EPERM);
371 prwlock->owner = NULL;
372 }
373
374 ret = _thr_rwlock_unlock(&prwlock->lock);
375 if (ret == 0 && (state & URWLOCK_WRITE_OWNER) == 0)
376 curthread->rdlock_count--;
377
378 return (ret);
379}
332 return (EINVAL);
333
334 state = prwlock->lock.rw_state;
335 if (state & URWLOCK_WRITE_OWNER) {
336 if (__predict_false(prwlock->owner != curthread))
337 return (EPERM);
338 prwlock->owner = NULL;
339 }
340
341 ret = _thr_rwlock_unlock(&prwlock->lock);
342 if (ret == 0 && (state & URWLOCK_WRITE_OWNER) == 0)
343 curthread->rdlock_count--;
344
345 return (ret);
346}