/* Void Main's man pages */

{ phpMan } else { main(); }

Command: man perldoc info search(apropos)  


PTHREAD_MUTEX_DESTROY(3P)                           POSIX Programmer's Manual                          PTHREAD_MUTEX_DESTROY(3P)



PROLOG
       This  manual  page is part of the POSIX Programmer's Manual.  The Linux implementation of this interface may differ (con-
       sult the corresponding Linux manual page for details of Linux behavior), or the  interface  may  not  be  implemented  on
       Linux.

NAME
       pthread_mutex_destroy, pthread_mutex_init - destroy and initialize a 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, uninitialized. 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 refer-
       encing the object after it has been destroyed are undefined.

       It shall be safe to destroy an initialized mutex that is unlocked.  Attempting to destroy a locked mutex results in unde-
       fined 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 successful 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 undefined 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  initialization  by a call to
       pthread_mutex_init() with parameter attr specified 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 num-
       ber 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 pro-
       cessing for the function and shall cause an error return prior to modifying the state of the mutex specified by mutex.

ERRORS
       The pthread_mutex_destroy() function may fail if:

       EBUSY  The implementation has detected an attempt to destroy the object referenced by mutex while it is locked or  refer-
              enced (for example, while being used in a pthread_cond_timedwait() or pthread_cond_wait()) by another thread.

       EINVAL The value specified by mutex is invalid.


       The pthread_mutex_init() function shall fail if:

       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 initial-
              ized, 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 implementations 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 restrictive) 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 opaque-
       ness 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 reference) 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 implementations trade off performance versus degree of  error
       checking  according  to  the needs of their specific applications and execution environment. As a general rule, errors or
       conditions caused by the system (such as insufficient memory) always need to be reported, but  errors  due  to  an  erro-
       neously  coded  application  (such  as  failing to provide adequate synchronization to prevent a mutex from being deleted
       while in use) are made optional.

       A wide range of implementations is thus made possible. For example, an implementation intended for application  debugging
       may  implement  all  of the error checks, but an implementation running a single, provably correct application under very
       tight performance constraints in an embedded computer might implement minimal checks. An  implementation  might  even  be
       provided  in two versions, similar to the options that compilers provide: a full-checking, but slower version; and a lim-
       ited-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 variables 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 synchronization objects allows modules with private static
       synchronization variables to avoid runtime initialization tests and overhead. Furthermore, it simplifies  the  coding  of
       self-initializing  modules.  Such modules 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
       initialization 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;


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

       Note  that  the  static initialization both eliminates the need for the initialization test inside pthread_once() and the
       fetch of &foo_mutex to learn the address to be passed to pthread_mutex_lock() or 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 spe-
       cial 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 allocated. 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 initialization.

       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  impor-
       tant case: on the lock operations that occur after the lock has been initialized. This can be done by shifting more over-
       head to the less frequent operation: initialization. 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 acqui-
       sition. 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  ini-
       tialized,  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 significantly 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 statically allocated mutexes. (Such
       finishing would typically involve taking an internal lock, allocating a structure, storing a pointer to the structure  in
       the  mutex,  and  releasing the internal lock.) First, many implementations would reduce such serialization by hashing on
       the mutex address. Second, such serialization can only occur a bounded number of times. In particular, it can  happen  at
       most  as  many times as there are statically allocated synchronization objects. Dynamically allocated objects would still
       be initialized via pthread_mutex_init() or pthread_cond_init().

       Finally, if none of the above optimization techniques for out-of-line allocation yields  sufficient  performance  for  an
       application on some implementation, the application can avoid static initialization altogether by explicitly initializing
       all synchronization objects with the corresponding pthread_*_init() functions, which are  supported  by  all  implementa-
       tions.  An implementation can also document the tradeoffs and advise which initialization technique is more efficient for
       that particular 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.   Implemen-
       tations  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,  Copy-
       right (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  at  http://www.open-
       group.org/unix/online.html .



IEEE/The Open Group                                           2003                                     PTHREAD_MUTEX_DESTROY(3P)

Valid XHTML 1.0!Valid CSS!