1204076Spjd/*- 2204076Spjd * Copyright (c) 2007 Stephan Uphoff <ups@FreeBSD.org> 3220272Spjd * All rights reserved. 4204076Spjd * 5204076Spjd * Redistribution and use in source and binary forms, with or without 6204076Spjd * modification, are permitted provided that the following conditions 7204076Spjd * are met: 8204076Spjd * 1. Redistributions of source code must retain the above copyright 9204076Spjd * notice, this list of conditions and the following disclaimer. 10204076Spjd * 2. Redistributions in binary form must reproduce the above copyright 11204076Spjd * notice, this list of conditions and the following disclaimer in the 12204076Spjd * documentation and/or other materials provided with the distribution. 13204076Spjd * 3. Neither the name of the author nor the names of any co-contributors 14204076Spjd * may be used to endorse or promote products derived from this software 15204076Spjd * without specific prior written permission. 16204076Spjd * 17204076Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18204076Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19204076Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20204076Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21204076Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22204076Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23204076Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24204076Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25204076Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26204076Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27204076Spjd * SUCH DAMAGE. 28204076Spjd * 29204076Spjd * $FreeBSD: stable/10/sys/sys/rmlock.h 323870 2017-09-21 19:24:11Z marius $ 30204076Spjd */ 31204076Spjd 32204076Spjd#ifndef _SYS_RMLOCK_H_ 33204076Spjd#define _SYS_RMLOCK_H_ 34204076Spjd 35204076Spjd#include <sys/mutex.h> 36204076Spjd#include <sys/sx.h> 37204076Spjd#include <sys/_lock.h> 38220272Spjd#include <sys/_rmlock.h> 39220272Spjd 40204076Spjd#ifdef _KERNEL 41204076Spjd 42220272Spjd/* 43204076Spjd * Flags passed to rm_init_flags(9). 44218138Spjd */ 45204076Spjd#define RM_NOWITNESS 0x00000001 46204076Spjd#define RM_RECURSE 0x00000002 47204076Spjd#define RM_SLEEPABLE 0x00000004 48204076Spjd#define RM_NEW 0x00000008 49211452Spjd 50204076Spjdvoid rm_init(struct rmlock *rm, const char *name); 51204076Spjdvoid rm_init_flags(struct rmlock *rm, const char *name, int opts); 52220272Spjdvoid rm_destroy(struct rmlock *rm); 53220272Spjdint rm_wowned(const struct rmlock *rm); 54220272Spjdvoid rm_sysinit(void *arg); 55220272Spjdvoid rm_sysinit_flags(void *arg); 56220272Spjd 57220272Spjdvoid _rm_wlock_debug(struct rmlock *rm, const char *file, int line); 58220272Spjdvoid _rm_wunlock_debug(struct rmlock *rm, const char *file, int line); 59220272Spjdint _rm_rlock_debug(struct rmlock *rm, struct rm_priotracker *tracker, 60220272Spjd int trylock, const char *file, int line); 61220272Spjdvoid _rm_runlock_debug(struct rmlock *rm, struct rm_priotracker *tracker, 62218194Spjd const char *file, int line); 63218194Spjd 64204076Spjdvoid _rm_wlock(struct rmlock *rm); 65218139Spjdvoid _rm_wunlock(struct rmlock *rm); 66218139Spjdint _rm_rlock(struct rmlock *rm, struct rm_priotracker *tracker, 67218139Spjd int trylock); 68218139Spjdvoid _rm_runlock(struct rmlock *rm, struct rm_priotracker *tracker); 69218139Spjd#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT) 70218139Spjdvoid _rm_assert(const struct rmlock *rm, int what, const char *file, 71218139Spjd int line); 72218139Spjd#endif 73218139Spjd 74218139Spjd/* 75218139Spjd * Public interface for lock operations. 76218139Spjd */ 77218139Spjd#ifndef LOCK_DEBUG 78218139Spjd#error LOCK_DEBUG not defined, include <sys/lock.h> before <sys/rmlock.h> 79218139Spjd#endif 80218139Spjd 81218139Spjd#if LOCK_DEBUG > 0 82218139Spjd#define rm_wlock(rm) _rm_wlock_debug((rm), LOCK_FILE, LOCK_LINE) 83218139Spjd#define rm_wunlock(rm) _rm_wunlock_debug((rm), LOCK_FILE, LOCK_LINE) 84218148Spjd#define rm_rlock(rm,tracker) \ 85218139Spjd ((void)_rm_rlock_debug((rm),(tracker), 0, LOCK_FILE, LOCK_LINE )) 86218139Spjd#define rm_try_rlock(rm,tracker) \ 87218139Spjd _rm_rlock_debug((rm),(tracker), 1, LOCK_FILE, LOCK_LINE ) 88218139Spjd#define rm_runlock(rm,tracker) \ 89218139Spjd _rm_runlock_debug((rm), (tracker), LOCK_FILE, LOCK_LINE ) 90218139Spjd#else 91218139Spjd#define rm_wlock(rm) _rm_wlock((rm)) 92218139Spjd#define rm_wunlock(rm) _rm_wunlock((rm)) 93218194Spjd#define rm_rlock(rm,tracker) ((void)_rm_rlock((rm),(tracker), 0)) 94218139Spjd#define rm_try_rlock(rm,tracker) _rm_rlock((rm),(tracker), 1) 95218194Spjd#define rm_runlock(rm,tracker) _rm_runlock((rm), (tracker)) 96218194Spjd#endif 97218194Spjd#define rm_sleep(chan, rm, pri, wmesg, timo) \ 98218194Spjd _sleep((chan), &(rm)->lock_object, (pri), (wmesg), \ 99220270Spjd tick_sbt * (timo), 0, C_HARDCLOCK) 100220270Spjd 101220270Spjdstruct rm_args { 102220270Spjd struct rmlock *ra_rm; 103220270Spjd const char *ra_desc; 104220270Spjd}; 105220270Spjd 106220270Spjdstruct rm_args_flags { 107220270Spjd struct rmlock *ra_rm; 108220270Spjd const char *ra_desc; 109220270Spjd int ra_opts; 110218194Spjd}; 111218194Spjd 112218194Spjd#define RM_SYSINIT(name, rm, desc) \ 113218194Spjd static struct rm_args name##_args = { \ 114218194Spjd (rm), \ 115218194Spjd (desc), \ 116220272Spjd }; \ 117218194Spjd SYSINIT(name##_rm_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ 118220272Spjd rm_sysinit, &name##_args); \ 119218194Spjd SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ 120218194Spjd rm_destroy, (rm)) 121220272Spjd 122220272Spjd 123220272Spjd#define RM_SYSINIT_FLAGS(name, rm, desc, opts) \ 124220272Spjd static struct rm_args name##_args = { \ 125220272Spjd (rm), \ 126220272Spjd (desc), \ 127220272Spjd (opts), \ 128220272Spjd }; \ 129218194Spjd SYSINIT(name##_rm_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ 130218194Spjd rm_sysinit_flags, &name##_args); \ 131218194Spjd SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ 132218194Spjd rm_destroy, (rm)) 133218194Spjd 134218194Spjd#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT) 135218194Spjd#define RA_LOCKED LA_LOCKED 136218194Spjd#define RA_RLOCKED LA_SLOCKED 137218194Spjd#define RA_WLOCKED LA_XLOCKED 138218194Spjd#define RA_UNLOCKED LA_UNLOCKED 139218194Spjd#define RA_RECURSED LA_RECURSED 140218194Spjd#define RA_NOTRECURSED LA_NOTRECURSED 141218194Spjd#endif 142218194Spjd 143218139Spjd#ifdef INVARIANTS 144218139Spjd#define rm_assert(rm, what) _rm_assert((rm), (what), LOCK_FILE, LOCK_LINE) 145218139Spjd#else 146218139Spjd#define rm_assert(rm, what) 147218139Spjd#endif 148218139Spjd 149218139Spjd#endif /* _KERNEL */ 150218139Spjd#endif /* !_SYS_RMLOCK_H_ */ 151218139Spjd