rmlock.h revision 247588
11558Srgrimes/*-
292058Sobrien * Copyright (c) 2007 Stephan Uphoff <ups@FreeBSD.org>
392058Sobrien * All rights reserved.
492058Sobrien *
51558Srgrimes * Redistribution and use in source and binary forms, with or without
61558Srgrimes * modification, are permitted provided that the following conditions
71558Srgrimes * are met:
81558Srgrimes * 1. Redistributions of source code must retain the above copyright
91558Srgrimes *    notice, this list of conditions and the following disclaimer.
101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111558Srgrimes *    notice, this list of conditions and the following disclaimer in the
121558Srgrimes *    documentation and/or other materials provided with the distribution.
131558Srgrimes * 3. Neither the name of the author nor the names of any co-contributors
141558Srgrimes *    may be used to endorse or promote products derived from this software
151558Srgrimes *    without specific prior written permission.
161558Srgrimes *
171558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
181558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201558Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
211558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2392058Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271558Srgrimes * SUCH DAMAGE.
281558Srgrimes *
291558Srgrimes * $FreeBSD: head/sys/sys/rmlock.h 247588 2013-03-01 22:03:31Z jhb $
301558Srgrimes */
311558Srgrimes
321558Srgrimes#ifndef _SYS_RMLOCK_H_
331558Srgrimes#define _SYS_RMLOCK_H_
341558Srgrimes
351558Srgrimes#include <sys/mutex.h>
361558Srgrimes#include <sys/sx.h>
371558Srgrimes#include <sys/_lock.h>
381558Srgrimes#include <sys/_rmlock.h>
3992058Sobrien
4092058Sobrien#ifdef _KERNEL
411558Srgrimes
421558Srgrimes/*
431558Srgrimes * Flags passed to rm_init_flags(9).
4436632Scharnier */
451558Srgrimes#define	RM_NOWITNESS	0x00000001
461558Srgrimes#define	RM_RECURSE	0x00000002
471558Srgrimes#define	RM_SLEEPABLE	0x00000004
481558Srgrimes
491558Srgrimesvoid	rm_init(struct rmlock *rm, const char *name);
5036632Scharniervoid	rm_init_flags(struct rmlock *rm, const char *name, int opts);
511558Srgrimesvoid	rm_destroy(struct rmlock *rm);
521558Srgrimesint	rm_wowned(const struct rmlock *rm);
5336632Scharniervoid	rm_sysinit(void *arg);
541558Srgrimesvoid	rm_sysinit_flags(void *arg);
551558Srgrimes
5699365Smarkmvoid	_rm_wlock_debug(struct rmlock *rm, const char *file, int line);
5799365Smarkmvoid	_rm_wunlock_debug(struct rmlock *rm, const char *file, int line);
5899365Smarkmint	_rm_rlock_debug(struct rmlock *rm, struct rm_priotracker *tracker,
591558Srgrimes	    int trylock, const char *file, int line);
601558Srgrimesvoid	_rm_runlock_debug(struct rmlock *rm,  struct rm_priotracker *tracker,
611558Srgrimes	    const char *file, int line);
6213544Sjoerg
631558Srgrimesvoid	_rm_wlock(struct rmlock *rm);
64101994Sbmilekicvoid	_rm_wunlock(struct rmlock *rm);
651558Srgrimesint	_rm_rlock(struct rmlock *rm, struct rm_priotracker *tracker,
6692058Sobrien	    int trylock);
6792058Sobrienvoid	_rm_runlock(struct rmlock *rm,  struct rm_priotracker *tracker);
6892058Sobrien
6999365Smarkm/*
701558Srgrimes * Public interface for lock operations.
711558Srgrimes */
721558Srgrimes#ifndef LOCK_DEBUG
7313544Sjoerg#error LOCK_DEBUG not defined, include <sys/lock.h> before <sys/rmlock.h>
7413544Sjoerg#endif
7513544Sjoerg
761558Srgrimes#if LOCK_DEBUG > 0
7726542Scharnier#define	rm_wlock(rm)	_rm_wlock_debug((rm), LOCK_FILE, LOCK_LINE)
7859216Simp#define	rm_wunlock(rm)	_rm_wunlock_debug((rm), LOCK_FILE, LOCK_LINE)
7999365Smarkm#define	rm_rlock(rm,tracker)  \
801558Srgrimes    ((void)_rm_rlock_debug((rm),(tracker), 0, LOCK_FILE, LOCK_LINE ))
811558Srgrimes#define	rm_try_rlock(rm,tracker)  \
821558Srgrimes    _rm_rlock_debug((rm),(tracker), 1, LOCK_FILE, LOCK_LINE )
831558Srgrimes#define	rm_runlock(rm,tracker)	\
841558Srgrimes    _rm_runlock_debug((rm), (tracker), LOCK_FILE, LOCK_LINE )
851558Srgrimes#else
861558Srgrimes#define	rm_wlock(rm)			_rm_wlock((rm))
871558Srgrimes#define	rm_wunlock(rm)			_rm_wunlock((rm))
881558Srgrimes#define	rm_rlock(rm,tracker)		((void)_rm_rlock((rm),(tracker), 0))
891558Srgrimes#define	rm_try_rlock(rm,tracker)	_rm_rlock((rm),(tracker), 1)
901558Srgrimes#define	rm_runlock(rm,tracker)		_rm_runlock((rm), (tracker))
911558Srgrimes#endif
921558Srgrimes
931558Srgrimesstruct rm_args {
941558Srgrimes	struct rmlock	*ra_rm;
9573034Sjwd	const char 	*ra_desc;
9673034Sjwd};
9773034Sjwd
9873034Sjwdstruct rm_args_flags {
9973034Sjwd	struct rmlock	*ra_rm;
10073034Sjwd	const char 	*ra_desc;
10197535Siedowse	int		ra_opts;
10273034Sjwd};
10373034Sjwd
10492057Sobrien#define	RM_SYSINIT(name, rm, desc)       				\
10592057Sobrien	static struct rm_args name##_args = {				\
10697047Sbenno		(rm),							\
1071558Srgrimes		(desc),							\
1081558Srgrimes	};								\
10992057Sobrien	SYSINIT(name##_rm_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
1101558Srgrimes	    rm_sysinit, &name##_args);					\
1111558Srgrimes	SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
11292541Simp	    rm_destroy, (rm))
11392541Simp
11492541Simp
11592541Simp#define	RM_SYSINIT_FLAGS(name, rm, desc, opts)       			\
11692541Simp	static struct rm_args name##_args = {				\
11792541Simp		(rm),							\
11892541Simp		(desc),							\
11992541Simp                (opts),							\
12092541Simp	};								\
12192541Simp	SYSINIT(name##_rm_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
12292541Simp	    rm_sysinit_flags, &name##_args);				\
12397534Siedowse	SYSUNINIT(name##_rm_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE,	\
12492541Simp	    rm_destroy, (rm))
12592541Simp
12692541Simp#endif /* _KERNEL */
12792541Simp#endif /* !_SYS_RMLOCK_H_ */
12892541Simp