From 3b9c3dff42a3c0ea7fc114e338e456cb79d6b757 Mon Sep 17 00:00:00 2001 From: jhb Date: Fri, 12 Mar 2004 19:07:18 +0000 Subject: Rewrite sleepqueue manpage to catch up to the new sleep queue interface. --- share/man/man9/Makefile | 20 ++- share/man/man9/sleepqueue.9 | 303 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 272 insertions(+), 51 deletions(-) diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 0d09ff3..471c1e0 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -772,9 +772,23 @@ MLINKS+=sleep.9 msleep.9 \ sleep.9 tsleep.9 \ sleep.9 wakeup.9 \ sleep.9 wakeup_one.9 -MLINKS+=sleepqueue.9 endtsleep.9 \ - sleepqueue.9 sleepinit.9 \ - sleepqueue.9 unsleep.9 +MLINKS+=sleepqueue.9 init_sleepqueues.9 \ + sleepqueue.9 sleepq_abort.9 \ + sleepqueue.9 sleepq_add.9 \ + sleepqueue.9 sleepq_alloc.9 \ + sleepqueue.9 sleepq_broadcast.9 \ + sleepqueue.9 sleepq_calc_signal_retval.9 \ + sleepqueue.9 sleepq_catch_signals.9 \ + sleepqueue.9 sleepq_free.9 \ + sleepqueue.9 sleepq_lookup.9 \ + sleepqueue.9 sleepq_release.9 \ + sleepqueue.9 sleepq_remove.9 \ + sleepqueue.9 sleepq_signal.9 \ + sleepqueue.9 sleepq_set_timeout.9 \ + sleepqueue.9 sleepq_timedwait.9 \ + sleepqueue.9 sleepq_timedwait_sig.9 \ + sleepqueue.9 sleepq_wait.9 \ + sleepqueue.9 sleepq_wait_sig.9 MLINKS+=spl.9 spl0.9 \ spl.9 splbio.9 \ spl.9 splclock.9 \ diff --git a/share/man/man9/sleepqueue.9 b/share/man/man9/sleepqueue.9 index 9f30f25..f5fefe0 100644 --- a/share/man/man9/sleepqueue.9 +++ b/share/man/man9/sleepqueue.9 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2000-2001 John H. Baldwin +.\" Copyright (c) 2000-2004 John H. Baldwin .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -23,67 +23,274 @@ .\" .\" $FreeBSD$ .\" -.Dd November 3, 2000 +.Dd March 10, 2004 .Dt SLEEPQUEUE 9 .Os .Sh NAME -.Nm endtsleep , -.Nm sleepinit , -.Nm unsleep -.Nd manage the queues of sleeping processes +.Nm init_sleepqueues , +.Nm sleepq_abort , +.Nm sleepq_add , +.Nm sleepq_alloc , +.Nm sleepq_broadcast , +.Nm sleepq_calc_signal_retval , +.Nm sleepq_catch_signals , +.Nm sleepq_free , +.Nm sleepq_lookup , +.Nm sleepq_release , +.Nm sleepq_remove , +.Nm sleepq_signal , +.Nm sleepq_set_timeout , +.Nm sleepq_timedwait , +.Nm sleepq_timedwait_sig , +.Nm sleepq_wait , +.Nm sleepq_wait_sig +.Nd manage the queues of sleeping threads .Sh SYNOPSIS .In sys/param.h -.In sys/proc.h +.In sys/sleepqueue.h .Ft void -.Fn endtsleep "void *arg" +.Fn init_sleepqueues "void" .Ft void -.Fn sleepinit "void" +.Fn sleepq_abort "struct thread *td" .Ft void -.Fn unsleep "struct thread *td" +.Fn sleepq_add "struct sleepqueue *sq" "void *wchan" "struct mtx *lock" "const char *wmesg" "int flags" +.Ft struct sleepqueue * +.Fn sleepq_alloc "void" +.Ft void +.Fn sleepq_broadcast "void *wchan" "int flags" "int pri" +.Ft int +.Fn sleepq_calc_signal_retval "int sig" +.Ft int +.Fn sleepq_catch_signals "void *wchan" +.Ft void +.Fn sleepq_free "struct sleepqueue *sq" +.Ft struct sleepqueue * +.Fn sleepq_lookup "void *wchan" +.Ft void +.Fn sleepq_release "void *wchan" +.Ft void +.Fn sleepq_remove "struct thread *td" "void *wchan" +.Ft void +.Fn sleepq_signal "void *wchan" "int flags" "int pri" +.Ft void +.Fn sleepq_set_timeout "void *wchan" "int timo" +.Ft int +.Fn sleepq_timedwait "void *wchan" "int signal_caught" +.Ft int +.Fn sleepq_timedwait_sig "void *wchan" "int signal_caught" +.Ft void +.Fn sleepq_wait "void *wchan" +.Ft int +.Fn sleepq_wait_sig "void *wchan" .Sh DESCRIPTION -The sleep queues used by -.Xr msleep 9 -and friends are stored in a hash array. -The address of the wait channel is used to generate an index into the array. -Each entry in the array is a queue of processes that are sleeping on wait -channels that hash to that index. -.Xr msleep 9 -places processes into their appropriate queues directly. -To handle timeouts, the -.Fn endtsleep -function is registered as a -.Xr timeout 9 . -When the process is woken by either -.Fn wakeup +Sleep queues provide a mechanism for suspending execution of a thread until +some condition is met. +Each queue is associated with a specific wait channel when it is active, +and only one queue may be associated with a wait channel at any given point +in time. +An active queue holds a list of threads that are blocked on the associated +wait channel. +Threads that are not blocked on a wait channel have an associated inactive +sleep queue. +When a thread blocks on a wait channel it donates its inactive sleep queue +to the wait channel. +When a thread is resumed, +the wait channel that it was blocked on gives it an inactive sleep queue for +later use. +The +.Fn sleepq_alloc +allocates an inactive sleep queue and is used to assign a sleep queue to a +thread during thread creation. +The +.Fn sleepq_free +function frees the resources associated with an inactive sleep queue and is +used to free a queue during thread destruction. +.Pp +Active sleep queues are stored in a hash table hashed on the addresses pointed +to by wait channels. +Each bucket in the hash table contains a sleep queue chain. +A sleep queue chain contains a spin mutex and a list of sleep queues that hash +to that specific chain. +Active sleep queues are protected by their chain's spin mutex. +The +.Fn init_sleepqueues +function initializes the hash table of sleep queue chains. +.Pp +The +.Fn sleepq_lookup +function locks the sleep queue chain associated with +.Fa wchan +and returns a pointer to the current active sleep queue for that wait channel or -.Fn wakeup_one , -the timeout is revoked via -.Xr untimeout 9 . -If the process is not awakened soon enough, then -.Fn endtsleep -is called with -.Fa arg -pointing to the -.Vt "struct proc" -of the process that timed out. -.Fn endtsleep -undoes the sleep and makes the process runnable if it is in the -.Dv SSLEEP -state. -The sleep queues and the hash array are protected internally by the -.Va sched_lock -mutex. +.Dv NULL +if there currently is not an active sleep queue. +The +.Fn sleepq_release +function unlocks the sleep queue chain associated with +.Fn wchan +and is primarily useful when aborting a pending sleep request before one of +the wait functions is called. +.Pp +The +.Fn sleepq_add +function places the current thread on the sleep queue associated with the +wait channel +.Fa wchan . +The associated sleep queue chain must be locked by a call to +.Fn sleepq_lookup +when this function is called and its return value should be passed as the +.Fa sq +parameter. +If a mutex is specified via the +.Fa lock +argument, then the sleep queue code will perform extra checks to ensure that +the mutex is held for all threads sleeping on +.Fa wchan . +The +.Fa wmesg +parameter should be a short description of +.Fa wchan . +The +.Fa flags +parameter currently only specifies the type of sleep queue being slept on. +A value of +.Dv 0 +indicates a sleep queue used by +.Xr msleep 9 +and a value of +.Dv SLEEPQ_CONDVAR +indicates a sleep queue used by +.Xr condvar 9 . +A timeout on the sleep may be specified by calling +.Fn sleepq_set_timeout +after +.Fn sleepq_add . +The +.Fa wchan +parameter should be the same value from the preceding call to +.Fn sleepq_add . +The +.Fa timo +parameter should specify the timeout value in ticks. +The thread may be marked interruptible by calling +.Fn sleepq_catch_signals +with +.Fa wchan +set to the wait channel. +The function returns a signal number if there are any pending signals for +the current thread and 0 if there is not a pending signal. +.Pp +Once the thread is ready to suspend, +one of the wait functions is called to put the thread to sleep until it is +awakened and context switch to another thread. +The +.Fn sleepq_wait +function is used for non-interruptible sleeps that do not have a timeout. +The +.Fn sleepq_timedwait +function is used for non-interruptible sleeps that have had a timeout set via +.Fn sleepq_set_timeout . +The +.Fn sleepq_wait_sig +function is used for interruptible sleeps that do not have a timeout. +The +.Fn sleepq_timedwait_sig +function is used for interruptible sleeps that do have a timeout set. +The +.Fa wchan +argument to all of the wait functions is the wait channel being slept on. +The +.Fa signal_caught +parameter to the timed wait functions specifies if a previous call to +.Fn sleepq_catch_signals +found a pending signal. +.Pp +When the thread is resumed, +the wait functions return a non-zero value if the thread was awakened due to +an interrupt other than a signal or a timeout. +If the sleep timed out, then +.Dv EWOULDBLOCK +is returned. +If the sleep was interrupted by something other than a signal, +then some other return value will be returned. +If zero is returned after resuming from an interruptible sleep, +then +.Fn sleepq_calc_signal_retval +should be called to determine if the sleep was interrupted by a signal. +If so, +.Fn sleepq_calc_signal_retval +returns +.Dv ERESTART +if the interrupting signal is restarable and +.Dv EINTR +otherwise. +If the sleep was not interrupted by a signal, +.Fn sleepq_calc_signal_retval +will return 0. .Pp -.Fn unsleep -simply removes the thread +A sleeping thread is normally resumed by the +.Fn sleepq_broadcast +and +.Fn sleepq_signal +functions. +The +.Fn sleepq_signal +function awakens the highest priority thread sleeping on a wait channel while +.Fn sleepq_broadcast +awakends all of the threads sleeping on a wait channel. +The +.Fa wchan +argument specifics which wait channel to awaken. +The +.Fa flags +argument should match the +.Fa flags +argument passed to +.Fn sleepq_add +by the threads sleeping on the wait channel. +If the +.Fa pri +argument does not equal -1, +then each thread that is awakened will have its priority raised to +.Fa pri +if it has a lower priority. +.Pp +A thread in an interruptible sleep can be interrupted by another thread via +the +.Fn sleepq_abort +function. +The +.Fa td +argument specifies the thread to interrupt. +An individual thread can also be awakened from sleeping on a specific wait +channel via the +.Fn sleepq_remove +function. +The .Fa td -from its sleep queue. +argument specifies the thread to awaken and the +.Fa wchan +argument specifies the wait channel to awaken it from. +If the thread +.Fa td +is not blocked on the the wait channel +.Fa wchan +then this function will not do anything, +even if the thread is asleep on a different wait channel. +This function should only be used if one of the other functions above is not +sufficient. +One possible use is waking up a specific thread from a widely shared sleep +channel. .Pp -.Fn sleepinit -is called during system startup and initializes the scheduler quantum -.Pq Va sched_quantum -and the sleep queues. +The sleep queue interface is currently used to implement the +.Xr msleep 9 +and +.Xr condvar 9 +interfaces. +Almost all other code in the kernel should use one of those interfaces rather +than manipulating sleep queues directly. .Sh SEE ALSO .Xr msleep 9 , +.Xr condvar 9 , .Xr runqueue 9 , .Xr scheduler 9 -- cgit v1.1