turnstile.h revision 139825
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 139825 2005-01-07 02:29:27Z imp $ 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 * A function can query a turnstile to see if it is empty via 66 * turnstile_empty(). The highest priority thread blocked on a turnstile 67 * can be obtained via turnstile_head(). 68 */ 69 70struct lock_object; 71struct thread; 72struct turnstile; 73 74#ifdef _KERNEL 75 76void init_turnstiles(void); 77void turnstile_adjust(struct thread *, u_char); 78struct turnstile *turnstile_alloc(void); 79void turnstile_broadcast(struct turnstile *); 80void turnstile_claim(struct lock_object *); 81int turnstile_empty(struct turnstile *); 82void turnstile_free(struct turnstile *); 83struct thread *turnstile_head(struct turnstile *); 84void turnstile_lock(struct lock_object *); 85struct turnstile *turnstile_lookup(struct lock_object *); 86void turnstile_release(struct lock_object *); 87int turnstile_signal(struct turnstile *); 88void turnstile_unpend(struct turnstile *); 89void turnstile_wait(struct lock_object *, struct thread *); 90 91#endif /* _KERNEL */ 92#endif /* _SYS_TURNSTILE_H_ */ 93