1*b819cea2SGordon Ross /*
2*b819cea2SGordon Ross * This file and its contents are supplied under the terms of the
3*b819cea2SGordon Ross * Common Development and Distribution License ("CDDL"), version 1.0.
4*b819cea2SGordon Ross * You may only use this file in accordance with the terms of version
5*b819cea2SGordon Ross * 1.0 of the CDDL.
6*b819cea2SGordon Ross *
7*b819cea2SGordon Ross * A full copy of the text of the CDDL should have accompanied this
8*b819cea2SGordon Ross * source. A copy of the CDDL is also available via the Internet at
9*b819cea2SGordon Ross * http://www.illumos.org/license/CDDL.
10*b819cea2SGordon Ross */
11*b819cea2SGordon Ross
12*b819cea2SGordon Ross /*
13*b819cea2SGordon Ross * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
14*b819cea2SGordon Ross */
15*b819cea2SGordon Ross
16*b819cea2SGordon Ross /*
17*b819cea2SGordon Ross * rwlock(9f)
18*b819cea2SGordon Ross */
19*b819cea2SGordon Ross
20*b819cea2SGordon Ross /* This is the API we're emulating */
21*b819cea2SGordon Ross #include <sys/rwlock.h>
22*b819cea2SGordon Ross
23*b819cea2SGordon Ross #include <sys/errno.h>
24*b819cea2SGordon Ross #include <sys/debug.h>
25*b819cea2SGordon Ross #include <sys/param.h>
26*b819cea2SGordon Ross #include <sys/synch32.h>
27*b819cea2SGordon Ross #include <sys/thread.h>
28*b819cea2SGordon Ross
29*b819cea2SGordon Ross /* avoiding synch.h */
30*b819cea2SGordon Ross int rwlock_init(lwp_rwlock_t *, int, void *);
31*b819cea2SGordon Ross int rwlock_destroy(lwp_rwlock_t *);
32*b819cea2SGordon Ross int rw_rdlock(lwp_rwlock_t *);
33*b819cea2SGordon Ross int rw_wrlock(lwp_rwlock_t *);
34*b819cea2SGordon Ross int rw_unlock(lwp_rwlock_t *);
35*b819cea2SGordon Ross int rw_tryrdlock(lwp_rwlock_t *);
36*b819cea2SGordon Ross int rw_trywrlock(lwp_rwlock_t *);
37*b819cea2SGordon Ross int _rw_read_held(void *);
38*b819cea2SGordon Ross int _rw_write_held(void *);
39*b819cea2SGordon Ross
40*b819cea2SGordon Ross /*ARGSUSED*/
41*b819cea2SGordon Ross void
rw_init(krwlock_t * rwlp,char * name,krw_type_t type,void * arg)42*b819cea2SGordon Ross rw_init(krwlock_t *rwlp, char *name, krw_type_t type, void *arg)
43*b819cea2SGordon Ross {
44*b819cea2SGordon Ross (void) rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
45*b819cea2SGordon Ross rwlp->rw_owner = _KTHREAD_INVALID;
46*b819cea2SGordon Ross }
47*b819cea2SGordon Ross
48*b819cea2SGordon Ross void
rw_destroy(krwlock_t * rwlp)49*b819cea2SGordon Ross rw_destroy(krwlock_t *rwlp)
50*b819cea2SGordon Ross {
51*b819cea2SGordon Ross (void) rwlock_destroy(&rwlp->rw_lock);
52*b819cea2SGordon Ross rwlp->rw_owner = _KTHREAD_INVALID;
53*b819cea2SGordon Ross }
54*b819cea2SGordon Ross
55*b819cea2SGordon Ross void
rw_enter(krwlock_t * rwlp,krw_t rw)56*b819cea2SGordon Ross rw_enter(krwlock_t *rwlp, krw_t rw)
57*b819cea2SGordon Ross {
58*b819cea2SGordon Ross int rc;
59*b819cea2SGordon Ross
60*b819cea2SGordon Ross if (rw == RW_READER) {
61*b819cea2SGordon Ross rc = rw_rdlock(&rwlp->rw_lock);
62*b819cea2SGordon Ross } else {
63*b819cea2SGordon Ross rc = rw_wrlock(&rwlp->rw_lock);
64*b819cea2SGordon Ross rwlp->rw_owner = _curthread();
65*b819cea2SGordon Ross }
66*b819cea2SGordon Ross VERIFY(rc == 0);
67*b819cea2SGordon Ross }
68*b819cea2SGordon Ross
69*b819cea2SGordon Ross void
rw_exit(krwlock_t * rwlp)70*b819cea2SGordon Ross rw_exit(krwlock_t *rwlp)
71*b819cea2SGordon Ross {
72*b819cea2SGordon Ross if (_rw_write_held(&rwlp->rw_lock)) {
73*b819cea2SGordon Ross ASSERT(rwlp->rw_owner == _curthread());
74*b819cea2SGordon Ross rwlp->rw_owner = _KTHREAD_INVALID;
75*b819cea2SGordon Ross }
76*b819cea2SGordon Ross (void) rw_unlock(&rwlp->rw_lock);
77*b819cea2SGordon Ross }
78*b819cea2SGordon Ross
79*b819cea2SGordon Ross int
rw_tryenter(krwlock_t * rwlp,krw_t rw)80*b819cea2SGordon Ross rw_tryenter(krwlock_t *rwlp, krw_t rw)
81*b819cea2SGordon Ross {
82*b819cea2SGordon Ross int rv;
83*b819cea2SGordon Ross
84*b819cea2SGordon Ross if (rw == RW_WRITER) {
85*b819cea2SGordon Ross rv = rw_trywrlock(&rwlp->rw_lock);
86*b819cea2SGordon Ross if (rv == 0)
87*b819cea2SGordon Ross rwlp->rw_owner = _curthread();
88*b819cea2SGordon Ross } else
89*b819cea2SGordon Ross rv = rw_tryrdlock(&rwlp->rw_lock);
90*b819cea2SGordon Ross
91*b819cea2SGordon Ross return ((rv == 0) ? 1 : 0);
92*b819cea2SGordon Ross }
93*b819cea2SGordon Ross
94*b819cea2SGordon Ross /*ARGSUSED*/
95*b819cea2SGordon Ross int
rw_tryupgrade(krwlock_t * rwlp)96*b819cea2SGordon Ross rw_tryupgrade(krwlock_t *rwlp)
97*b819cea2SGordon Ross {
98*b819cea2SGordon Ross
99*b819cea2SGordon Ross return (0);
100*b819cea2SGordon Ross }
101*b819cea2SGordon Ross
102*b819cea2SGordon Ross void
rw_downgrade(krwlock_t * rwlp)103*b819cea2SGordon Ross rw_downgrade(krwlock_t *rwlp)
104*b819cea2SGordon Ross {
105*b819cea2SGordon Ross ASSERT(rwlp->rw_owner == _curthread());
106*b819cea2SGordon Ross rwlp->rw_owner = _KTHREAD_INVALID;
107*b819cea2SGordon Ross VERIFY(rw_unlock(&rwlp->rw_lock) == 0);
108*b819cea2SGordon Ross VERIFY(rw_rdlock(&rwlp->rw_lock) == 0);
109*b819cea2SGordon Ross }
110*b819cea2SGordon Ross
111*b819cea2SGordon Ross int
rw_read_held(krwlock_t * rwlp)112*b819cea2SGordon Ross rw_read_held(krwlock_t *rwlp)
113*b819cea2SGordon Ross {
114*b819cea2SGordon Ross return (_rw_read_held(rwlp));
115*b819cea2SGordon Ross }
116*b819cea2SGordon Ross
117*b819cea2SGordon Ross int
rw_write_held(krwlock_t * rwlp)118*b819cea2SGordon Ross rw_write_held(krwlock_t *rwlp)
119*b819cea2SGordon Ross {
120*b819cea2SGordon Ross return (_rw_write_held(rwlp));
121*b819cea2SGordon Ross }
122*b819cea2SGordon Ross
123*b819cea2SGordon Ross int
rw_lock_held(krwlock_t * rwlp)124*b819cea2SGordon Ross rw_lock_held(krwlock_t *rwlp)
125*b819cea2SGordon Ross {
126*b819cea2SGordon Ross return (rw_read_held(rwlp) || rw_write_held(rwlp));
127*b819cea2SGordon Ross }
128*b819cea2SGordon Ross
129*b819cea2SGordon Ross /*
130*b819cea2SGordon Ross * Return the kthread_t * of the lock owner
131*b819cea2SGordon Ross */
132*b819cea2SGordon Ross void *
rw_owner(krwlock_t * rwlp)133*b819cea2SGordon Ross rw_owner(krwlock_t *rwlp)
134*b819cea2SGordon Ross {
135*b819cea2SGordon Ross return (rwlp->rw_owner);
136*b819cea2SGordon Ross }
137