1168404Spjd/*- 2168404Spjd * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3168404Spjd * All rights reserved. 4168404Spjd * 5168404Spjd * Redistribution and use in source and binary forms, with or without 6168404Spjd * modification, are permitted provided that the following conditions 7168404Spjd * are met: 8168404Spjd * 1. Redistributions of source code must retain the above copyright 9168404Spjd * notice, this list of conditions and the following disclaimer. 10168404Spjd * 2. Redistributions in binary form must reproduce the above copyright 11168404Spjd * notice, this list of conditions and the following disclaimer in the 12168404Spjd * documentation and/or other materials provided with the distribution. 13168404Spjd * 14168404Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15168404Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16168404Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17168404Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18168404Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19168404Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20168404Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21168404Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22168404Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23168404Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24168404Spjd * SUCH DAMAGE. 25168404Spjd * 26168404Spjd * $FreeBSD$ 27168404Spjd */ 28168404Spjd 29168404Spjd#ifndef _OPENSOLARIS_SYS_RWLOCK_H_ 30168404Spjd#define _OPENSOLARIS_SYS_RWLOCK_H_ 31168404Spjd 32168404Spjd#include <sys/param.h> 33168404Spjd#include <sys/proc.h> 34168404Spjd#include <sys/lock.h> 35168404Spjd#include <sys/sx.h> 36168404Spjd 37168404Spjd#ifdef _KERNEL 38168404Spjd 39168404Spjdtypedef enum { 40168404Spjd RW_DEFAULT = 4 /* kernel default rwlock */ 41168404Spjd} krw_type_t; 42168404Spjd 43168404Spjdtypedef enum { 44168404Spjd RW_WRITER, 45168404Spjd RW_READER 46168404Spjd} krw_t; 47168404Spjd 48168404Spjdtypedef struct sx krwlock_t; 49168404Spjd 50253996Savg#ifndef OPENSOLARIS_WITNESS 51193011Sattilio#define RW_FLAGS (SX_DUPOK | SX_NOWITNESS) 52170006Spjd#else 53193011Sattilio#define RW_FLAGS (SX_DUPOK) 54170006Spjd#endif 55170006Spjd 56168404Spjd#define RW_READ_HELD(x) (rw_read_held((x))) 57168404Spjd#define RW_WRITE_HELD(x) (rw_write_held((x))) 58168404Spjd#define RW_LOCK_HELD(x) (rw_lock_held((x))) 59168404Spjd#define RW_ISWRITER(x) (rw_iswriter(x)) 60168404Spjd 61168514Spjd#define rw_init(lock, desc, type, arg) do { \ 62173371Spjd const char *_name; \ 63219089Spjd ASSERT((type) == 0 || (type) == RW_DEFAULT); \ 64168514Spjd KASSERT(((lock)->lock_object.lo_flags & LO_ALLMASK) != \ 65168514Spjd LO_EXPECTED, ("lock %s already initialized", #lock)); \ 66168514Spjd bzero((lock), sizeof(struct sx)); \ 67173371Spjd for (_name = #lock; *_name != '\0'; _name++) { \ 68173371Spjd if (*_name >= 'a' && *_name <= 'z') \ 69173371Spjd break; \ 70173371Spjd } \ 71173371Spjd if (*_name == '\0') \ 72173371Spjd _name = #lock; \ 73173371Spjd sx_init_flags((lock), _name, RW_FLAGS); \ 74168514Spjd} while (0) 75168404Spjd#define rw_destroy(lock) sx_destroy(lock) 76168404Spjd#define rw_enter(lock, how) do { \ 77168404Spjd if ((how) == RW_READER) \ 78168404Spjd sx_slock(lock); \ 79168404Spjd else /* if ((how) == RW_WRITER) */ \ 80168404Spjd sx_xlock(lock); \ 81168404Spjd} while (0) 82168404Spjd#define rw_tryenter(lock, how) ((how) == RW_READER ? sx_try_slock(lock) : sx_try_xlock(lock)) 83168404Spjd#define rw_exit(lock) sx_unlock(lock) 84168404Spjd#define rw_downgrade(lock) sx_downgrade(lock) 85168404Spjd#define rw_tryupgrade(lock) sx_try_upgrade(lock) 86168404Spjd#define rw_read_held(lock) ((lock)->sx_lock != SX_LOCK_UNLOCKED && ((lock)->sx_lock & SX_LOCK_SHARED)) 87168404Spjd#define rw_write_held(lock) sx_xlocked(lock) 88168404Spjd#define rw_lock_held(lock) (rw_read_held(lock) || rw_write_held(lock)) 89168404Spjd#define rw_iswriter(lock) sx_xlocked(lock) 90168404Spjd/* TODO: Change to sx_xholder() once it is moved from kern_sx.c to sx.h. */ 91168404Spjd#define rw_owner(lock) ((lock)->sx_lock & SX_LOCK_SHARED ? NULL : (struct thread *)SX_OWNER((lock)->sx_lock)) 92168404Spjd 93168404Spjd#endif /* defined(_KERNEL) */ 94168404Spjd 95168404Spjd#endif /* _OPENSOLARIS_SYS_RWLOCK_H_ */ 96