1PTHREAD_MUTEX_DESTROY(3P)  POSIX Programmer's Manual PTHREAD_MUTEX_DESTROY(3P)
2
3
4

PROLOG

6       This  manual  page is part of the POSIX Programmer's Manual.  The Linux
7       implementation of this interface may differ (consult the  corresponding
8       Linux  manual page for details of Linux behavior), or the interface may
9       not be implemented on Linux.
10

NAME

12       pthread_mutex_destroy, pthread_mutex_init - destroy  and  initialize  a
13       mutex
14

SYNOPSIS

16       #include <pthread.h>
17
18       int pthread_mutex_destroy(pthread_mutex_t *mutex);
19       int pthread_mutex_init(pthread_mutex_t *restrict mutex,
20              const pthread_mutexattr_t *restrict attr);
21       pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
22
23

DESCRIPTION

25       The  pthread_mutex_destroy()  function  shall  destroy the mutex object
26       referenced by mutex; the mutex object becomes,  in  effect,  uninitial‐
27       ized.  An  implementation  may cause pthread_mutex_destroy() to set the
28       object referenced by mutex to  an  invalid  value.  A  destroyed  mutex
29       object  can be reinitialized using pthread_mutex_init(); the results of
30       otherwise referencing the object after it has been destroyed are  unde‐
31       fined.
32
33       It  shall  be  safe  to  destroy an initialized mutex that is unlocked.
34       Attempting to destroy a locked mutex results in undefined behavior.
35
36       The pthread_mutex_init() function shall initialize the mutex referenced
37       by  mutex  with  attributes  specified  by  attr.  If attr is NULL, the
38       default mutex attributes are used; the effect  shall  be  the  same  as
39       passing the address of a default mutex attributes object. Upon success‐
40       ful initialization, the state of  the  mutex  becomes  initialized  and
41       unlocked.
42
43       Only  mutex  itself  may  be  used for performing synchronization.  The
44       result   of   referring   to   copies   of   mutex    in    calls    to
45       pthread_mutex_lock(),  pthread_mutex_trylock(), pthread_mutex_unlock(),
46       and pthread_mutex_destroy() is undefined.
47
48       Attempting to initialize an already initialized mutex results in  unde‐
49       fined behavior.
50
51       In  cases  where  default  mutex  attributes are appropriate, the macro
52       PTHREAD_MUTEX_INITIALIZER can be used to initialize  mutexes  that  are
53       statically  allocated.  The  effect shall be equivalent to dynamic ini‐
54       tialization by a call to pthread_mutex_init() with parameter attr spec‐
55       ified as NULL, except that no error checks are performed.
56

RETURN VALUE

58       If  successful,  the  pthread_mutex_destroy()  and pthread_mutex_init()
59       functions shall return  zero;  otherwise,  an  error  number  shall  be
60       returned to indicate the error.
61
62       The  [EBUSY]  and [EINVAL] error checks, if implemented, act as if they
63       were performed immediately at the beginning of processing for the func‐
64       tion  and  shall  cause an error return prior to modifying the state of
65       the mutex specified by mutex.
66

ERRORS

68       The pthread_mutex_destroy() function may fail if:
69
70       EBUSY  The implementation has detected an attempt to destroy the object
71              referenced  by mutex while it is locked or referenced (for exam‐
72              ple,  while  being  used  in   a   pthread_cond_timedwait()   or
73              pthread_cond_wait()) by another thread.
74
75       EINVAL The value specified by mutex is invalid.
76
77
78       The pthread_mutex_init() function shall fail if:
79
80       EAGAIN The system lacked the necessary resources (other than memory) to
81              initialize another mutex.
82
83       ENOMEM Insufficient memory exists to initialize the mutex.
84
85       EPERM  The caller does not have the privilege to perform the operation.
86
87
88       The pthread_mutex_init() function may fail if:
89
90       EBUSY  The implementation has detected an attempt to  reinitialize  the
91              object  referenced  by  mutex, a previously initialized, but not
92              yet destroyed, mutex.
93
94       EINVAL The value specified by attr is invalid.
95
96
97       These functions shall not return an error code of [EINTR].
98
99       The following sections are informative.
100

EXAMPLES

102       None.
103

APPLICATION USAGE

105       None.
106

RATIONALE

108   Alternate Implementations Possible
109       This volume of IEEE Std 1003.1-2001 supports several alternative imple‐
110       mentations of mutexes. An implementation may store the lock directly in
111       the object of type pthread_mutex_t.  Alternatively,  an  implementation
112       may  store  the lock in the heap and merely store a pointer, handle, or
113       unique ID in the mutex object. Either implementation has advantages  or
114       may  be  required  on certain hardware configurations. So that portable
115       code can be written that is invariant to this choice,  this  volume  of
116       IEEE Std 1003.1-2001  does  not  define assignment or equality for this
117       type, and it uses the term "initialize" to reinforce the (more restric‐
118       tive)  notion  that  the  lock  may actually reside in the mutex object
119       itself.
120
121       Note that this precludes an over-specification of the type of the mutex
122       or condition variable and motivates the opaqueness of the type.
123
124       An   implementation   is   permitted,   but   not   required,  to  have
125       pthread_mutex_destroy() store an illegal value into  the  mutex.   This
126       may  help detect erroneous programs that try to lock (or otherwise ref‐
127       erence) a mutex that has already been destroyed.
128
129   Tradeoff Between Error Checks and Performance Supported
130       Many of the error checks were made optional in order to let implementa‐
131       tions  trade  off performance versus degree of error checking according
132       to the needs of their specific applications and execution  environment.
133       As  a  general rule, errors or conditions caused by the system (such as
134       insufficient memory) always need to be reported, but errors due  to  an
135       erroneously coded application (such as failing to provide adequate syn‐
136       chronization to prevent a mutex from being deleted while  in  use)  are
137       made optional.
138
139       A  wide range of implementations is thus made possible. For example, an
140       implementation intended for application debugging may implement all  of
141       the error checks, but an implementation running a single, provably cor‐
142       rect application under very tight performance constraints in an  embed‐
143       ded  computer  might  implement minimal checks. An implementation might
144       even be provided in two versions, similar to the options that compilers
145       provide:  a  full-checking, but slower version; and a limited-checking,
146       but faster version. To forbid this optionality would be a disservice to
147       users.
148
149       By  carefully  limiting  the use of "undefined behavior" only to things
150       that an erroneous (badly coded) application might do, and  by  defining
151       that  resource-not-available  errors  are  mandatory,  this  volume  of
152       IEEE Std 1003.1-2001 ensures that  a  fully-conforming  application  is
153       portable  across  the  full range of implementations, while not forcing
154       all implementations to add overhead to check for numerous things that a
155       correct program never does.
156
157   Why No Limits are Defined
158       Defining  symbols for the maximum number of mutexes and condition vari‐
159       ables was considered but rejected because the number of  these  objects
160       may  change  dynamically. Furthermore, many implementations place these
161       objects into application memory; thus, there is no explicit maximum.
162
163   Static Initializers for Mutexes and Condition Variables
164       Providing for static initialization of  statically  allocated  synchro‐
165       nization  objects  allows  modules  with private static synchronization
166       variables to avoid runtime initialization tests and overhead.  Further‐
167       more,  it simplifies the coding of self-initializing modules. Such mod‐
168       ules are common in C libraries, where for various  reasons  the  design
169       calls  for  self-initialization instead of requiring an explicit module
170       initialization function to be called. An example use of static initial‐
171       ization follows.
172
173       Without  static initialization, a self-initializing routine foo() might
174       look as follows:
175
176
177              static pthread_once_t foo_once = PTHREAD_ONCE_INIT;
178              static pthread_mutex_t foo_mutex;
179
180
181              void foo_init()
182              {
183                  pthread_mutex_init(&foo_mutex, NULL);
184              }
185
186
187              void foo()
188              {
189                  pthread_once(&foo_once, foo_init);
190                  pthread_mutex_lock(&foo_mutex);
191                 /* Do work. */
192                  pthread_mutex_unlock(&foo_mutex);
193              }
194
195       With static initialization, the same routine could be coded as follows:
196
197
198              static pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER;
199
200
201              void foo()
202              {
203                  pthread_mutex_lock(&foo_mutex);
204                 /* Do work. */
205                  pthread_mutex_unlock(&foo_mutex);
206              }
207
208       Note that the static initialization both eliminates the  need  for  the
209       initialization  test  inside pthread_once() and the fetch of &foo_mutex
210       to  learn  the  address  to  be  passed  to   pthread_mutex_lock()   or
211       pthread_mutex_unlock().
212
213       Thus, the C code written to initialize static objects is simpler on all
214       systems and is also faster on a large class of systems; those where the
215       (entire) synchronization object can be stored in application memory.
216
217       Yet  the  locking  performance  question  is  likely  to  be raised for
218       machines that require mutexes to be allocated out  of  special  memory.
219       Such  machines  actually  have  to  have mutexes and possibly condition
220       variables contain pointers to the actual hardware  locks.   For  static
221       initialization  to work on such machines, pthread_mutex_lock() also has
222       to test whether or not the pointer to the actual lock  has  been  allo‐
223       cated.  If it has not, pthread_mutex_lock() has to initialize it before
224       use. The reservation of such resources can be made when the program  is
225       loaded, and hence return codes have not been added to mutex locking and
226       condition variable waiting to indicate failure to complete  initializa‐
227       tion.
228
229       This  runtime  test  in  pthread_mutex_lock() would at first seem to be
230       extra work; an extra test is required to see whether  the  pointer  has
231       been  initialized.  On most machines this would actually be implemented
232       as a fetch of the pointer, testing the pointer against zero,  and  then
233       using  the  pointer  if it has already been initialized. While the test
234       might seem to add extra work, the extra effort of testing a register is
235       usually  negligible since no extra memory references are actually done.
236       As more and more machines provide caches, the real expenses are  memory
237       references, not instructions executed.
238
239       Alternatively,  depending  on the machine architecture, there are often
240       ways to eliminate all overhead in the most important case: on the  lock
241       operations  that occur after the lock has been initialized. This can be
242       done by shifting more overhead to the less frequent operation: initial‐
243       ization.  Since out-of-line mutex allocation also means that an address
244       has to be dereferenced to find the actual lock, one technique  that  is
245       widely  applicable is to have static initialization store a bogus value
246       for that address; in particular, an address that causes a machine fault
247       to  occur. When such a fault occurs upon the first attempt to lock such
248       a mutex, validity checks can be done, and then the correct address  for
249       the  actual  lock can be filled in. Subsequent lock operations incur no
250       extra overhead since they do not "fault".  This is merely one technique
251       that  can be used to support static initialization, while not adversely
252       affecting the performance of lock acquisition. No doubt there are other
253       techniques that are highly machine-dependent.
254
255       The locking overhead for machines doing out-of-line mutex allocation is
256       thus similar for modules being  implicitly  initialized,  where  it  is
257       improved  for those doing mutex allocation entirely inline.  The inline
258       case is thus made much faster, and the out-of-line case is not signifi‐
259       cantly worse.
260
261       Besides  the  issue of locking performance for such machines, a concern
262       is raised that it is possible that threads would  serialize  contending
263       for  initialization locks when attempting to finish initializing stati‐
264       cally allocated mutexes. (Such finishing would typically involve taking
265       an  internal  lock,  allocating  a  structure, storing a pointer to the
266       structure in the mutex, and releasing the internal lock.)  First,  many
267       implementations would reduce such serialization by hashing on the mutex
268       address. Second, such serialization can only occur a bounded number  of
269       times.  In particular, it can happen at most as many times as there are
270       statically allocated  synchronization  objects.  Dynamically  allocated
271       objects   would   still  be  initialized  via  pthread_mutex_init()  or
272       pthread_cond_init().
273
274       Finally, if none of the above optimization techniques  for  out-of-line
275       allocation  yields  sufficient  performance  for an application on some
276       implementation, the application can avoid static  initialization  alto‐
277       gether  by explicitly initializing all synchronization objects with the
278       corresponding pthread_*_init() functions, which are  supported  by  all
279       implementations.  An implementation can also document the tradeoffs and
280       advise which initialization technique is more efficient for  that  par‐
281       ticular implementation.
282
283   Destroying Mutexes
284       A mutex can be destroyed immediately after it is unlocked. For example,
285       consider the following code:
286
287
288              struct obj {
289              pthread_mutex_t om;
290                  int refcnt;
291                  ...
292              };
293
294
295              obj_done(struct obj *op)
296              {
297                  pthread_mutex_lock(&op->om);
298                  if (--op->refcnt == 0) {
299                      pthread_mutex_unlock(&op->om);
300              (A)     pthread_mutex_destroy(&op->om);
301              (B)     free(op);
302                  } else
303              (C)     pthread_mutex_unlock(&op->om);
304              }
305
306       In this case obj is reference counted and obj_done() is called whenever
307       a  reference to the object is dropped.  Implementations are required to
308       allow an object to be destroyed and freed and potentially unmapped (for
309       example,  lines A and B) immediately after the object is unlocked (line
310       C).
311

FUTURE DIRECTIONS

313       None.
314

SEE ALSO

316       pthread_mutex_getprioceiling(),                   pthread_mutex_lock(),
317       pthread_mutex_timedlock(),   pthread_mutexattr_getpshared(),  the  Base
318       Definitions volume of IEEE Std 1003.1-2001, <pthread.h>
319
321       Portions of this text are reprinted and reproduced in  electronic  form
322       from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology
323       -- Portable Operating System Interface (POSIX),  The  Open  Group  Base
324       Specifications  Issue  6,  Copyright  (C) 2001-2003 by the Institute of
325       Electrical and Electronics Engineers, Inc and The Open  Group.  In  the
326       event of any discrepancy between this version and the original IEEE and
327       The Open Group Standard, the original IEEE and The Open Group  Standard
328       is  the  referee document. The original Standard can be obtained online
329       at http://www.opengroup.org/unix/online.html .
330
331
332
333IEEE/The Open Group                  2003            PTHREAD_MUTEX_DESTROY(3P)
Impressum