lock.h revision 115080
1193326Sed/*
2193326Sed * Copyright (c) 2001, 2003 Daniel Eischen <deischen@freebsd.org>.
3193326Sed * All rights reserved.
4193326Sed *
5193326Sed * Redistribution and use in source and binary forms, with or without
6193326Sed * modification, are permitted provided that the following conditions
7193326Sed * are met:
8193326Sed * 1. Redistributions of source code must retain the above copyright
9193326Sed *    notice, this list of conditions and the following disclaimer.
10198092Srdivacky * 2. Redistributions in binary form must reproduce the above copyright
11193326Sed *    notice, this list of conditions and the following disclaimer in the
12193326Sed *    documentation and/or other materials provided with the distribution.
13193326Sed *
14193326Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
15193326Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16193326Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17198092Srdivacky * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18193326Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19193326Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20193326Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21193326Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22193326Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23203955Srdivacky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24193326Sed * SUCH DAMAGE.
25193326Sed *
26193326Sed * $FreeBSD: head/lib/libkse/sys/lock.h 115080 2003-05-16 19:58:30Z deischen $
27193326Sed */
28193326Sed
29193326Sed#ifndef _LOCK_H_
30193326Sed#define	_LOCK_H_
31193326Sed
32198092Srdivackystruct lockreq;
33193326Sedstruct lockuser;
34193326Sedstruct lock;
35193326Sed
36193326Sedenum lock_type {
37193326Sed	LCK_DEFAULT	= 0x0000,	/* default is FIFO spin locks */
38204643Srdivacky	LCK_PRIORITY	= 0x0001,
39199990Srdivacky	LCK_ADAPTIVE 	= 0x0002	/* call user-supplied handlers */
40199990Srdivacky};
41193326Sed
42193326Sedtypedef void lock_handler_t(struct lock *, struct lockuser *);
43193326Sed
44193326Sedstruct lock {
45193326Sed	struct lockreq	*l_head;
46193326Sed	struct lockreq	*l_tail;	/* only used for priority locks */
47193326Sed	enum lock_type	l_type;
48193326Sed	lock_handler_t	*l_wait;	/* only used for adaptive locks */
49193326Sed	lock_handler_t	*l_wakeup;	/* only used for adaptive locks */
50193326Sed};
51193326Sed
52204643Srdivacky/* Try to make this >= CACHELINESIZE */
53193326Sedstruct lockreq {
54193326Sed	volatile long	lr_locked;	/* lock granted = 0, busy otherwise */
55193326Sed	struct lockuser	*lr_watcher;	/* only used for priority locks */
56193326Sed	struct lockuser	*lr_owner;	/* only used for priority locks */
57198092Srdivacky	long		lr_waiting;	/* non-zero when wakeup needed */
58193326Sed	volatile int	lr_active;	/* non-zero if the lock is last lock for thread */
59193326Sed};
60193326Sed
61198092Srdivackystruct lockuser {
62198092Srdivacky	struct lockreq	*lu_myreq;	/* request to give up/trade */
63198092Srdivacky	struct lockreq	*lu_watchreq;	/* watch this request */
64198092Srdivacky	int		lu_priority;	/* only used for priority locks */
65203955Srdivacky	void		*lu_private1;	/* private{1,2} are initialized to */
66203955Srdivacky	void		*lu_private2;	/*   NULL and can be used by caller */
67203955Srdivacky#define	lu_private	lu_private1
68203955Srdivacky};
69198092Srdivacky
70193326Sed#define	_LCK_INITIALIZER(lck_req)	{ &lck_req, NULL, LCK_DEFAULT, \
71203955Srdivacky					  NULL, NULL }
72203955Srdivacky#define	_LCK_REQUEST_INITIALIZER	{ 0, NULL, NULL, 0 }
73193326Sed
74193326Sed#define	_LCK_BUSY(lu)			((lu)->lu_watchreq->lr_locked != 0)
75198092Srdivacky#define	_LCK_ACTIVE(lu)			((lu)->lu_watchreq->lr_active != 0)
76198092Srdivacky#define	_LCK_GRANTED(lu)		((lu)->lu_watchreq->lr_locked == 0)
77193326Sed
78193326Sed#define	_LCK_SET_PRIVATE(lu, p)		(lu)->lu_private = (void *)(p)
79203955Srdivacky#define	_LCK_GET_PRIVATE(lu)		(lu)->lu_private
80203955Srdivacky#define	_LCK_SET_PRIVATE2(lu, p)	(lu)->lu_private2 = (void *)(p)
81203955Srdivacky#define	_LCK_GET_PRIVATE2(lu)		(lu)->lu_private2
82203955Srdivacky
83193326Sedvoid	_lock_destroy(struct lock *);
84198092Srdivackyint	_lock_init(struct lock *, enum lock_type,
85193326Sed	    lock_handler_t *, lock_handler_t *);
86193326Sedint	_lockuser_init(struct lockuser *lu, void *priv);
87193326Sedvoid	_lockuser_destroy(struct lockuser *lu);
88193326Sedvoid	_lockuser_setactive(struct lockuser *lu, int active);
89193326Sedvoid	_lock_acquire(struct lock *, struct lockuser *, int);
90199482Srdivackyvoid	_lock_release(struct lock *, struct lockuser *);
91193326Sedvoid	_lock_grant(struct lock *, struct lockuser *);
92193326Sed
93202379Srdivacky#endif
94198092Srdivacky