1139825Simp/*-
2177957Sattilio * Copyright (c) 2008 Attilio Rao <attilio@FreeBSD.org>
3177957Sattilio * All rights reserved.
424269Speter *
524269Speter * Redistribution and use in source and binary forms, with or without
624269Speter * modification, are permitted provided that the following conditions
724269Speter * are met:
824269Speter * 1. Redistributions of source code must retain the above copyright
9177957Sattilio *    notice(s), this list of conditions and the following disclaimer as
10177957Sattilio *    the first lines of this file unmodified other than the possible
11177957Sattilio *    addition of one or more copyright notices.
1224269Speter * 2. Redistributions in binary form must reproduce the above copyright
13177957Sattilio *    notice(s), this list of conditions and the following disclaimer in the
1424269Speter *    documentation and/or other materials provided with the distribution.
1524269Speter *
16177957Sattilio * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
17177957Sattilio * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18177957Sattilio * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19177957Sattilio * DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
20177957Sattilio * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21177957Sattilio * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22177957Sattilio * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23177957Sattilio * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2424269Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25177957Sattilio * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26177957Sattilio * DAMAGE.
2724269Speter *
2850477Speter * $FreeBSD$
2924269Speter */
3024269Speter
3176166Smarkm#ifndef	_SYS_LOCKMGR_H_
3276166Smarkm#define	_SYS_LOCKMGR_H_
3324269Speter
34176708Sattilio#include <sys/_lock.h>
35177957Sattilio#include <sys/_lockmgr.h>
36177957Sattilio#include <sys/_mutex.h>
37177957Sattilio#include <sys/_rwlock.h>
38148668Sjeff
39177957Sattilio#define	LK_SHARE			0x01
40177957Sattilio#define	LK_SHARED_WAITERS		0x02
41177957Sattilio#define	LK_EXCLUSIVE_WAITERS		0x04
42194317Sattilio#define	LK_EXCLUSIVE_SPINNERS		0x08
43177957Sattilio#define	LK_ALL_WAITERS							\
44177957Sattilio	(LK_SHARED_WAITERS | LK_EXCLUSIVE_WAITERS)
45177957Sattilio#define	LK_FLAGMASK							\
46194317Sattilio	(LK_SHARE | LK_ALL_WAITERS | LK_EXCLUSIVE_SPINNERS)
4767537Sjhb
48177957Sattilio#define	LK_HOLDER(x)			((x) & ~LK_FLAGMASK)
49194317Sattilio#define	LK_SHARERS_SHIFT		4
50177957Sattilio#define	LK_SHARERS(x)			(LK_HOLDER(x) >> LK_SHARERS_SHIFT)
51177957Sattilio#define	LK_SHARERS_LOCK(x)		((x) << LK_SHARERS_SHIFT | LK_SHARE)
52177957Sattilio#define	LK_ONE_SHARER			(1 << LK_SHARERS_SHIFT)
53177957Sattilio#define	LK_UNLOCKED			LK_SHARERS_LOCK(0)
54177957Sattilio#define	LK_KERNPROC			((uintptr_t)(-1) & ~LK_FLAGMASK)
55177957Sattilio
56177957Sattilio#ifdef _KERNEL
57177957Sattilio
58177957Sattilio#if !defined(LOCK_FILE) || !defined(LOCK_LINE)
59177957Sattilio#error	"LOCK_FILE and LOCK_LINE not defined, include <sys/lock.h> before"
60177957Sattilio#endif
61177957Sattilio
62177957Sattiliostruct thread;
63179025Sattilio#define	lk_recurse	lock_object.lo_data
64177957Sattilio
6524269Speter/*
66177957Sattilio * Function prototipes.  Routines that start with an underscore are not part
67177957Sattilio * of the public interface and might be wrappered with a macro.
6824269Speter */
69177957Sattilioint	 __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
70177957Sattilio	    const char *wmesg, int prio, int timo, const char *file, int line);
71177957Sattilio#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
72227588Spjdvoid	 _lockmgr_assert(const struct lock *lk, int what, const char *file, int line);
73177957Sattilio#endif
74177957Sattiliovoid	 _lockmgr_disown(struct lock *lk, const char *file, int line);
75164159Skmacy
76211531Sjhbvoid	 lockallowrecurse(struct lock *lk);
77211531Sjhbvoid	 lockallowshare(struct lock *lk);
78177957Sattiliovoid	 lockdestroy(struct lock *lk);
79211531Sjhbvoid	 lockdisablerecurse(struct lock *lk);
80271161Skibvoid	 lockdisableshare(struct lock *lk);
81177957Sattiliovoid	 lockinit(struct lock *lk, int prio, const char *wmesg, int timo,
82177957Sattilio	    int flags);
83177957Sattilio#ifdef DDB
84177957Sattilioint	 lockmgr_chain(struct thread *td, struct thread **ownerp);
8542900Seivind#endif
86227588Spjdvoid	 lockmgr_printinfo(const struct lock *lk);
87227588Spjdint	 lockstatus(const struct lock *lk);
88164159Skmacy
89177957Sattilio/*
90177957Sattilio * As far as the ilk can be a static NULL pointer these functions need a
91177957Sattilio * strict prototype in order to safely use the lock_object member.
92177957Sattilio */
93177957Sattiliostatic __inline int
94177957Sattilio_lockmgr_args(struct lock *lk, u_int flags, struct mtx *ilk, const char *wmesg,
95177957Sattilio    int prio, int timo, const char *file, int line)
96177957Sattilio{
97176715Sattilio
98177957Sattilio	return (__lockmgr_args(lk, flags, (ilk != NULL) ? &ilk->lock_object :
99177957Sattilio	    NULL, wmesg, prio, timo, file, line));
100177957Sattilio}
101176715Sattilio
102177957Sattiliostatic __inline int
103177957Sattilio_lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk,
104177957Sattilio    const char *wmesg, int prio, int timo, const char *file, int line)
105177957Sattilio{
106177957Sattilio
107177957Sattilio	return (__lockmgr_args(lk, flags, (ilk != NULL) ? &ilk->lock_object :
108177957Sattilio	    NULL, wmesg, prio, timo, file, line));
109177957Sattilio}
110177957Sattilio
11124269Speter/*
112177957Sattilio * Define aliases in order to complete lockmgr KPI.
11324269Speter */
114177957Sattilio#define	lockmgr(lk, flags, ilk)						\
115177957Sattilio	_lockmgr_args((lk), (flags), (ilk), LK_WMESG_DEFAULT,		\
116177957Sattilio	    LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, LOCK_FILE, LOCK_LINE)
117177957Sattilio#define	lockmgr_args(lk, flags, ilk, wmesg, prio, timo)			\
118177957Sattilio	_lockmgr_args((lk), (flags), (ilk), (wmesg), (prio), (timo),	\
119177957Sattilio	    LOCK_FILE, LOCK_LINE)
120177957Sattilio#define	lockmgr_args_rw(lk, flags, ilk, wmesg, prio, timo)		\
121177957Sattilio	_lockmgr_args_rw((lk), (flags), (ilk), (wmesg), (prio), (timo),	\
122177957Sattilio	    LOCK_FILE, LOCK_LINE)
123177957Sattilio#define	lockmgr_disown(lk)						\
124177957Sattilio	_lockmgr_disown((lk), LOCK_FILE, LOCK_LINE)
125177957Sattilio#define	lockmgr_recursed(lk)						\
126177957Sattilio	((lk)->lk_recurse != 0)
127177957Sattilio#define	lockmgr_rw(lk, flags, ilk)					\
128177957Sattilio	_lockmgr_args_rw((lk), (flags), (ilk), LK_WMESG_DEFAULT,	\
129177957Sattilio	    LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, LOCK_FILE, LOCK_LINE)
130177957Sattilio#define	lockmgr_waiters(lk)						\
131177957Sattilio	((lk)->lk_lock & LK_ALL_WAITERS)
132177957Sattilio#ifdef INVARIANTS
133177957Sattilio#define	lockmgr_assert(lk, what)					\
134177957Sattilio	_lockmgr_assert((lk), (what), LOCK_FILE, LOCK_LINE)
135177957Sattilio#else
136177957Sattilio#define	lockmgr_assert(lk, what)
137177957Sattilio#endif
138177957Sattilio
13924269Speter/*
140177957Sattilio * Flags for lockinit().
14124269Speter */
142177982Sattilio#define	LK_INIT_MASK	0x0000FF
143177982Sattilio#define	LK_CANRECURSE	0x000001
144177982Sattilio#define	LK_NODUP	0x000002
145177982Sattilio#define	LK_NOPROFILE	0x000004
146177982Sattilio#define	LK_NOSHARE	0x000008
147177982Sattilio#define	LK_NOWITNESS	0x000010
148177982Sattilio#define	LK_QUIET	0x000020
149194317Sattilio#define	LK_ADAPTIVE	0x000040
150250411Smarcel#define	LK_IS_VNODE	0x000080	/* Tell WITNESS about a VNODE lock */
151177957Sattilio
15224269Speter/*
153177957Sattilio * Additional attributes to be used in lockmgr().
154144220Sjeff */
155177982Sattilio#define	LK_EATTR_MASK	0x00FF00
156177982Sattilio#define	LK_INTERLOCK	0x000100
157177982Sattilio#define	LK_NOWAIT	0x000200
158177982Sattilio#define	LK_RETRY	0x000400
159177982Sattilio#define	LK_SLEEPFAIL	0x000800
160177982Sattilio#define	LK_TIMELOCK	0x001000
161274606Skib#define	LK_NODDLKTREAT	0x002000
162176708Sattilio
163144220Sjeff/*
164177957Sattilio * Operations for lockmgr().
165177957Sattilio */
166177982Sattilio#define	LK_TYPE_MASK	0xFF0000
167177982Sattilio#define	LK_DOWNGRADE	0x010000
168177982Sattilio#define	LK_DRAIN	0x020000
169177982Sattilio#define	LK_EXCLOTHER	0x040000
170177982Sattilio#define	LK_EXCLUSIVE	0x080000
171177982Sattilio#define	LK_RELEASE	0x100000
172177982Sattilio#define	LK_SHARED	0x200000
173177982Sattilio#define	LK_UPGRADE	0x400000
174255940Skib#define	LK_TRYUPGRADE	0x800000
175177957Sattilio
176177957Sattilio#define	LK_TOTAL_MASK	(LK_INIT_MASK | LK_EATTR_MASK | LK_TYPE_MASK)
177177957Sattilio
178177957Sattilio/*
179176708Sattilio * Default values for lockmgr_args().
180176708Sattilio */
181176708Sattilio#define	LK_WMESG_DEFAULT	(NULL)
182177957Sattilio#define	LK_PRIO_DEFAULT		(0)
183176708Sattilio#define	LK_TIMO_DEFAULT		(0)
184176708Sattilio
185176708Sattilio/*
186176249Sattilio * Assertion flags.
187176249Sattilio */
188176249Sattilio#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
189176249Sattilio#define	KA_LOCKED	LA_LOCKED
190176249Sattilio#define	KA_SLOCKED	LA_SLOCKED
191176249Sattilio#define	KA_XLOCKED	LA_XLOCKED
192176249Sattilio#define	KA_UNLOCKED	LA_UNLOCKED
193176249Sattilio#define	KA_RECURSED	LA_RECURSED
194176249Sattilio#define	KA_NOTRECURSED	LA_NOTRECURSED
195176249Sattilio#endif
196144220Sjeff
197176715Sattilio#endif /* _KERNEL */
198176715Sattilio
19976166Smarkm#endif /* !_SYS_LOCKMGR_H_ */
200