sleep -- suspend process execution pending occurrence of an event

Synopsis (Not in current DDI version)

   #include <sys/types.h>
   #include <sys/param.h>
   #include <sys/ddi.h>

int sleep(caddr_t event, int priority);


sleep( ) suspends execution of a process to await certain events such as reaching a known system state in hardware or software. For instance, when a process wants to read a device and no data are available, the driver may need to call sleep( ) to wait for data to become available before returning. This causes the kernel to suspend execution of the process that called sleep and schedule another process. The process that called sleep can be resumed by a call to the wakeup(D3) function with the same event specified as that used to call sleep.


Kernel address signifying an event for which the caller wishes to wait.

A hint to the scheduling policy as to the relative priority the caller wishes to be assigned while running in the kernel after waking up.

Return values

sleep( ) returns 0 if the caller woke up because of a call to wakeup( ), or if the caller was stopped by a job control signal and subsequently continued. If the sleep is interrupted by a signal that does not cause the process to be stopped and the priority argument includes the PCATCH flag, the sleep( ) call returns a value of 1. If the sleep is interrupted by a signal and the PCATCH flag is not set, the process will longjmp out of the driver and the sleep call will never return to the calling code.


event argument

The address has no significance except that the same address must be passed to wakeup(D3) to resume the sleeping process. The address used should be the address of a kernel data structure associated with the driver, or one of the driver's own data structures. Use of arbitrary addresses not associated with a private data structure can result in conflict with other, unrelated sleep and wakeup operations in the kernel.

priority argument

Valid values for priority are 0 through 39 inclusive. In general, a lower value will result in more favorable scheduling although the exact semantic of the priority argument is specific to the scheduling class of the caller, and some scheduling classes may choose to ignore the argument for the purposes of assigning a scheduling priority.

In addition to the scheduling semantics, the value of the priority argument determines whether the sleep may be interrupted by signals. If the value of priority is less than or equal to the value of the constant PZERO (defined in sys/param.h), the sleeping process will not be awakened by a signal. If the value of priority is greater than PZERO and the PCATCH bit flag is ORed into the priority argument, the process will wake up prematurely (without a call to wakeup) upon receipt of a non-ignored, non-held signal and will normally return 1 to the calling code. If priority is greater than PZERO and PCATCH is not set, the sleep function will longjmp out of the driver upon receipt of a signal and will never return to the caller.

Calls to sleep( ) must be able to tolerate premature wakeups. After it is awakened, the code must reexamine the condition on which it was sleeping.

General considerations

If a process were to sleep while it is manipulating global data inside a critical section of driver code, it would be possible for another process to execute base level driver code that manipulates the same data while the first process was sleeping, resulting in data corruption. A driver should not sleep inside such a critical section unless it takes explicit steps to prevent concurrent access to the data (for example, the driver could implement its own locking protocol to protect the data). See ``Critical code section'' in HDK Technical Reference.

The value for priority should be selected based on whether or not a wakeup is certain to occur as well as the importance of the driver and of any resources that the driver will hold after waking up. If the driver is holding or waiting for a critical kernel resource or is otherwise crucial to the performance of the system, and the corresponding call to wakeup is guaranteed to happen, the driver should specify a priority argument less than or equal to PZERO. If the driver is less performance critical or it is possible that the wakeup may not occur, the driver should specify a priority argument greater than PZERO.

If there is any driver state that needs to be cleaned up in the event of a signal, the driver should OR the PCATCH flag in with the priority argument. Typical items that need cleaning up are locked data structures that should be unlocked or dynamically allocated resources that need to be freed. When PCATCH is specified, sleep will normally return a 1 in the event of a signal, indicating that the calling routine should perform any necessary cleanup and then return.

If sleep is called from the driver's strategy(D2) routine, the caller should OR the priority argument with PCATCH or select a priority of PZERO or less.

Context and synchronization

User or blockable context.

Note that, when you acquire a spin lock from within the user or blockable context, the context changes to non-blockable until the lock is released. This means that you cannot call the sleep( ) function while locks are held.

Hardware applicability


Version applicability

ddi: 1, 2, 3, 4, 5, 6

Differences between versions

Starting with DDI version 7, SV_WAIT(D3) and SV_WAIT_SIG(D3) replace sleep. These new functions are much faster, since they avoid the hash table insertion and lookup that are needed to unblock a process based on an arbitrary channel number. Instead, they are pased a driver-owned sv_t object, which directly tracks sleeping LWPs. See ``Synchronization variables'' in HDK Technical Reference.

The split into a signalable and a non-signalable form also avoids the confusing overloading of the priority argument. The priority arguments to the SV_WAIT( ) and SV_WAIT_SIG( ) functions take different values than the priority argument to the sleep( ) function. In particular, SV_WAIT_SIG(D3) implicitly behaves as if PCATCH is set.

SInce SV_WAIT( ) and SV_WAIT_SIG( ) were designed for multithreaded drivers, they require the use of LOCK(D3) and UNLOCK(D3) instead of spl( ) and splx( ). These can be used even in a driver that is not multithreaded; in this case, they simply serve the purpose of raising and lowering the interrupt priority level.

SCO OpenServer ODDI compatibility

The sleep(D3oddi) function is the equivalent of the DDI sleep( ) function, although the priority argument is formed differently.

Note that SCO OpenServer releases all locks when the sleep( ) function is called, and reacquires them after the wakeup(D3oddi) call executes.



``Synchronization variables'' in HDK Technical Reference

19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005