sx.h revision 161337
1135446Strhodes/*- 2224092Sdougb * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. All rights reserved. 3135446Strhodes * 4135446Strhodes * Redistribution and use in source and binary forms, with or without 5193149Sdougb * modification, are permitted provided that the following conditions 6135446Strhodes * are met: 7135446Strhodes * 1. Redistributions of source code must retain the above copyright 8135446Strhodes * notice(s), this list of conditions and the following disclaimer as 9135446Strhodes * the first lines of this file unmodified other than the possible 10135446Strhodes * addition of one or more copyright notices. 11135446Strhodes * 2. Redistributions in binary form must reproduce the above copyright 12135446Strhodes * notice(s), this list of conditions and the following disclaimer in the 13135446Strhodes * documentation and/or other materials provided with the distribution. 14135446Strhodes * 15135446Strhodes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 16135446Strhodes * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17135446Strhodes * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18234010Sdougb * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 19135446Strhodes * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20135446Strhodes * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21135446Strhodes * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22135446Strhodes * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23170222Sdougb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24135446Strhodes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25135446Strhodes * DAMAGE. 26135446Strhodes * 27135446Strhodes * $FreeBSD: head/sys/sys/sx.h 161337 2006-08-15 18:29:01Z jhb $ 28135446Strhodes */ 29135446Strhodes 30193149Sdougb#ifndef _SYS_SX_H_ 31224092Sdougb#define _SYS_SX_H_ 32170222Sdougb 33170222Sdougb#include <sys/queue.h> 34135446Strhodes#include <sys/_lock.h> 35135446Strhodes#include <sys/condvar.h> /* XXX */ 36135446Strhodes 37135446Strhodesstruct sx { 38135446Strhodes struct lock_object sx_object; /* Common lock properties. */ 39135446Strhodes struct mtx *sx_lock; /* General protection lock. */ 40135446Strhodes int sx_cnt; /* -1: xlock, > 0: slock count. */ 41135446Strhodes struct cv sx_shrd_cv; /* slock waiters. */ 42135446Strhodes int sx_shrd_wcnt; /* Number of slock waiters. */ 43135446Strhodes struct cv sx_excl_cv; /* xlock waiters. */ 44135446Strhodes int sx_excl_wcnt; /* Number of xlock waiters. */ 45224092Sdougb struct thread *sx_xholder; /* Thread presently holding xlock. */ 46170222Sdougb}; 47135446Strhodes 48135446Strhodes#ifdef _KERNEL 49135446Strhodesvoid sx_sysinit(void *arg); 50135446Strhodesvoid sx_init(struct sx *sx, const char *description); 51135446Strhodesvoid sx_destroy(struct sx *sx); 52135446Strhodesvoid _sx_slock(struct sx *sx, const char *file, int line); 53135446Strhodesvoid _sx_xlock(struct sx *sx, const char *file, int line); 54135446Strhodesint _sx_try_slock(struct sx *sx, const char *file, int line); 55135446Strhodesint _sx_try_xlock(struct sx *sx, const char *file, int line); 56135446Strhodesvoid _sx_sunlock(struct sx *sx, const char *file, int line); 57135446Strhodesvoid _sx_xunlock(struct sx *sx, const char *file, int line); 58135446Strhodesint _sx_try_upgrade(struct sx *sx, const char *file, int line); 59135446Strhodesvoid _sx_downgrade(struct sx *sx, const char *file, int line); 60135446Strhodes#ifdef INVARIANT_SUPPORT 61135446Strhodesvoid _sx_assert(struct sx *sx, int what, const char *file, int line); 62135446Strhodes#endif 63135446Strhodes#ifdef DDB 64135446Strhodesint sx_chain(struct thread *td, struct thread **ownerp); 65135446Strhodes#endif 66135446Strhodes 67135446Strhodesstruct sx_args { 68135446Strhodes struct sx *sa_sx; 69170222Sdougb const char *sa_desc; 70135446Strhodes}; 71135446Strhodes 72170222Sdougb#define SX_SYSINIT(name, sxa, desc) \ 73170222Sdougb static struct sx_args name##_args = { \ 74170222Sdougb (sxa), \ 75170222Sdougb (desc) \ 76170222Sdougb }; \ 77135446Strhodes SYSINIT(name##_sx_sysinit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ 78135446Strhodes sx_sysinit, &name##_args); \ 79135446Strhodes SYSUNINIT(name##_sx_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \ 80135446Strhodes sx_destroy, (sxa)) 81135446Strhodes 82135446Strhodes#define sx_xlocked(sx) ((sx)->sx_cnt < 0 && (sx)->sx_xholder == curthread) 83135446Strhodes#define sx_slock(sx) _sx_slock((sx), LOCK_FILE, LOCK_LINE) 84135446Strhodes#define sx_xlock(sx) _sx_xlock((sx), LOCK_FILE, LOCK_LINE) 85135446Strhodes#define sx_try_slock(sx) _sx_try_slock((sx), LOCK_FILE, LOCK_LINE) 86135446Strhodes#define sx_try_xlock(sx) _sx_try_xlock((sx), LOCK_FILE, LOCK_LINE) 87135446Strhodes#define sx_sunlock(sx) _sx_sunlock((sx), LOCK_FILE, LOCK_LINE) 88135446Strhodes#define sx_xunlock(sx) _sx_xunlock((sx), LOCK_FILE, LOCK_LINE) 89135446Strhodes#define sx_try_upgrade(sx) _sx_try_upgrade((sx), LOCK_FILE, LOCK_LINE) 90135446Strhodes#define sx_downgrade(sx) _sx_downgrade((sx), LOCK_FILE, LOCK_LINE) 91135446Strhodes#define sx_unlock(sx) do { \ 92135446Strhodes if (sx_xlocked(sx)) \ 93135446Strhodes sx_xunlock(sx); \ 94135446Strhodes else \ 95135446Strhodes sx_sunlock(sx); \ 96135446Strhodes} while (0) 97135446Strhodes 98170222Sdougb#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT) 99135446Strhodes#define SX_LOCKED LA_LOCKED 100170222Sdougb#define SX_SLOCKED LA_SLOCKED 101170222Sdougb#define SX_XLOCKED LA_XLOCKED 102135446Strhodes#define SX_UNLOCKED LA_UNLOCKED 103170222Sdougb#endif 104170222Sdougb 105170222Sdougb#ifdef INVARIANTS 106224092Sdougb#define sx_assert(sx, what) _sx_assert((sx), (what), LOCK_FILE, LOCK_LINE) 107170222Sdougb#else 108170222Sdougb#define sx_assert(sx, what) 109170222Sdougb#endif 110170222Sdougb 111170222Sdougb#endif /* _KERNEL */ 112170222Sdougb 113170222Sdougb#endif /* !_SYS_SX_H_ */ 114170222Sdougb