summaryrefslogtreecommitdiffstats
path: root/man3p/pthread_mutex_init.3p
diff options
context:
space:
mode:
Diffstat (limited to 'man3p/pthread_mutex_init.3p')
-rw-r--r--man3p/pthread_mutex_init.3p363
1 files changed, 363 insertions, 0 deletions
diff --git a/man3p/pthread_mutex_init.3p b/man3p/pthread_mutex_init.3p
new file mode 100644
index 000000000..f538d727b
--- /dev/null
+++ b/man3p/pthread_mutex_init.3p
@@ -0,0 +1,363 @@
+.\" Copyright (c) 2001-2003 The Open Group, All Rights Reserved
+.TH "PTHREAD_MUTEX_DESTROY" P 2003 "IEEE/The Open Group" "POSIX Programmer's Manual"
+.\" pthread_mutex_destroy
+.SH NAME
+pthread_mutex_destroy, pthread_mutex_init \- destroy and initialize
+a mutex
+.SH SYNOPSIS
+.LP
+\fB#include <pthread.h>
+.br
+.sp
+int pthread_mutex_destroy(pthread_mutex_t *\fP\fImutex\fP\fB);
+.br
+int pthread_mutex_init(pthread_mutex_t *restrict\fP \fImutex\fP\fB,
+.br
+\ \ \ \ \ \ const pthread_mutexattr_t *restrict\fP \fIattr\fP\fB);
+.br
+pthread_mutex_t\fP \fImutex\fP \fB= PTHREAD_MUTEX_INITIALIZER; \fP
+\fB
+.br
+\fP
+.SH DESCRIPTION
+.LP
+The \fIpthread_mutex_destroy\fP() function shall destroy the mutex
+object referenced by \fImutex\fP; the mutex object becomes,
+in effect, uninitialized. An implementation may cause \fIpthread_mutex_destroy\fP()
+to set the object referenced by \fImutex\fP
+to an invalid value. A destroyed mutex object can be reinitialized
+using \fIpthread_mutex_init\fP(); the results of otherwise
+referencing the object after it has been destroyed are undefined.
+.LP
+It shall be safe to destroy an initialized mutex that is unlocked.
+Attempting to destroy a locked mutex results in undefined
+behavior.
+.LP
+The \fIpthread_mutex_init\fP() function shall initialize the mutex
+referenced by \fImutex\fP with attributes specified by
+\fIattr\fP. If \fIattr\fP 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.
+.LP
+Only \fImutex\fP itself may be used for performing synchronization.
+The result of referring to copies of \fImutex\fP in calls
+to \fIpthread_mutex_lock\fP(), \fIpthread_mutex_trylock\fP(), \fIpthread_mutex_unlock\fP(),
+and \fIpthread_mutex_destroy\fP() is undefined.
+.LP
+Attempting to initialize an already initialized mutex results in undefined
+behavior.
+.LP
+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 \fIpthread_mutex_init\fP()
+with parameter \fIattr\fP specified as NULL, except that no error
+checks are performed.
+.SH RETURN VALUE
+.LP
+If successful, the \fIpthread_mutex_destroy\fP() and \fIpthread_mutex_init\fP()
+functions shall return zero; otherwise, an
+error number shall be returned to indicate the error.
+.LP
+The [EBUSY] and [EINVAL] error checks, if implemented, act as if they
+were performed immediately at the beginning of processing
+for the function and shall cause an error return prior to modifying
+the state of the mutex specified by \fImutex\fP.
+.SH ERRORS
+.LP
+The \fIpthread_mutex_destroy\fP() function may fail if:
+.TP 7
+.B EBUSY
+The implementation has detected an attempt to destroy the object referenced
+by \fImutex\fP while it is locked or referenced
+(for example, while being used in a \fIpthread_cond_timedwait\fP()
+or \fIpthread_cond_wait\fP()) by another thread.
+.TP 7
+.B EINVAL
+The value specified by \fImutex\fP is invalid.
+.sp
+.LP
+The \fIpthread_mutex_init\fP() function shall fail if:
+.TP 7
+.B EAGAIN
+The system lacked the necessary resources (other than memory) to initialize
+another mutex.
+.TP 7
+.B ENOMEM
+Insufficient memory exists to initialize the mutex.
+.TP 7
+.B EPERM
+The caller does not have the privilege to perform the operation.
+.sp
+.LP
+The \fIpthread_mutex_init\fP() function may fail if:
+.TP 7
+.B EBUSY
+The implementation has detected an attempt to reinitialize the object
+referenced by \fImutex\fP, a previously initialized, but
+not yet destroyed, mutex.
+.TP 7
+.B EINVAL
+The value specified by \fIattr\fP is invalid.
+.sp
+.LP
+These functions shall not return an error code of [EINTR].
+.LP
+\fIThe following sections are informative.\fP
+.SH EXAMPLES
+.LP
+None.
+.SH APPLICATION USAGE
+.LP
+None.
+.SH RATIONALE
+.SS Alternate Implementations Possible
+.LP
+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 \fBpthread_mutex_t\fP.
+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.
+.LP
+Note that this precludes an over-specification of the type of the
+mutex or condition variable and motivates the opaqueness of
+the type.
+.LP
+An implementation is permitted, but not required, to have \fIpthread_mutex_destroy\fP()
+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.
+.SS Tradeoff Between Error Checks and Performance Supported
+.LP
+Many of the error checks were made optional in order to let implementations
+trade off performance \fIversus\fP 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 erroneously coded application
+(such as failing to provide adequate synchronization to prevent a
+mutex from being deleted while in use) are made optional.
+.LP
+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 limited-checking, but faster
+version. To forbid this optionality would be a disservice to users.
+.LP
+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.
+.SS Why No Limits are Defined
+.LP
+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.
+.SS Static Initializers for Mutexes and Condition Variables
+.LP
+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.
+.LP
+Without static initialization, a self-initializing routine \fIfoo\fP()
+might look as follows:
+.sp
+.RS
+.nf
+
+\fBstatic pthread_once_t foo_once = PTHREAD_ONCE_INIT;
+static pthread_mutex_t foo_mutex;
+.sp
+
+void foo_init()
+{
+ pthread_mutex_init(&foo_mutex, NULL);
+}
+.sp
+
+void foo()
+{
+ pthread_once(&foo_once, foo_init);
+ pthread_mutex_lock(&foo_mutex);
+ /* Do work. */
+ pthread_mutex_unlock(&foo_mutex);
+}
+\fP
+.fi
+.RE
+.LP
+With static initialization, the same routine could be coded as follows:
+.sp
+.RS
+.nf
+
+\fBstatic pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER;
+.sp
+
+void foo()
+{
+ pthread_mutex_lock(&foo_mutex);
+ /* Do work. */
+ pthread_mutex_unlock(&foo_mutex);
+}
+\fP
+.fi
+.RE
+.LP
+Note that the static initialization both eliminates the need for the
+initialization test inside \fIpthread_once\fP() and the fetch of &\fIfoo_mutex\fP
+to learn the address to be passed
+to \fIpthread_mutex_lock\fP() or \fIpthread_mutex_unlock\fP().
+.LP
+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.
+.LP
+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, \fIpthread_mutex_lock\fP()
+also has to test whether or not the pointer to the actual lock has
+been allocated. If it has not, \fIpthread_mutex_lock\fP() 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.
+.LP
+This runtime test in \fIpthread_mutex_lock\fP() 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.
+.LP
+Alternatively, depending on the machine architecture, there are often
+ways to eliminate \fIall\fP overhead in the most
+important case: on the lock operations that occur \fIafter\fP the
+lock has been initialized. This can be done by shifting more
+overhead 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 acquisition. No doubt there are other techniques that
+are highly machine-dependent.
+.LP
+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 significantly worse.
+.LP
+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 \fIpthread_mutex_init\fP() or \fIpthread_cond_init\fP().
+.LP
+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 \fIpthread_*_init\fP()
+functions,
+which are supported by all implementations. An implementation can
+also document the tradeoffs and advise which initialization
+technique is more efficient for that particular implementation.
+.SS Destroying Mutexes
+.LP
+A mutex can be destroyed immediately after it is unlocked. For example,
+consider the following code:
+.sp
+.RS
+.nf
+
+\fBstruct obj {
+pthread_mutex_t om;
+ int refcnt;
+ ...
+};
+.sp
+
+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);
+}
+\fP
+.fi
+.RE
+.LP
+In this case \fIobj\fP is reference counted and \fIobj_done\fP() 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).
+.SH FUTURE DIRECTIONS
+.LP
+None.
+.SH SEE ALSO
+.LP
+\fIpthread_mutex_getprioceiling\fP() , \fIpthread_mutex_lock\fP()
+, \fIpthread_mutex_timedlock\fP() , \fIpthread_mutexattr_getpshared\fP()
+, the Base Definitions volume of
+IEEE\ Std\ 1003.1-2001, \fI<pthread.h>\fP
+.SH 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 at
+http://www.opengroup.org/unix/online.html .