SVR5
sleep(D3)
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);
Description
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.
Arguments
event-
Kernel address signifying an event for which the caller wishes to wait.
priority-
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.
Usage
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
All
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.
References
wakeup(D3)
``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