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

개요

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

mutex_init(9f)

mutex(9F)                      Kernel Functions                      mutex(9F)

NAME
       mutex, mutex_enter, mutex_exit, mutex_init, mutex_destroy, mutex_owned,
       mutex_tryenter - mutual exclusion lock routines

SYNOPSIS
       #include <sys/ksynch.h>

       void mutex_init(kmutex_t *mp, char *name, kmutex_type_t type,
            void *arg);


       void mutex_destroy(kmutex_t *mp);


       void mutex_enter(kmutex_t *mp);


       void mutex_exit(kmutex_t *mp);


       int mutex_owned(kmutex_t *mp);


       int mutex_tryenter(kmutex_t *mp);

INTERFACE LEVEL
       Solaris DDI specific (Solaris DDI).

PARAMETERS
       mp      Pointer to a kernel mutex lock (kmutex_t).


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


       type    Type of mutex lock.


       arg     Type-specific argument for initialization routine.


DESCRIPTION
       A mutex enforces a policy of mutual exclusion. Only  one  thread  at  a
       time  may  hold a particular mutex. Threads trying to lock a held mutex
       will block until the mutex is unlocked.


       Mutexes are strictly bracketing and  may  not  be  recursively  locked,
       meaning  that  mutexes should be exited in the opposite order they were
       entered, and cannot be reentered before exiting.


       mutex_init() initializes a mutex. It is an error to initialize a  mutex
       more than once.


       The  type  argument  specifies  the type of mutex lock. The basic mutex
       type is MUTEX_ADAPTIVE, which is expected to be used in almost  all  of
       the  kernel. MUTEX_SPIN provides interrupt blocking and must be used in
       interrupt handlers above LOCK_LEVEL. The iblock cookie argument to  mu‐
       tex_init() encodes the interrupt level to block. The iblock cookie must
       be NULL for adaptive locks.


       MUTEX_DEFAULT  is the type usually specified (except in drivers) to mu‐
       tex_init(). It is identical to MUTEX_ADAPTIVE.


       MUTEX_DRIVER is always used by drivers. mutex_init() converts  this  to
       either MUTEX_ADAPTIVE or MUTEX_SPIN, depending on the iblock cookie.


       The arg argument provides type-specific information for a given variant
       type  of  mutex. When mutex_init() is called for driver mutexes, if the
       mutex is used by the interrupt handler, the arg should be the interrupt
       priority  returned  from  ddi_intr_get_pri(9F)  or   ddi_intr_get_soft‐
       int_pri(9F).  Note that arg should be the value of the interrupt prior‐
       ity cast by calling the DDI_INTR_PRI macro. If the mutex is never  used
       inside an interrupt handler, the argument should be NULL.


       mutex_enter() is used to acquire a mutex. If the mutex is already held,
       then  the  caller  blocks.  After  returning, the calling thread is the
       owner of the mutex. If the mutex is already held by the calling thread,
       a panic ensues.


       mutex_owned() should only be used in ASSERT() and may  be  enforced  by
       not  being defined unless the preprocessor symbol DEBUG is defined. Its
       return value is non-zero if the current thread (or, if that  cannot  be
       determined, at least some thread) holds the mutex pointed to by mp.


       mutex_tryenter()  is  very  similar  to  mutex_enter()  except  that it
       doesn't block when the mutex is already held. mutex_tryenter()  returns
       non-zero  when  it  acquired  the mutex and 0 when the mutex is already
       held.


       mutex_exit() releases a mutex and will unblock another  thread  if  any
       are blocked on the mutex.


       mutex_destroy()  releases  any resources that might have been allocated
       by mutex_init(). mutex_destroy() must be called before freeing the mem‐
       ory containing the mutex with  the  mutex  unheld  (not  owned  by  any
       thread). The caller must be sure that no thread attempts to use the mu‐
       tex.  It  is  an error to reference mutex after it was destroyed except
       re-initializing it using mutex_init().

RETURN VALUES
       mutex_tryenter() returns a non-zero value on success and zero on  fail‐
       ure.


       mutex_owned()  returns a non-zero value if the calling thread currently
       holds the mutex pointed to by mp, or when that cannot be determined, if
       any thread holds the mutex. Otherwise mutex_owned() returns zero.

CONTEXT
       These functions can be called from user, kernel, or  high-level  inter‐
       rupt context, except for mutex_init() and mutex_destroy(), which can be
       called from user or kernel context only.

EXAMPLES
       Example 1 Initializing a Mutex



       A  driver  might do this to initialize a mutex that is part of its unit
       structure and used in its interrupt routine:


         ddi_intr_get_pri(hdlp, &pri);
         mutex_init(&un->un_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri));
         ddi_intr_add_handler(hdlp, xxintr, (caddr_t)un, NULL);


       Example 2 Calling a Routine with a Lock



       A routine that expects to be called with a certain lock held might have
       the following ASSERT:


         xxstart(struct xxunit *un)
         {
                    ASSERT(mutex_owned(&un->un_lock));
         ...


SEE ALSO
       lockstat(4D), lockstat(8),  Intro(9F),  condvar(9F),  ddi_intr_add_han‐
       dler(9F),  ddi_intr_alloc(9F), ddi_intr_get_pri(9F), ddi_intr_get_soft‐
       int_pri(9F), rwlock(9F), semaphore(9F)


       Writing Device Drivers in Oracle Solaris 11.4

NOTES
       Compiling with _LOCKTEST or _MPSTATS defined has no effect.  To  gather
       lock  statistics,  see lockstat(8). Mutex statistics can be gathered on
       the fly, without rebooting or recompiling the  kernel,  via  the  lock‐
       stat(4D) driver.


       The  address  of  a kmutex_t lock must be aligned on an 8-byte boundary
       for 64-bit kernels, or a 4-byte boundary for 32-bit kernels.  Violation
       of  this  requirement will result in undefined behavior, including, but
       not limited to, failure of mutual exclusion or a system panic.


       To write scalable, responsive drivers that do not hang, panic or  dead‐
       lock the system, follow these guidelines:
         Never return from a driver entry point with a mutex held.
         Never hold a mutex when calling a service that may block, for example
         kmem_alloc(9F) with KM_SLEEP or delay(9F).
         Always  acquire  mutexes in a consistent order. If a critical section
         acquires mutex A followed by B, and elsewhere in the driver  mutex  B
         is acquired before A, the driver can deadlock with one thread holding
         A and waiting for B and another thread holding B while waiting for A.
         Always  use a mutex to enforce exclusive access to data, not instruc‐
         tion paths.
         Acquiring a lock in user context that is also acquired  in  interrupt
         context means that, as long as that lock is held, the driver instance
         holding  the  lock is subject to all the rules and limitations of in‐
         terrupt context.
         In most cases, a mutex can and should be acquired and released within
         the same function.
         Liberal use of debugging aids  like  ASSERT(mutex_owned(&mutex))  can
         help  find  callers of a function which should be holding a mutex but
         are not. This means you need to test your driver compiled with DEBUG.
         Do not use a mutex to set driver state. However, you should use a mu‐
         tex to protect driver state data.
         Use per-instance and automatic data  where  possible  to  reduce  the
         amount  of  shared data. Per-instance data can be protected by a per-
         instance lock to improve scalability and reduce contention with  mul‐
         tiple hardware instances.
         Avoid global data and global mutexes whenever possible.


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