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: stable/11/sys/sys/lockmgr.h 315375 2017-03-16 06:14:33Z mjg $
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);
71315375Smjgint	 lockmgr_lock_fast_path(struct lock *lk, u_int flags,
72315375Smjg	    struct lock_object *ilk, const char *file, int line);
73315375Smjgint	 lockmgr_unlock_fast_path(struct lock *lk, u_int flags,
74315375Smjg	    struct lock_object *ilk);
75177957Sattilio#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
76227588Spjdvoid	 _lockmgr_assert(const struct lock *lk, int what, const char *file, int line);
77177957Sattilio#endif
78177957Sattiliovoid	 _lockmgr_disown(struct lock *lk, const char *file, int line);
79164159Skmacy
80211531Sjhbvoid	 lockallowrecurse(struct lock *lk);
81211531Sjhbvoid	 lockallowshare(struct lock *lk);
82177957Sattiliovoid	 lockdestroy(struct lock *lk);
83211531Sjhbvoid	 lockdisablerecurse(struct lock *lk);
84270795Skibvoid	 lockdisableshare(struct lock *lk);
85177957Sattiliovoid	 lockinit(struct lock *lk, int prio, const char *wmesg, int timo,
86177957Sattilio	    int flags);
87177957Sattilio#ifdef DDB
88177957Sattilioint	 lockmgr_chain(struct thread *td, struct thread **ownerp);
8942900Seivind#endif
90227588Spjdvoid	 lockmgr_printinfo(const struct lock *lk);
91227588Spjdint	 lockstatus(const struct lock *lk);
92164159Skmacy
93177957Sattilio/*
94177957Sattilio * As far as the ilk can be a static NULL pointer these functions need a
95177957Sattilio * strict prototype in order to safely use the lock_object member.
96177957Sattilio */
97177957Sattiliostatic __inline int
98177957Sattilio_lockmgr_args(struct lock *lk, u_int flags, struct mtx *ilk, const char *wmesg,
99177957Sattilio    int prio, int timo, const char *file, int line)
100177957Sattilio{
101176715Sattilio
102177957Sattilio	return (__lockmgr_args(lk, flags, (ilk != NULL) ? &ilk->lock_object :
103177957Sattilio	    NULL, wmesg, prio, timo, file, line));
104177957Sattilio}
105176715Sattilio
106177957Sattiliostatic __inline int
107177957Sattilio_lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk,
108177957Sattilio    const char *wmesg, int prio, int timo, const char *file, int line)
109177957Sattilio{
110177957Sattilio
111177957Sattilio	return (__lockmgr_args(lk, flags, (ilk != NULL) ? &ilk->lock_object :
112177957Sattilio	    NULL, wmesg, prio, timo, file, line));
113177957Sattilio}
114177957Sattilio
11524269Speter/*
116177957Sattilio * Define aliases in order to complete lockmgr KPI.
11724269Speter */
118177957Sattilio#define	lockmgr(lk, flags, ilk)						\
119177957Sattilio	_lockmgr_args((lk), (flags), (ilk), LK_WMESG_DEFAULT,		\
120177957Sattilio	    LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, LOCK_FILE, LOCK_LINE)
121177957Sattilio#define	lockmgr_args(lk, flags, ilk, wmesg, prio, timo)			\
122177957Sattilio	_lockmgr_args((lk), (flags), (ilk), (wmesg), (prio), (timo),	\
123177957Sattilio	    LOCK_FILE, LOCK_LINE)
124177957Sattilio#define	lockmgr_args_rw(lk, flags, ilk, wmesg, prio, timo)		\
125177957Sattilio	_lockmgr_args_rw((lk), (flags), (ilk), (wmesg), (prio), (timo),	\
126177957Sattilio	    LOCK_FILE, LOCK_LINE)
127177957Sattilio#define	lockmgr_disown(lk)						\
128177957Sattilio	_lockmgr_disown((lk), LOCK_FILE, LOCK_LINE)
129177957Sattilio#define	lockmgr_recursed(lk)						\
130177957Sattilio	((lk)->lk_recurse != 0)
131177957Sattilio#define	lockmgr_rw(lk, flags, ilk)					\
132177957Sattilio	_lockmgr_args_rw((lk), (flags), (ilk), LK_WMESG_DEFAULT,	\
133177957Sattilio	    LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, LOCK_FILE, LOCK_LINE)
134177957Sattilio#define	lockmgr_waiters(lk)						\
135177957Sattilio	((lk)->lk_lock & LK_ALL_WAITERS)
136177957Sattilio#ifdef INVARIANTS
137177957Sattilio#define	lockmgr_assert(lk, what)					\
138177957Sattilio	_lockmgr_assert((lk), (what), LOCK_FILE, LOCK_LINE)
139177957Sattilio#else
140177957Sattilio#define	lockmgr_assert(lk, what)
141177957Sattilio#endif
142177957Sattilio
14324269Speter/*
144177957Sattilio * Flags for lockinit().
14524269Speter */
146177982Sattilio#define	LK_INIT_MASK	0x0000FF
147177982Sattilio#define	LK_CANRECURSE	0x000001
148177982Sattilio#define	LK_NODUP	0x000002
149177982Sattilio#define	LK_NOPROFILE	0x000004
150177982Sattilio#define	LK_NOSHARE	0x000008
151177982Sattilio#define	LK_NOWITNESS	0x000010
152177982Sattilio#define	LK_QUIET	0x000020
153194317Sattilio#define	LK_ADAPTIVE	0x000040
154250411Smarcel#define	LK_IS_VNODE	0x000080	/* Tell WITNESS about a VNODE lock */
155177957Sattilio
15624269Speter/*
157177957Sattilio * Additional attributes to be used in lockmgr().
158144220Sjeff */
159177982Sattilio#define	LK_EATTR_MASK	0x00FF00
160177982Sattilio#define	LK_INTERLOCK	0x000100
161177982Sattilio#define	LK_NOWAIT	0x000200
162177982Sattilio#define	LK_RETRY	0x000400
163177982Sattilio#define	LK_SLEEPFAIL	0x000800
164177982Sattilio#define	LK_TIMELOCK	0x001000
165273966Skib#define	LK_NODDLKTREAT	0x002000
166285632Smjg#define	LK_VNHELD	0x004000
167176708Sattilio
168144220Sjeff/*
169177957Sattilio * Operations for lockmgr().
170177957Sattilio */
171177982Sattilio#define	LK_TYPE_MASK	0xFF0000
172177982Sattilio#define	LK_DOWNGRADE	0x010000
173177982Sattilio#define	LK_DRAIN	0x020000
174177982Sattilio#define	LK_EXCLOTHER	0x040000
175177982Sattilio#define	LK_EXCLUSIVE	0x080000
176177982Sattilio#define	LK_RELEASE	0x100000
177177982Sattilio#define	LK_SHARED	0x200000
178177982Sattilio#define	LK_UPGRADE	0x400000
179255940Skib#define	LK_TRYUPGRADE	0x800000
180177957Sattilio
181177957Sattilio#define	LK_TOTAL_MASK	(LK_INIT_MASK | LK_EATTR_MASK | LK_TYPE_MASK)
182177957Sattilio
183177957Sattilio/*
184176708Sattilio * Default values for lockmgr_args().
185176708Sattilio */
186176708Sattilio#define	LK_WMESG_DEFAULT	(NULL)
187177957Sattilio#define	LK_PRIO_DEFAULT		(0)
188176708Sattilio#define	LK_TIMO_DEFAULT		(0)
189176708Sattilio
190176708Sattilio/*
191176249Sattilio * Assertion flags.
192176249Sattilio */
193176249Sattilio#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
194176249Sattilio#define	KA_LOCKED	LA_LOCKED
195176249Sattilio#define	KA_SLOCKED	LA_SLOCKED
196176249Sattilio#define	KA_XLOCKED	LA_XLOCKED
197176249Sattilio#define	KA_UNLOCKED	LA_UNLOCKED
198176249Sattilio#define	KA_RECURSED	LA_RECURSED
199176249Sattilio#define	KA_NOTRECURSED	LA_NOTRECURSED
200176249Sattilio#endif
201144220Sjeff
202176715Sattilio#endif /* _KERNEL */
203176715Sattilio
20476166Smarkm#endif /* !_SYS_LOCKMGR_H_ */
205