condvar(9f) 맨 페이지 - 윈디하나의 솔라나라

개요

섹션
맨 페이지 이름
검색(S)

condvar(9f)

condvar(9F)                    Kernel Functions                    condvar(9F)

NAME
       condvar,   cv_init,   cv_destroy,   cv_wait,  cv_signal,  cv_broadcast,
       cv_wait_sig, cv_timedwait, cv_timedwait_sig,  cv_reltimedwait,  cv_rel‐
       timedwait_sig - condition variable routines

SYNOPSIS
       #include <sys/ksynch.h>

       void cv_init(kcondvar_t *cvp, char *name, kcv_type_t type, void *arg);


       void cv_destroy(kcondvar_t *cvp);


       void cv_wait(kcondvar_t *cvp, kmutex_t *mp);


       void cv_signal(kcondvar_t *cvp);


       void cv_broadcast(kcondvar_t *cvp);


       int cv_wait_sig(kcondvar_t *cvp, kmutex_t *mp);


       clock_t cv_timedwait(kcondvar_t *cvp, kmutex_t *mp, clock_t timeout);


       clock_t cv_timedwait_sig(kcondvar_t *cvp, kmutex_t *mp, clock_t timeout);


       clock_t cv_reltimedwait(kcondvar_t *cvp, kmutex_t *mp, clock_t delta,
            time_res_t resolution);


       clock_t cv_reltimedwait_sig(kcondvar_t *cvp, kmutex_t *mp, clock_t delta,
            time_res_t resolution);

INTERFACE LEVEL
       Solaris DDI specific (Solaris DDI).

PARAMETERS
       cvp           A pointer to an abstract data type kcondvar_t.


       mp            A pointer to a mutual exclusion lock (kmutex_t), initial‐
                     ized by mutex_init(9F) and held by the caller.


       name          Descriptive  string. This is obsolete and should be NULL.
                     (Non-NULL strings are legal, but they're a waste of  ker‐
                     nel memory.)


       type          The constant CV_DRIVER.


       arg           A  type-specific  argument,  drivers  should  pass arg as
                     NULL.


       timeout       A time, in absolute ticks since boot, when cv_timedwait()
                     or cv_timedwait_sig() should return.


       delta         A time, in  relative  ticks,  when  cv_reltimedwait()  or
                     cv_reltimedwait_sig() should return.


       resolution    A  flag that specifies how accurate the relative time in‐
                     terval should be. Possible values are TR_NANOSEC,  TR_MI‐
                     CROSEC,    TR_MILLISEC,    TR_SEC,    or   TR_CLOCK_TICK.
                     TR_CLOCK_TICK  indicates  that  the  interval  should  be
                     aligned  to  system clock ticks. This information is used
                     to anticipate or defer the timeout expiration in order to
                     batch process similarly  expiring  events,  allowing  the
                     system  to  stay  idle for longer periods of time and en‐
                     hance its power efficiency.


DESCRIPTION
       Condition variables are a standard form of thread synchronization. They
       are designed to be used with mutual exclusion locks (mutexes). The  as‐
       sociated mutex is used to ensure that a condition can be checked atomi‐
       cally  and  that the thread can block on the associated condition vari‐
       able without missing either a change to the condition or a signal  that
       the  condition  has changed. Condition variables must be initialized by
       calling cv_init(), and must be deallocated by calling cv_destroy().


       The usual use of condition variables is to check a condition (for exam‐
       ple, device state, data structure reference count, etc.) while  holding
       a  mutex  which keeps other threads from changing the condition. If the
       condition is such that the thread should  block,  cv_wait()  is  called
       with a related condition variable and the mutex. At some later point in
       time,  another  thread  would acquire the mutex, set the condition such
       that the previous thread can be unblocked, unblock the previous  thread
       with cv_signal() or cv_broadcast(), and then release the mutex.


       The  cv_wait() function suspends the calling thread and exits the mutex
       atomically so that another thread which holds the mutex  cannot  signal
       on  the condition variable until the blocking thread is blocked. Before
       returning, the mutex is reacquired.


       The cv_signal() function signals the condition and  wakes  one  blocked
       thread. All blocked threads can be unblocked by calling cv_broadcast().
       cv_signal()  and  cv_broadcast()  can  be called by a thread even if it
       does not hold the mutex passed into cv_wait(), though holding the mutex
       is necessary to ensure predictable scheduling.


       The cv_wait_sig() function is similar to cv_wait() but returns 0  if  a
       signal  (for  example,  by kill(2)) is sent to the thread. In any case,
       the mutex is reacquired before returning.


       The cv_timedwait() function is similar to cv_wait(), except that it re‐
       turns −1 without the condition being signaled after  the  timeout  time
       has been reached.


       The  cv_timedwait_sig()  function  is  similar  to  cv_timedwait()  and
       cv_wait_sig(), except that it returns −1 without  the  condition  being
       signaled after the timeout time has been reached, or 0 if a signal (for
       example, by kill(2)) is sent to the thread.


       For  both  cv_timedwait()  and  cv_timedwait_sig(), time is in absolute
       clock ticks since the last system reboot. The current time may be found
       by calling ddi_get_lbolt(9F).


       The cv_reltimedwait() function is  similar  to  cv_timedwait(),  except
       that  it  takes  a relative time value as argument and it also takes an
       additional argument to specify  the  accuracy  of  such  interval.  The
       cv_reltimedwait_sig()  function  is analogous to cv_timedwait_sig() but
       takes the same arguments as cv_reltimedwait().

RETURN VALUES
       0        For  cv_wait_sig(),   cv_timedwait_sig(),   and   cv_reltimed‐
                wait_sig(),  this  value  indicates that the condition was not
                necessarily signaled and the function returned because a  sig‐
                nal (as in kill(2)) was pending.


       −1       For cv_timedwait(), cv_timedwait_sig(), cv_reltimedwait(), and
                cv_reltimedwait_sig(), this value indicates that the condition
                was not necessarily signaled and the function returned because
                the timeout time was reached.


       >0       For cv_wait_sig(), cv_timedwait(), cv_timedwait_sig(), cv_rel‐
                timedwait(), and cv_reltimedwait_sig(), a value greater than 0
                indicates that the condition was met and the function returned
                due  to a call to either cv_signal() or cv_broadcast(), or due
                to a premature wakeup (see NOTES).


CONTEXT
       These functions can be called from user, kernel or  interrupt  context.
       In  most  cases,  however,  cv_wait(),  cv_timedwait(),  cv_wait_sig(),
       cv_timedwait_sig(), cv_reltimedwait(), and cv_reltimedwait_sig() should
       not be called from interrupt context, and cannot be called from a high-
       level interrupt context.


       If  cv_wait(),   cv_timedwait(),   cv_wait_sig(),   cv_timedwait_sig(),
       cv_reltimedwait(),  or  cv_reltimedwait_sig()  are  used from interrupt
       context, lower-priority interrupts will  not  be  serviced  during  the
       wait.  This  means  that if the thread that will eventually perform the
       wakeup becomes blocked on anything that requires the lower-priority in‐
       terrupt, the system will hang.


       For example, the thread that will perform the wakeup may need to  first
       allocate  memory. This memory allocation may require waiting for paging
       I/O to complete, which may require a lower-priority disk or network in‐
       terrupt to be serviced. In general, situations like this  are  hard  to
       predict,  so it is advisable to avoid waiting on condition variables or
       semaphores in an interrupt context.

EXAMPLES
       Example 1 Waiting for a Flag Value in a Driver's Unit



       Here the condition being waited for is a flag value in a driver's  unit
       structure.  The  condition  variable is also in the unit structure, and
       the flag word is protected by a mutex in the unit structure.


         mutex_enter(&un->un_lock);
         while (un->un_flag & UNIT_BUSY)
               cv_wait(&un->un_cv, &un->un_lock);
         un->un_flag |= UNIT_BUSY;
         mutex_exit(&un->un_lock);


       Example 2 Unblocking Threads Blocked by the Code in Example 1



       At some later point in time, another thread would execute the following
       to unblock any threads blocked by the above code.


         mutex_enter(&un->un_lock);
         un->un_flag &= ~UNIT_BUSY;
         cv_broadcast(&un->un_cv);
         mutex_exit(&un->un_lock);


NOTES
       It is possible for cv_wait(), cv_wait_sig(), cv_timedwait(),  cv_timed‐
       wait_sig(), cv_reltimedwait(), and cv_reltimedwait_sig() to return pre‐
       maturely,  that is, not due to a call to cv_signal() or cv_broadcast().
       This occurs most commonly in the case of  cv_wait_sig()  and  cv_timed‐
       wait_sig()  and  cv_timedwait_sig()  when  the  thread  is  stopped and
       restarted by job control signals or by a debugger, but  can  happen  in
       other  cases  as  well, even for cv_wait(). Code that calls these func‐
       tions must always recheck the reason for blocking and call again if the
       reason for blocking is still true.


       If your driver needs to wait on behalf of processes that have real-time
       constraints, use cv_timedwait() or cv_reltimedwait()  rather  than  de‐
       lay(9F).  The  delay() function calls timeout(9F), which can be subject
       to priority inversions.


       Not all threads can receive signals from user level processes. In cases
       where such  reception  is  impossible  (such  as  during  execution  of
       close(9E)   due   to  exit(2)),  cv_wait_sig()  behaves  as  cv_wait(),
       cv_timedwait_sig() behaves as cv_timedwait(), and cv_reltimedwait_sig()
       behaves as cv_reltimedwait(). To avoid unkillable processes,  users  of
       these  functions  may  need to protect against waiting indefinitely for
       events that might not occur. The  ddi_can_receive_sig(9F)  function  is
       provided to detect when signal reception is possible.

SEE ALSO
       kill(2),  ddi_can_receive_sig(9F),  ddi_get_lbolt(9F),  mutex(9F),  mu‐
       tex_init(9F)


       Writing Device Drivers in Oracle Solaris 11.4

Oracle Solaris 11.4               13 Nov 2009                      condvar(9F)
맨 페이지 내용의 저작권은 맨 페이지 작성자에게 있습니다.
RSS ATOM XHTML 5 CSS3