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

NAME

6       pthread_mutex_destroy,  pthread_mutex_init  -  destroy and initialize a
7       mutex
8

SYNOPSIS

10       #include <pthread.h>
11
12       int pthread_mutex_destroy(pthread_mutex_t *mutex);
13       int pthread_mutex_init(pthread_mutex_t *restrict mutex,
14              const pthread_mutexattr_t *restrict attr);
15       pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
16
17

DESCRIPTION

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

RETURN VALUE

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

ERRORS

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

EXAMPLES

96       None.
97

APPLICATION USAGE

99       None.
100

RATIONALE

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

FUTURE DIRECTIONS

307       None.
308

SEE ALSO

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