MyWebUniversity.com Home Page
 



OpenSolaris man pages main menu


Kernel Functions for Drivers                          condvar(9F)



NAME
     condvar,   cvinit,    cvdestroy,    cvwait,    cvsignal,
     cvbroadcast,  cvwaitsig, cvtimedwait, cvtimedwaitsig -
     condition variable routines

SYNOPSIS
     #include 



     void cvinit(kcondvart *cvp, char *name, kcvtypet type, void *arg);


     void cvdestroy(kcondvart *cvp);


     void cvwait(kcondvart *cvp, kmutext *mp);


     void cvsignal(kcondvart *cvp);


     void cvbroadcast(kcondvart *cvp);


     int cvwaitsig(kcondvart *cvp, kmutext *mp);


     clockt cvtimedwait(kcondvart *cvp, kmutext *mp, clockt timeout);


     clockt cvtimedwaitsig(kcondvart *cvp, kmutext *mp, clockt timeout);


INTERFACE LEVEL
     Solaris DI specific (Solaris DI).

PARAMETERS
     cvp        A pointer to an abstract data type kcondvart.


     mp         A pointer to a mutual exclusion lock  (kmutext),
                initialized  by  mutexinit(9F)  and  held by the
                caller.


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






SunOS 5.11          Last change: 15 Dec 2003                    1






Kernel Functions for Drivers                          condvar(9F)



     type       The constant CVDRIVER.


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


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


DESCRIPTION
     Condition variables are a standard form of thread synchroni-
     zation.  They  are designed to be used with mutual exclusion
     locks (mutexes). The associated mutex is used to ensure that
     a  condition  can  be checked atomically and that the thread
     can block on the associated condition variable without miss-
     ing  either  a  change to the condition or a signal that the
     condition has changed. Condition variables must be  initial-
     ized  by  calling cvinit(), and must be deallocated by cal-
     ling cvdestroy().


     The usual use of condition variables is to check a condition
     (for  example, 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, cvwait() is called with a related con-
     dition  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 cvsignal() or cvbroadcast(), and then
     release the mutex.


     cvwait() suspends the calling thread and  exits  the  mutex
     atomically so that another thread which holds the mutex can-
     not signal on the  condition  variable  until  the  blocking
     thread  is  blocked.  Before  returning,  the mutex is reac-
     quired.


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






SunOS 5.11          Last change: 15 Dec 2003                    2






Kernel Functions for Drivers                          condvar(9F)



     The function  cvwaitsig()  is  similar  to  cvwait()  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 function cvtimedwait() is similar to cvwait(),  except
     that  it  returns  -1  without  the condition being signaled
     after the timeout time has been reached.


     The function cvtimedwaitsig() is similar to cvtimedwait()
     and  cvwaitsig(),  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 cvtimedwait() and cvtimedwaitsig(), time  is  in
     absolute  clock  ticks  since  the  last  system reboot. The
     current time may be found by calling ddigetlbolt(9F).

RETURN VALUES
     0        For cvwaitsig() and cvtimedwaitsig()  indicates
              that the condition was not necessarily signaled and
              the function  returned  because  a  signal  (as  in
              kill(2)) was pending.


     -1       For cvtimedwait() and cvtimedwaitsig() indicates
              that the condition was not necessarily signaled and
              the function returned because the timeout time  was
              reached.


     >0       For      cvwaitsig(),      cvtimedwait()      or
              cvtimedwaitsig() indicates that the condition was
              met and the function returned  due  to  a  call  to
              cvsignal()  or  cvbroadcast(), or due to a prema-
              ture wakeup (see NOTES).


CONTEXT
     These functions can be called from user, kernel or interrupt
     context.  In most cases, however, cvwait(), cvtimedwait(),
     cvwaitsig(), and cvtimedwaitsig() should not  be  called
     from  interrupt  context,  and cannot be called from a high-
     level interrupt context.


     If    cvwait(),    cvtimedwait(),    cvwaitsig(),     or
     cvtimedwaitsig()  are  used from interrupt context, lower-



SunOS 5.11          Last change: 15 Dec 2003                    3






Kernel Functions for Drivers                          condvar(9F)



     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 interrupt, 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 interrupt 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.


            mutexenter(&un->unlock);
            while (un->unflag & UNITBUSY)
              cvwait(&un->uncv, &un->unlock);
            un->unflag = UNITBUSY;
            mutexexit(&un->unlock);


     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.



       mutexenter(&un->unlock);
       un->unflag &= ~UNITBUSY;
       cvbroadcast(&un->uncv);
       mutexexit(&un->unlock);


NOTES
     It is possible for cvwait(), cvwaitsig(), cvtimedwait(),
     and  cvtimedwaitsig()  to return prematurely, that is, not
     due to a call to cvsignal() or cvbroadcast(). This  occurs
     most   commonly   in   the   case   of   cvwaitsig()   and



SunOS 5.11          Last change: 15 Dec 2003                    4






Kernel Functions for Drivers                          condvar(9F)



     cvtimedwaitsig() 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  cvwait().  Code  that  calls
     these  functions 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 cvtimedwait() rather than
     delay(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)),
     cvwaitsig()  behaves  as cvwait(), and cvtimedwaitsig()
     behaves as cvtimedwait(). To  avoid  unkillable  processes,
     users of these functions may need to protect against waiting
     indefinitely  for  events  that   might   not   occur.   The
     ddicanreceivesig(9F)  function is provided to detect when
     signal reception is possible.

SEE ALSO
     kill(2),     ddicanreceivesig(9F),     ddigetlbolt(9F),
     mutex(9F), mutexinit(9F)


     Writing Device Drivers


























SunOS 5.11          Last change: 15 Dec 2003                    5



OpenSolaris man pages main menu

Contact us      |       About us      |       Term of use      |       Copyright © 2000-2010 MyWebUniversity.com ™