1PTHREAD_MUTEX_DESTROY(P) POSIX Programmer's Manual PTHREAD_MUTEX_DESTROY(P)
2
3
4
6 pthread_mutex_destroy, pthread_mutex_init - destroy and initialize a
7 mutex
8
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
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
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
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
96 None.
97
99 None.
100
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
307 None.
308
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)