1PTHREAD_MUTEX_DESTROY(3P) POSIX Programmer's Manual PTHREAD_MUTEX_DESTROY(3P)
2
3
4
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
12 pthread_mutex_destroy, pthread_mutex_init - destroy and initialize a
13 mutex
14
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
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
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
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
102 None.
103
105 None.
106
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
313 None.
314
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)