turnstile.h revision 157844
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 157844 2006-04-18 18:16:54Z 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_lock() to lock the turnstile chain associated 40 * with a given lock. A thread calls turnstile_wait() when the lock is 41 * contested to be put on the queue and block. If a thread needs to retry 42 * a lock operation instead of blocking, it should call turnstile_release() 43 * to unlock the associated turnstile chain lock. 44 * 45 * When a lock is released, the thread calls turnstile_lookup() to loop 46 * up the turnstile associated with the given lock in the hash table. Then 47 * it calls either turnstile_signal() or turnstile_broadcast() to mark 48 * blocked threads for a pending wakeup. turnstile_signal() marks the 49 * highest priority blocked thread while turnstile_broadcast() marks all 50 * blocked threads. The turnstile_signal() function returns true if the 51 * turnstile became empty as a result. After the higher level code finishes 52 * releasing the lock, turnstile_unpend() must be called to wake up the 53 * pending thread(s). 54 * 55 * When a lock is acquired that already has at least one thread contested 56 * on it, the new owner of the lock must claim ownership of the turnstile 57 * via turnstile_claim(). 58 * 59 * Each thread allocates a turnstile at thread creation via turnstile_alloc() 60 * and releases it at thread destruction via turnstile_free(). Note that 61 * a turnstile is not tied to a specific thread and that the turnstile 62 * released at thread destruction may not be the same turnstile that the 63 * thread allocated when it was created. 64 * 65 * The highest priority thread blocked on a turnstile can be obtained via 66 * turnstile_head(). 67 */ 68 69struct lock_object; 70struct thread; 71struct turnstile; 72 73#ifdef _KERNEL 74 75/* Which queue to block on or which queue to wakeup one or more threads from. */ 76#define TS_EXCLUSIVE_QUEUE 0 77#define TS_SHARED_QUEUE 1 78 79/* The type of lock currently held. */ 80#define TS_EXCLUSIVE_LOCK TS_EXCLUSIVE_QUEUE 81#define TS_SHARED_LOCK TS_SHARED_QUEUE 82 83void init_turnstiles(void); 84void turnstile_adjust(struct thread *, u_char); 85struct turnstile *turnstile_alloc(void); 86void turnstile_broadcast(struct turnstile *, int); 87void turnstile_claim(struct lock_object *); 88void turnstile_disown(struct turnstile *); 89int turnstile_empty(struct turnstile *ts, int queue); 90void turnstile_free(struct turnstile *); 91struct thread *turnstile_head(struct turnstile *, int); 92void turnstile_lock(struct lock_object *); 93struct turnstile *turnstile_lookup(struct lock_object *); 94void turnstile_release(struct lock_object *); 95int turnstile_signal(struct turnstile *, int); 96void turnstile_unpend(struct turnstile *, int); 97void turnstile_wait(struct lock_object *, struct thread *, int); 98 99#endif /* _KERNEL */ 100#endif /* _SYS_TURNSTILE_H_ */ 101