turnstile.h revision 127951
1/* 2 * Copyright (c) 2002 John Baldwin <jhb@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the author nor the names of any co-contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD: head/sys/sys/turnstile.h 127951 2004-04-06 19:07:21Z jhb $ 30 */ 31 32#ifndef _SYS_TURNSTILE_H_ 33#define _SYS_TURNSTILE_H_ 34 35/* 36 * Turnstile interface. Non-sleepable locks use a turnstile for the 37 * queue of threads blocked on them when they are contested. 38 * 39 * A thread calls turnstile_lookup() to look up the proper turnstile in 40 * the hash table. This function returns a pointer to the turnstile and 41 * locks the associated turnstile chain. A thread calls turnstile_wait() 42 * when the lock is contested to be put on the queue and block. If a 43 * thread needs to retry a lock operation instead of blocking, it should 44 * call turnstile_release() to unlock the associated turnstile chain lock. 45 * 46 * When a lock is released, either turnstile_signal() or turnstile_broadcast() 47 * is called to mark blocked threads for a pending wakeup. 48 * turnstile_signal() marks the highest priority blocked thread while 49 * turnstile_broadcast() marks all blocked threads. The turnstile_signal() 50 * function returns true if the turnstile became empty as a result. After 51 * the higher level code finishes releasing the lock, turnstile_unpend() 52 * must be called to wakeup the pending thread(s). 53 * 54 * When a lock is acquired that already has at least one thread contested 55 * on it, the new owner of the lock must claim ownership of the turnstile 56 * via turnstile_claim(). 57 * 58 * Each thread allocates a turnstile at thread creation via turnstile_alloc() 59 * and releases it at thread destruction via turnstile_free(). Note that 60 * a turnstile is not tied to a specific thread and that the turnstile 61 * released at thread destruction may not be the same turnstile that the 62 * thread allocated when it was created. 63 * 64 * A function can query a turnstile to see if it is empty via 65 * turnstile_empty(). The highest priority thread blocked on a turnstile 66 * can be obtained via turnstile_head(). 67 */ 68 69struct lock_object; 70struct thread; 71struct turnstile; 72 73#ifdef _KERNEL 74 75void init_turnstiles(void); 76struct turnstile *turnstile_alloc(void); 77void turnstile_claim(struct turnstile *); 78void turnstile_free(struct turnstile *); 79struct turnstile *turnstile_lookup(struct lock_object *); 80void turnstile_release(struct lock_object *); 81int turnstile_signal(struct turnstile *); 82void turnstile_unpend(struct turnstile *); 83void turnstile_wait(struct turnstile *, struct lock_object *, 84 struct thread *); 85void turnstile_broadcast(struct turnstile *); 86struct thread *turnstile_head(struct turnstile *); 87int turnstile_empty(struct turnstile *); 88 89#endif /* _KERNEL */ 90#endif /* _SYS_TURNSTILE_H_ */ 91