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

DESCRIPTION

24       The  pthread_mutex_destroy()  function  shall  destroy the mutex object
25       referenced by mutex; the mutex object becomes,  in  effect,  uninitial‐
26       ized.  An  implementation  may cause pthread_mutex_destroy() to set the
27       object referenced by mutex to an invalid value.
28
29       A   destroyed    mutex    object    can    be    reinitialized    using
30       pthread_mutex_init();  the  results of otherwise referencing the object
31       after it has been destroyed are undefined.
32
33       It shall be safe to destroy an  initialized  mutex  that  is  unlocked.
34       Attempting to destroy a locked mutex, or a mutex that another thread is
35       attempting  to  lock,  or  a  mutex   that   is   being   used   in   a
36       pthread_cond_timedwait() or pthread_cond_wait() call by another thread,
37       results in undefined behavior.
38
39       The pthread_mutex_init() function shall initialize the mutex referenced
40       by  mutex  with  attributes  specified  by  attr.  If attr is NULL, the
41       default mutex attributes are used; the effect  shall  be  the  same  as
42       passing the address of a default mutex attributes object. Upon success‐
43       ful initialization, the state of  the  mutex  becomes  initialized  and
44       unlocked.
45
46       See  Section  2.9.9, Synchronization Object Copies and Alternative Map‐
47       pings for further requirements.
48
49       Attempting to initialize an already initialized mutex results in  unde‐
50       fined behavior.
51
52       In  cases  where  default  mutex  attributes are appropriate, the macro
53       PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes. The effect
54       shall   be   equivalent   to   dynamic  initialization  by  a  call  to
55       pthread_mutex_init() with parameter attr specified as NULL, except that
56       no error checks are performed.
57
58       The  behavior is undefined if the value specified by the mutex argument
59       to pthread_mutex_destroy() does not refer to an initialized mutex.
60
61       The behavior is undefined if the value specified by the  attr  argument
62       to   pthread_mutex_init()  does  not  refer  to  an  initialized  mutex
63       attributes object.
64

RETURN VALUE

66       If successful,  the  pthread_mutex_destroy()  and  pthread_mutex_init()
67       functions  shall  return  zero;  otherwise,  an  error  number shall be
68       returned to indicate the error.
69

ERRORS

71       The pthread_mutex_init() function shall fail if:
72
73       EAGAIN The system lacked the necessary resources (other than memory) to
74              initialize another mutex.
75
76       ENOMEM Insufficient memory exists to initialize the mutex.
77
78       EPERM  The caller does not have the privilege to perform the operation.
79
80       The pthread_mutex_init() function may fail if:
81
82       EINVAL The  attributes  object  referenced by attr has the robust mutex
83              attribute set without the process-shared attribute being set.
84
85       These functions shall not return an error code of [EINTR].
86
87       The following sections are informative.
88

EXAMPLES

90       None.
91

APPLICATION USAGE

93       None.
94

RATIONALE

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

FUTURE DIRECTIONS

309       None.
310

SEE ALSO

312       pthread_mutex_getprioceiling(), pthread_mutexattr_getrobust(),
313       pthread_mutex_lock(), pthread_mutex_timedlock(), pthread_mutex‐
314       attr_getpshared()
315
316       The Base Definitions volume of POSIX.1‐2017, <pthread.h>
317
319       Portions  of  this text are reprinted and reproduced in electronic form
320       from IEEE Std 1003.1-2017, Standard for Information Technology --  Por‐
321       table  Operating System Interface (POSIX), The Open Group Base Specifi‐
322       cations Issue 7, 2018 Edition, Copyright (C) 2018 by the  Institute  of
323       Electrical  and  Electronics Engineers, Inc and The Open Group.  In the
324       event of any discrepancy between this version and the original IEEE and
325       The  Open Group Standard, the original IEEE and The Open Group Standard
326       is the referee document. The original Standard can be  obtained  online
327       at http://www.opengroup.org/unix/online.html .
328
329       Any  typographical  or  formatting  errors that appear in this page are
330       most likely to have been introduced during the conversion of the source
331       files  to  man page format. To report such errors, see https://www.ker
332       nel.org/doc/man-pages/reporting_bugs.html .
333
334
335
336IEEE/The Open Group                  2017            PTHREAD_MUTEX_DESTROY(3P)
Impressum