TUX: Penguin Power!
Linux| Perl| PHP| Webserv| Databases| Sysadmin| Programming| Filesystems| Java| Webprog

Make Tux happy: Link to us!

       mutex

SYNOPSIS
       #include <pthread.h>

       int pthread_mutex_destroy(pthread_mutex_t *mutex);
       int pthread_mutex_init(pthread_mutex_t *restrict mutex,
              const pthread_mutexattr_t *restrict attr);
       pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;


DESCRIPTION
       The pthread_mutex_destroy() function shall  destroy  the  mutex  object
       referenced  by  mutex;  the mutex object becomes, in effect, uninitial-
       ized. An implementation may cause pthread_mutex_destroy()  to  set  the
       object  referenced  by  mutex  to  an  invalid value. A destroyed mutex
       object can be reinitialized using pthread_mutex_init(); the results  of
       otherwise  referencing the object after it has been destroyed are unde-
       fined.

       It shall be safe to destroy an  initialized  mutex  that  is  unlocked.
       Attempting to destroy a locked mutex results in undefined behavior.

       The pthread_mutex_init() function shall initialize the mutex referenced
       by mutex with attributes specified  by  attr.  If  attr  is  NULL,  the
       default  mutex  attributes  are  used;  the effect shall be the same as
       passing the address of a default mutex attributes object. Upon success-
       ful  initialization,  the  state  of  the mutex becomes initialized and
       unlocked.

       Only mutex itself may be  used  for  performing  synchronization.   The
       result    of    referring    to   copies   of   mutex   in   calls   to
       pthread_mutex_lock(), pthread_mutex_trylock(),  pthread_mutex_unlock(),
       and pthread_mutex_destroy() is undefined.

       Attempting  to initialize an already initialized mutex results in unde-
       fined behavior.

       In cases where default mutex  attributes  are  appropriate,  the  macro
       PTHREAD_MUTEX_INITIALIZER  can  be  used to initialize mutexes that are
       statically allocated. The effect shall be equivalent  to  dynamic  ini-
       tialization by a call to pthread_mutex_init() with parameter attr spec-
       ified as NULL, except that no error checks are performed.

RETURN VALUE
       If successful,  the  pthread_mutex_destroy()  and  pthread_mutex_init()
       functions  shall  return  zero;  otherwise,  an  error  number shall be
       returned to indicate the error.

       The [EBUSY] and [EINVAL] error checks, if implemented, act as  if  they
       were performed immediately at the beginning of processing for the func-
       tion and shall cause an error return prior to modifying  the  state  of
       the mutex specified by mutex.


       EAGAIN The system lacked the necessary resources (other than memory) to
              initialize another mutex.

       ENOMEM Insufficient memory exists to initialize the mutex.

       EPERM  The caller does not have the privilege to perform the operation.


       The pthread_mutex_init() function may fail if:

       EBUSY  The  implementation  has detected an attempt to reinitialize the
              object referenced by mutex, a previously  initialized,  but  not
              yet destroyed, mutex.

       EINVAL The value specified by attr is invalid.


       These functions shall not return an error code of [EINTR].

       The following sections are informative.

EXAMPLES
       None.

APPLICATION USAGE
       None.

RATIONALE
   Alternate Implementations Possible
       This volume of IEEE Std 1003.1-2001 supports several alternative imple-
       mentations of mutexes. An implementation may store the lock directly in
       the  object  of type pthread_mutex_t.  Alternatively, an implementation
       may store the lock in the heap and merely store a pointer,  handle,  or
       unique  ID in the mutex object. Either implementation has advantages or
       may be required on certain hardware configurations.  So  that  portable
       code  can  be  written that is invariant to this choice, this volume of
       IEEE Std 1003.1-2001 does not define assignment or  equality  for  this
       type, and it uses the term "initialize" to reinforce the (more restric-
       tive) notion that the lock may actually  reside  in  the  mutex  object
       itself.

       Note that this precludes an over-specification of the type of the mutex
       or condition variable and motivates the opaqueness of the type.

       An  implementation  is   permitted,   but   not   required,   to   have
       pthread_mutex_destroy()  store  an  illegal value into the mutex.  This
       may help detect erroneous programs that try to lock (or otherwise  ref-
       erence) a mutex that has already been destroyed.

   Tradeoff Between Error Checks and Performance Supported
       Many of the error checks were made optional in order to let implementa-
       tions trade off performance versus degree of error  checking  according
       to  the needs of their specific applications and execution environment.
       provide: a full-checking, but slower version; and  a  limited-checking,
       but faster version. To forbid this optionality would be a disservice to
       users.

       By carefully limiting the use of "undefined behavior"  only  to  things
       that  an  erroneous (badly coded) application might do, and by defining
       that  resource-not-available  errors  are  mandatory,  this  volume  of
       IEEE Std 1003.1-2001  ensures  that  a  fully-conforming application is
       portable across the full range of implementations,  while  not  forcing
       all implementations to add overhead to check for numerous things that a
       correct program never does.

   Why No Limits are Defined
       Defining symbols for the maximum number of mutexes and condition  vari-
       ables  was  considered but rejected because the number of these objects
       may change dynamically. Furthermore, many implementations  place  these
       objects into application memory; thus, there is no explicit maximum.

   Static Initializers for Mutexes and Condition Variables
       Providing  for  static  initialization of statically allocated synchro-
       nization objects allows modules  with  private  static  synchronization
       variables  to avoid runtime initialization tests and overhead. Further-
       more, it simplifies the coding of self-initializing modules. Such  mod-
       ules  are  common  in C libraries, where for various reasons the design
       calls for self-initialization instead of requiring an  explicit  module
       initialization function to be called. An example use of static initial-
       ization follows.

       Without static initialization, a self-initializing routine foo()  might
       look as follows:


              static pthread_once_t foo_once = PTHREAD_ONCE_INIT;
              static pthread_mutex_t foo_mutex;


              void foo_init()
              {
                  pthread_mutex_init(&foo_mutex, NULL);
              }


              void foo()
              {
                  pthread_once(&foo_once, foo_init);
                  pthread_mutex_lock(&foo_mutex);
                 /* Do work. */
                  pthread_mutex_unlock(&foo_mutex);
              }

       With static initialization, the same routine could be coded as follows:


              static pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER;

       pthread_mutex_unlock().

       Thus, the C code written to initialize static objects is simpler on all
       systems and is also faster on a large class of systems; those where the
       (entire) synchronization object can be stored in application memory.

       Yet the locking  performance  question  is  likely  to  be  raised  for
       machines  that  require  mutexes to be allocated out of special memory.
       Such machines actually have to  have  mutexes  and  possibly  condition
       variables  contain  pointers  to the actual hardware locks.  For static
       initialization to work on such machines, pthread_mutex_lock() also  has
       to  test  whether  or not the pointer to the actual lock has been allo-
       cated. If it has not, pthread_mutex_lock() has to initialize it  before
       use.  The reservation of such resources can be made when the program is
       loaded, and hence return codes have not been added to mutex locking and
       condition  variable waiting to indicate failure to complete initializa-
       tion.

       This runtime test in pthread_mutex_lock() would at  first  seem  to  be
       extra  work;  an  extra test is required to see whether the pointer has
       been initialized. On most machines this would actually  be  implemented
       as  a  fetch of the pointer, testing the pointer against zero, and then
       using the pointer if it has already been initialized.  While  the  test
       might seem to add extra work, the extra effort of testing a register is
       usually negligible since no extra memory references are actually  done.
       As  more and more machines provide caches, the real expenses are memory
       references, not instructions executed.

       Alternatively, depending on the machine architecture, there  are  often
       ways  to eliminate all overhead in the most important case: on the lock
       operations that occur after the lock has been initialized. This can  be
       done by shifting more overhead to the less frequent operation: initial-
       ization. Since out-of-line mutex allocation also means that an  address
       has  to  be dereferenced to find the actual lock, one technique that is
       widely applicable is to have static initialization store a bogus  value
       for that address; in particular, an address that causes a machine fault
       to occur. When such a fault occurs upon the first attempt to lock  such
       a  mutex, validity checks can be done, and then the correct address for
       the actual lock can be filled in. Subsequent lock operations  incur  no
       extra overhead since they do not "fault".  This is merely one technique
       that can be used to support static initialization, while not  adversely
       affecting the performance of lock acquisition. No doubt there are other
       techniques that are highly machine-dependent.

       The locking overhead for machines doing out-of-line mutex allocation is
       thus  similar  for  modules  being  implicitly initialized, where it is
       improved for those doing mutex allocation entirely inline.  The  inline
       case is thus made much faster, and the out-of-line case is not signifi-
       cantly worse.

       Besides the issue of locking performance for such machines,  a  concern
       is  raised  that it is possible that threads would serialize contending
       for initialization locks when attempting to finish initializing  stati-
       cally allocated mutexes. (Such finishing would typically involve taking
       gether by explicitly initializing all synchronization objects with  the
       corresponding  pthread_*_init()  functions,  which are supported by all
       implementations. An implementation can also document the tradeoffs  and
       advise  which  initialization technique is more efficient for that par-
       ticular implementation.

   Destroying Mutexes
       A mutex can be destroyed immediately after it is unlocked. For example,
       consider the following code:


              struct obj {
              pthread_mutex_t om;
                  int refcnt;
                  ...
              };


              obj_done(struct obj *op)
              {
                  pthread_mutex_lock(&op->om);
                  if (--op->refcnt == 0) {
                      pthread_mutex_unlock(&op->om);
              (A)     pthread_mutex_destroy(&op->om);
              (B)     free(op);
                  } else
              (C)     pthread_mutex_unlock(&op->om);
              }

       In this case obj is reference counted and obj_done() is called whenever
       a reference to the object is dropped.  Implementations are required  to
       allow an object to be destroyed and freed and potentially unmapped (for
       example, lines A and B) immediately after the object is unlocked  (line
       C).

FUTURE DIRECTIONS
       None.

SEE ALSO
       pthread_mutex_getprioceiling()       ,      pthread_mutex_lock()      ,
       pthread_mutex_timedlock() , pthread_mutexattr_getpshared() ,  the  Base
       Definitions volume of IEEE Std 1003.1-2001, <pthread.h>

COPYRIGHT
       Portions  of  this text are reprinted and reproduced in electronic form
       from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology
       --  Portable  Operating  System  Interface (POSIX), The Open Group Base
       Specifications Issue 6, Copyright (C) 2001-2003  by  the  Institute  of
       Electrical  and  Electronics  Engineers, Inc and The Open Group. In the
       event of any discrepancy between this version and the original IEEE and
       The  Open Group Standard, the original IEEE and The Open Group Standard
       is the referee document. The original Standard can be  obtained  online
Find all the song lyrics here: Lyrics Now!