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