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