sx.h revision 74912
173782Sjasone/*
273782Sjasone * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>.  All rights reserved.
373782Sjasone *
473782Sjasone * Redistribution and use in source and binary forms, with or without
573782Sjasone * modification, are permitted provided that the following conditions
673782Sjasone * are met:
773782Sjasone * 1. Redistributions of source code must retain the above copyright
873782Sjasone *    notice(s), this list of conditions and the following disclaimer as
973782Sjasone *    the first lines of this file unmodified other than the possible
1073782Sjasone *    addition of one or more copyright notices.
1173782Sjasone * 2. Redistributions in binary form must reproduce the above copyright
1273782Sjasone *    notice(s), this list of conditions and the following disclaimer in the
1373782Sjasone *    documentation and/or other materials provided with the distribution.
1473782Sjasone *
1573782Sjasone * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
1673782Sjasone * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1773782Sjasone * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1873782Sjasone * DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
1973782Sjasone * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2073782Sjasone * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2173782Sjasone * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2273782Sjasone * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2373782Sjasone * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2473782Sjasone * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
2573782Sjasone * DAMAGE.
2673782Sjasone *
2773782Sjasone * $FreeBSD: head/sys/sys/sx.h 74912 2001-03-28 09:03:24Z jhb $
2873782Sjasone */
2973782Sjasone
3073782Sjasone#ifndef	_SYS_SX_H_
3173782Sjasone#define	_SYS_SX_H_
3273782Sjasone
3373782Sjasone#ifndef	LOCORE
3474912Sjhb#include <sys/lock.h>		/* XXX */
3574912Sjhb#include <sys/mutex.h>		/* XXX */
3674912Sjhb#include <sys/condvar.h>	/* XXX */
3773782Sjasone
3874912Sjhbstruct lock_object;
3974912Sjhb
4073782Sjasonestruct sx {
4174912Sjhb	struct lock_object sx_object;	/* Common lock properties. */
4273863Sbmilekic	struct mtx	sx_lock;	/* General protection lock. */
4373782Sjasone	int		sx_cnt;		/* -1: xlock, > 0: slock count. */
4473782Sjasone	struct cv	sx_shrd_cv;	/* slock waiters. */
4573782Sjasone	int		sx_shrd_wcnt;	/* Number of slock waiters. */
4673782Sjasone	struct cv	sx_excl_cv;	/* xlock waiters. */
4773782Sjasone	int		sx_excl_wcnt;	/* Number of xlock waiters. */
4873863Sbmilekic	struct proc	*sx_xholder;	/* Thread presently holding xlock. */
4973782Sjasone};
5073782Sjasone
5173782Sjasone#ifdef _KERNEL
5273782Sjasonevoid	sx_init(struct sx *sx, const char *description);
5373782Sjasonevoid	sx_destroy(struct sx *sx);
5474912Sjhbvoid	_sx_slock(struct sx *sx, const char *file, int line);
5574912Sjhbvoid	_sx_xlock(struct sx *sx, const char *file, int line);
5674912Sjhbvoid	_sx_sunlock(struct sx *sx, const char *file, int line);
5774912Sjhbvoid	_sx_xunlock(struct sx *sx, const char *file, int line);
5873782Sjasone
5974912Sjhb#define	sx_slock(sx)	_sx_slock((sx), __FILE__, __LINE__)
6074912Sjhb#define	sx_xlock(sx)	_sx_xlock((sx), __FILE__, __LINE__)
6174912Sjhb#define	sx_sunlock(sx)	_sx_sunlock((sx), __FILE__, __LINE__)
6274912Sjhb#define	sx_xunlock(sx)	_sx_xunlock((sx), __FILE__, __LINE__)
6374912Sjhb
6473782Sjasone#ifdef INVARIANTS
6573782Sjasone/*
6673782Sjasone * SX_ASSERT_SLOCKED() can only detect that at least *some* thread owns an
6773782Sjasone * slock, but it cannot guarantee that *this* thread owns an slock.
6873782Sjasone */
6973782Sjasone#define	SX_ASSERT_SLOCKED(sx) do {					\
7073782Sjasone	mtx_lock(&(sx)->sx_lock);					\
7173901Sjhb	_SX_ASSERT_SLOCKED((sx));					\
7273901Sjhb	mtx_unlock(&(sx)->sx_lock);					\
7373901Sjhb} while (0)
7473901Sjhb#define	_SX_ASSERT_SLOCKED(sx) do {					\
7573863Sbmilekic	KASSERT(((sx)->sx_cnt > 0), ("%s: lacking slock %s\n",		\
7674912Sjhb	    __FUNCTION__, (sx)->sx_object.lo_name));			\
7773782Sjasone} while (0)
7873863Sbmilekic
7973782Sjasone/*
8073863Sbmilekic * SX_ASSERT_XLOCKED() detects and guarantees that *we* own the xlock.
8173782Sjasone */
8273782Sjasone#define	SX_ASSERT_XLOCKED(sx) do {					\
8373782Sjasone	mtx_lock(&(sx)->sx_lock);					\
8473901Sjhb	_SX_ASSERT_XLOCKED((sx));					\
8573901Sjhb	mtx_unlock(&(sx)->sx_lock);					\
8673901Sjhb} while (0)
8773901Sjhb#define	_SX_ASSERT_XLOCKED(sx) do {					\
8873863Sbmilekic	KASSERT(((sx)->sx_xholder == curproc),				\
8973863Sbmilekic	    ("%s: thread %p lacking xlock %s\n", __FUNCTION__,		\
9074912Sjhb	    curproc, (sx)->sx_object.lo_name));				\
9173782Sjasone} while (0)
9273863Sbmilekic
9373782Sjasone#else	/* INVARIANTS */
9473782Sjasone#define	SX_ASSERT_SLOCKED(sx)
9573874Sdwmalone#define	SX_ASSERT_XLOCKED(sx)
9673901Sjhb#define	_SX_ASSERT_SLOCKED(sx)
9773901Sjhb#define	_SX_ASSERT_XLOCKED(sx)
9873782Sjasone#endif	/* INVARIANTS */
9973782Sjasone
10073782Sjasone#endif	/* _KERNEL */
10173782Sjasone#endif	/* !LOCORE */
10273782Sjasone#endif	/* _SYS_SX_H_ */
103