sleepqueue.h revision 136445
1126324Sjhb/* 2126324Sjhb * Copyright (c) 2004 John Baldwin <jhb@FreeBSD.org> 3126324Sjhb * All rights reserved. 4126324Sjhb * 5126324Sjhb * Redistribution and use in source and binary forms, with or without 6126324Sjhb * modification, are permitted provided that the following conditions 7126324Sjhb * are met: 8126324Sjhb * 1. Redistributions of source code must retain the above copyright 9126324Sjhb * notice, this list of conditions and the following disclaimer. 10126324Sjhb * 2. Redistributions in binary form must reproduce the above copyright 11126324Sjhb * notice, this list of conditions and the following disclaimer in the 12126324Sjhb * documentation and/or other materials provided with the distribution. 13126324Sjhb * 3. Neither the name of the author nor the names of any co-contributors 14126324Sjhb * may be used to endorse or promote products derived from this software 15126324Sjhb * without specific prior written permission. 16126324Sjhb * 17126324Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18126324Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19126324Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20126324Sjhb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21126324Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22126324Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23126324Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24126324Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25126324Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26126324Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27126324Sjhb * SUCH DAMAGE. 28126324Sjhb * 29126324Sjhb * $FreeBSD: head/sys/sys/sleepqueue.h 136445 2004-10-12 18:36:20Z jhb $ 30126324Sjhb */ 31126324Sjhb 32126324Sjhb#ifndef _SYS_SLEEPQUEUE_H_ 33126324Sjhb#define _SYS_SLEEPQUEUE_H_ 34126324Sjhb 35126324Sjhb/* 36126324Sjhb * Sleep queue interface. Sleep/wakeup and condition variables use a sleep 37126324Sjhb * queue for the queue of threads blocked on a sleep channel. 38126324Sjhb * 39136445Sjhb * A thread calls sleepq_lock() to lock the sleep queue chain associated 40136445Sjhb * with a given wait channel. A thread can then call call sleepq_add() to 41136445Sjhb * add themself onto a sleep queue and call one of the sleepq_wait() 42136445Sjhb * functions to actually go to sleep. If a thread needs to abort a sleep 43136445Sjhb * operation it should call sleepq_release() to unlock the associated sleep 44136445Sjhb * queue chain lock. If the thread also needs to remove itself from a queue 45136445Sjhb * it just enqueued itself on, it can use sleepq_remove() instead. 46126324Sjhb * 47126324Sjhb * If the thread only wishes to sleep for a limited amount of time, it can 48126324Sjhb * call sleepq_set_timeout() after sleepq_add() to setup a timeout. It 49126324Sjhb * should then use one of the sleepq_timedwait() functions to block. 50126324Sjhb * 51126324Sjhb * If the thread wants to the sleep to be interruptible by signals, it can 52126324Sjhb * call sleepq_catch_signals() after sleepq_add(). It should then use 53126324Sjhb * one of the sleepq_wait_sig() functions to block. After the thread has 54126324Sjhb * been resumed, it should call sleepq_calc_signal_retval() to determine 55126324Sjhb * if it should return EINTR or ERESTART passing in the value returned from 56126324Sjhb * the earlier call to sleepq_catch_signals(). 57126324Sjhb * 58126324Sjhb * A thread is normally resumed from a sleep queue by either the 59126324Sjhb * sleepq_signal() or sleepq_broadcast() functions. Sleepq_signal() wakes 60126324Sjhb * the thread with the highest priority that is sleeping on the specified 61126324Sjhb * wait channel. Sleepq_broadcast() wakes all threads that are sleeping 62126324Sjhb * on the specified wait channel. A thread sleeping in an interruptible 63126324Sjhb * sleep can be interrupted by calling sleepq_abort(). A thread can also 64126324Sjhb * be removed from a specified sleep queue using the sleepq_remove() 65136445Sjhb * function. Note that the sleep queue chain must first be locked via 66136445Sjhb * sleepq_lock() when calling sleepq_signal() and sleepq_broadcast(). 67126324Sjhb * 68126324Sjhb * Each thread allocates a sleep queue at thread creation via sleepq_alloc() 69126324Sjhb * and releases it at thread destruction via sleepq_free(). Note that 70126324Sjhb * a sleep queue is not tied to a specific thread and that the sleep queue 71126324Sjhb * released at thread destruction may not be the same sleep queue that the 72126324Sjhb * thread allocated when it was created. 73126324Sjhb * 74126324Sjhb * XXX: Some other parts of the kernel such as ithread sleeping may end up 75126324Sjhb * using this interface as well (death to TDI_IWAIT!) 76126324Sjhb */ 77126324Sjhb 78126324Sjhbstruct mtx; 79126324Sjhbstruct sleepqueue; 80126324Sjhbstruct thread; 81126324Sjhb 82126324Sjhb#ifdef _KERNEL 83126324Sjhb 84134013Sjhb#define SLEEPQ_TYPE 0x0ff /* Mask of sleep queue types. */ 85134013Sjhb#define SLEEPQ_MSLEEP 0x00 /* Used by msleep/wakeup. */ 86134013Sjhb#define SLEEPQ_CONDVAR 0x01 /* Used for a cv. */ 87134013Sjhb#define SLEEPQ_INTERRUPTIBLE 0x100 /* Sleep is interruptible. */ 88126324Sjhb 89126324Sjhbvoid init_sleepqueues(void); 90126324Sjhbvoid sleepq_abort(struct thread *td); 91136445Sjhbvoid sleepq_add(void *, struct mtx *, const char *, int); 92126324Sjhbstruct sleepqueue *sleepq_alloc(void); 93126324Sjhbvoid sleepq_broadcast(void *, int, int); 94126324Sjhbint sleepq_calc_signal_retval(int sig); 95126324Sjhbint sleepq_catch_signals(void *wchan); 96126324Sjhbvoid sleepq_free(struct sleepqueue *); 97136445Sjhbvoid sleepq_lock(void *); 98126324Sjhbstruct sleepqueue *sleepq_lookup(void *); 99126324Sjhbvoid sleepq_release(void *); 100126324Sjhbvoid sleepq_remove(struct thread *, void *); 101126324Sjhbvoid sleepq_signal(void *, int, int); 102126885Sjhbvoid sleepq_set_timeout(void *wchan, int timo); 103131249Sjhbint sleepq_timedwait(void *wchan); 104126324Sjhbint sleepq_timedwait_sig(void *wchan, int signal_caught); 105126324Sjhbvoid sleepq_wait(void *); 106126324Sjhbint sleepq_wait_sig(void *wchan); 107126324Sjhb 108126324Sjhb#endif /* _KERNEL */ 109126324Sjhb#endif /* !_SYS_SLEEPQUEUE_H_ */ 110