blob: 755b0ac5583d98e2c6236d4eadda3fba01427e9b [file] [log] [blame]
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
Pierre Peifferd0c884d2012-02-22 16:40:15 +010028
Elliott Hughes6f94de32013-02-12 06:06:22 +000029#include <pthread.h>
Elliott Hughes3e898472013-02-12 16:40:24 +000030
31#include <errno.h>
32#include <limits.h>
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080033#include <sys/atomics.h>
Elliott Hughes84114c82013-07-17 13:33:19 -070034#include <sys/mman.h>
Pierre Peifferd0c884d2012-02-22 16:40:15 +010035#include <unistd.h>
36
37#include "bionic_atomic_inline.h"
38#include "bionic_futex.h"
39#include "bionic_pthread.h"
40#include "bionic_tls.h"
41#include "pthread_internal.h"
42#include "thread_private.h"
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080043
Mathias Agopian7c0c3792011-09-05 23:54:55 -070044extern void pthread_debug_mutex_lock_check(pthread_mutex_t *mutex);
45extern void pthread_debug_mutex_unlock_check(pthread_mutex_t *mutex);
46
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080047extern void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode);
48extern void _exit_thread(int retCode);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080049
David 'Digit' Turner6304d8b2010-06-02 18:12:12 -070050int __futex_wake_ex(volatile void *ftx, int pshared, int val)
51{
52 return __futex_syscall3(ftx, pshared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, val);
53}
54
55int __futex_wait_ex(volatile void *ftx, int pshared, int val, const struct timespec *timeout)
56{
57 return __futex_syscall4(ftx, pshared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, val, timeout);
58}
59
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080060/* CAVEAT: our implementation of pthread_cleanup_push/pop doesn't support C++ exceptions
61 * and thread cancelation
62 */
63
64void __pthread_cleanup_push( __pthread_cleanup_t* c,
65 __pthread_cleanup_func_t routine,
66 void* arg )
67{
68 pthread_internal_t* thread = __get_thread();
69
70 c->__cleanup_routine = routine;
71 c->__cleanup_arg = arg;
72 c->__cleanup_prev = thread->cleanup_stack;
73 thread->cleanup_stack = c;
74}
75
76void __pthread_cleanup_pop( __pthread_cleanup_t* c, int execute )
77{
78 pthread_internal_t* thread = __get_thread();
79
80 thread->cleanup_stack = c->__cleanup_prev;
81 if (execute)
82 c->__cleanup_routine(c->__cleanup_arg);
83}
84
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080085void pthread_exit(void * retval)
86{
87 pthread_internal_t* thread = __get_thread();
88 void* stack_base = thread->attr.stack_base;
89 int stack_size = thread->attr.stack_size;
90 int user_stack = (thread->attr.flags & PTHREAD_ATTR_FLAG_USER_STACK) != 0;
Jack Rene480fc82011-09-21 12:44:11 +020091 sigset_t mask;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080092
93 // call the cleanup handlers first
94 while (thread->cleanup_stack) {
95 __pthread_cleanup_t* c = thread->cleanup_stack;
96 thread->cleanup_stack = c->__cleanup_prev;
97 c->__cleanup_routine(c->__cleanup_arg);
98 }
99
100 // call the TLS destructors, it is important to do that before removing this
101 // thread from the global list. this will ensure that if someone else deletes
102 // a TLS key, the corresponding value will be set to NULL in this thread's TLS
103 // space (see pthread_key_delete)
104 pthread_key_clean_all();
105
Elliott Hughes84114c82013-07-17 13:33:19 -0700106 if (thread->alternate_signal_stack != NULL) {
107 // Tell the kernel to stop using the alternate signal stack.
108 stack_t ss;
109 ss.ss_sp = NULL;
110 ss.ss_flags = SS_DISABLE;
111 sigaltstack(&ss, NULL);
112
113 // Free it.
114 munmap(thread->alternate_signal_stack, SIGSTKSZ);
115 thread->alternate_signal_stack = NULL;
116 }
117
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800118 // if the thread is detached, destroy the pthread_internal_t
Sergey Melnikov10ce9692012-10-26 14:06:43 +0400119 // otherwise, keep it in memory and signal any joiners.
Elliott Hughes9d23e042013-02-15 19:21:51 -0800120 pthread_mutex_lock(&gThreadListLock);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800121 if (thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) {
Elliott Hughes9d23e042013-02-15 19:21:51 -0800122 _pthread_internal_remove_locked(thread);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800123 } else {
Bjorn Andersson0753dc62012-05-03 17:12:39 -0700124 /* make sure that the thread struct doesn't have stale pointers to a stack that
125 * will be unmapped after the exit call below.
126 */
127 if (!user_stack) {
128 thread->attr.stack_base = NULL;
129 thread->attr.stack_size = 0;
130 thread->tls = NULL;
131 }
132
msg5550f020d12013-06-06 14:59:28 -0400133 /* Indicate that the thread has exited for joining threads. */
134 thread->attr.flags |= PTHREAD_ATTR_FLAG_ZOMBIE;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800135 thread->return_value = retval;
msg5550f020d12013-06-06 14:59:28 -0400136
137 /* Signal the joining thread if present. */
138 if (thread->attr.flags & PTHREAD_ATTR_FLAG_JOINED) {
139 pthread_cond_signal(&thread->join_cond);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800140 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800141 }
Elliott Hughes9d23e042013-02-15 19:21:51 -0800142 pthread_mutex_unlock(&gThreadListLock);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800143
Jack Rene480fc82011-09-21 12:44:11 +0200144 sigfillset(&mask);
145 sigdelset(&mask, SIGSEGV);
146 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
147
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800148 // destroy the thread stack
Elliott Hughesa97cc5b2013-10-07 10:20:24 -0700149 if (user_stack) {
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800150 _exit_thread((int)retval);
Elliott Hughesa97cc5b2013-10-07 10:20:24 -0700151 } else {
152 // We need to munmap the stack we're running on before calling exit.
153 // That's not something we can do in C.
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800154 _exit_with_stack_teardown(stack_base, stack_size, (int)retval);
Elliott Hughesa97cc5b2013-10-07 10:20:24 -0700155 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800156}
157
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800158/* a mutex is implemented as a 32-bit integer holding the following fields
159 *
160 * bits: name description
Elliott Hughes40eabe22013-02-14 18:59:37 -0800161 * 31-16 tid owner thread's tid (recursive and errorcheck only)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800162 * 15-14 type mutex type
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700163 * 13 shared process-shared flag
164 * 12-2 counter counter of recursive mutexes
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800165 * 1-0 state lock state (0, 1 or 2)
166 */
167
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100168/* Convenience macro, creates a mask of 'bits' bits that starts from
169 * the 'shift'-th least significant bit in a 32-bit word.
170 *
171 * Examples: FIELD_MASK(0,4) -> 0xf
172 * FIELD_MASK(16,9) -> 0x1ff0000
173 */
174#define FIELD_MASK(shift,bits) (((1 << (bits))-1) << (shift))
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800175
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100176/* This one is used to create a bit pattern from a given field value */
177#define FIELD_TO_BITS(val,shift,bits) (((val) & ((1 << (bits))-1)) << (shift))
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100178
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100179/* And this one does the opposite, i.e. extract a field's value from a bit pattern */
180#define FIELD_FROM_BITS(val,shift,bits) (((val) >> (shift)) & ((1 << (bits))-1))
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800181
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100182/* Mutex state:
183 *
184 * 0 for unlocked
185 * 1 for locked, no waiters
186 * 2 for locked, maybe waiters
187 */
188#define MUTEX_STATE_SHIFT 0
189#define MUTEX_STATE_LEN 2
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800190
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100191#define MUTEX_STATE_MASK FIELD_MASK(MUTEX_STATE_SHIFT, MUTEX_STATE_LEN)
192#define MUTEX_STATE_FROM_BITS(v) FIELD_FROM_BITS(v, MUTEX_STATE_SHIFT, MUTEX_STATE_LEN)
193#define MUTEX_STATE_TO_BITS(v) FIELD_TO_BITS(v, MUTEX_STATE_SHIFT, MUTEX_STATE_LEN)
194
195#define MUTEX_STATE_UNLOCKED 0 /* must be 0 to match __PTHREAD_MUTEX_INIT_VALUE */
196#define MUTEX_STATE_LOCKED_UNCONTENDED 1 /* must be 1 due to atomic dec in unlock operation */
197#define MUTEX_STATE_LOCKED_CONTENDED 2 /* must be 1 + LOCKED_UNCONTENDED due to atomic dec */
198
199#define MUTEX_STATE_FROM_BITS(v) FIELD_FROM_BITS(v, MUTEX_STATE_SHIFT, MUTEX_STATE_LEN)
200#define MUTEX_STATE_TO_BITS(v) FIELD_TO_BITS(v, MUTEX_STATE_SHIFT, MUTEX_STATE_LEN)
201
202#define MUTEX_STATE_BITS_UNLOCKED MUTEX_STATE_TO_BITS(MUTEX_STATE_UNLOCKED)
203#define MUTEX_STATE_BITS_LOCKED_UNCONTENDED MUTEX_STATE_TO_BITS(MUTEX_STATE_LOCKED_UNCONTENDED)
204#define MUTEX_STATE_BITS_LOCKED_CONTENDED MUTEX_STATE_TO_BITS(MUTEX_STATE_LOCKED_CONTENDED)
205
206/* return true iff the mutex if locked with no waiters */
207#define MUTEX_STATE_BITS_IS_LOCKED_UNCONTENDED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_UNCONTENDED)
208
209/* return true iff the mutex if locked with maybe waiters */
210#define MUTEX_STATE_BITS_IS_LOCKED_CONTENDED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_CONTENDED)
211
212/* used to flip from LOCKED_UNCONTENDED to LOCKED_CONTENDED */
213#define MUTEX_STATE_BITS_FLIP_CONTENTION(v) ((v) ^ (MUTEX_STATE_BITS_LOCKED_CONTENDED ^ MUTEX_STATE_BITS_LOCKED_UNCONTENDED))
214
215/* Mutex counter:
216 *
217 * We need to check for overflow before incrementing, and we also need to
218 * detect when the counter is 0
219 */
220#define MUTEX_COUNTER_SHIFT 2
221#define MUTEX_COUNTER_LEN 11
222#define MUTEX_COUNTER_MASK FIELD_MASK(MUTEX_COUNTER_SHIFT, MUTEX_COUNTER_LEN)
223
224#define MUTEX_COUNTER_BITS_WILL_OVERFLOW(v) (((v) & MUTEX_COUNTER_MASK) == MUTEX_COUNTER_MASK)
225#define MUTEX_COUNTER_BITS_IS_ZERO(v) (((v) & MUTEX_COUNTER_MASK) == 0)
226
227/* Used to increment the counter directly after overflow has been checked */
228#define MUTEX_COUNTER_BITS_ONE FIELD_TO_BITS(1,MUTEX_COUNTER_SHIFT,MUTEX_COUNTER_LEN)
229
230/* Returns true iff the counter is 0 */
231#define MUTEX_COUNTER_BITS_ARE_ZERO(v) (((v) & MUTEX_COUNTER_MASK) == 0)
232
233/* Mutex shared bit flag
234 *
235 * This flag is set to indicate that the mutex is shared among processes.
236 * This changes the futex opcode we use for futex wait/wake operations
237 * (non-shared operations are much faster).
238 */
239#define MUTEX_SHARED_SHIFT 13
240#define MUTEX_SHARED_MASK FIELD_MASK(MUTEX_SHARED_SHIFT,1)
241
242/* Mutex type:
243 *
244 * We support normal, recursive and errorcheck mutexes.
245 *
246 * The constants defined here *cannot* be changed because they must match
247 * the C library ABI which defines the following initialization values in
248 * <pthread.h>:
249 *
250 * __PTHREAD_MUTEX_INIT_VALUE
251 * __PTHREAD_RECURSIVE_MUTEX_VALUE
252 * __PTHREAD_ERRORCHECK_MUTEX_INIT_VALUE
253 */
254#define MUTEX_TYPE_SHIFT 14
255#define MUTEX_TYPE_LEN 2
256#define MUTEX_TYPE_MASK FIELD_MASK(MUTEX_TYPE_SHIFT,MUTEX_TYPE_LEN)
257
258#define MUTEX_TYPE_NORMAL 0 /* Must be 0 to match __PTHREAD_MUTEX_INIT_VALUE */
259#define MUTEX_TYPE_RECURSIVE 1
260#define MUTEX_TYPE_ERRORCHECK 2
261
262#define MUTEX_TYPE_TO_BITS(t) FIELD_TO_BITS(t, MUTEX_TYPE_SHIFT, MUTEX_TYPE_LEN)
263
264#define MUTEX_TYPE_BITS_NORMAL MUTEX_TYPE_TO_BITS(MUTEX_TYPE_NORMAL)
265#define MUTEX_TYPE_BITS_RECURSIVE MUTEX_TYPE_TO_BITS(MUTEX_TYPE_RECURSIVE)
266#define MUTEX_TYPE_BITS_ERRORCHECK MUTEX_TYPE_TO_BITS(MUTEX_TYPE_ERRORCHECK)
267
268/* Mutex owner field:
269 *
270 * This is only used for recursive and errorcheck mutexes. It holds the
Elliott Hughes40eabe22013-02-14 18:59:37 -0800271 * tid of the owning thread. Note that this works because the Linux
272 * kernel _only_ uses 16-bit values for tids.
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100273 *
274 * More specifically, it will wrap to 10000 when it reaches over 32768 for
275 * application processes. You can check this by running the following inside
276 * an adb shell session:
277 *
278 OLDPID=$$;
279 while true; do
280 NEWPID=$(sh -c 'echo $$')
281 if [ "$NEWPID" -gt 32768 ]; then
282 echo "AARGH: new PID $NEWPID is too high!"
283 exit 1
284 fi
285 if [ "$NEWPID" -lt "$OLDPID" ]; then
286 echo "****** Wrapping from PID $OLDPID to $NEWPID. *******"
287 else
288 echo -n "$NEWPID!"
289 fi
290 OLDPID=$NEWPID
291 done
292
293 * Note that you can run the same example on a desktop Linux system,
294 * the wrapping will also happen at 32768, but will go back to 300 instead.
295 */
296#define MUTEX_OWNER_SHIFT 16
297#define MUTEX_OWNER_LEN 16
298
299#define MUTEX_OWNER_FROM_BITS(v) FIELD_FROM_BITS(v,MUTEX_OWNER_SHIFT,MUTEX_OWNER_LEN)
300#define MUTEX_OWNER_TO_BITS(v) FIELD_TO_BITS(v,MUTEX_OWNER_SHIFT,MUTEX_OWNER_LEN)
301
302/* Convenience macros.
303 *
304 * These are used to form or modify the bit pattern of a given mutex value
305 */
306
307
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800308
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700309/* a mutex attribute holds the following fields
310 *
311 * bits: name description
312 * 0-3 type type of mutex
313 * 4 shared process-shared flag
314 */
315#define MUTEXATTR_TYPE_MASK 0x000f
316#define MUTEXATTR_SHARED_MASK 0x0010
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800317
318
319int pthread_mutexattr_init(pthread_mutexattr_t *attr)
320{
321 if (attr) {
322 *attr = PTHREAD_MUTEX_DEFAULT;
323 return 0;
324 } else {
325 return EINVAL;
326 }
327}
328
329int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
330{
331 if (attr) {
332 *attr = -1;
333 return 0;
334 } else {
335 return EINVAL;
336 }
337}
338
339int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
340{
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700341 if (attr) {
342 int atype = (*attr & MUTEXATTR_TYPE_MASK);
343
344 if (atype >= PTHREAD_MUTEX_NORMAL &&
345 atype <= PTHREAD_MUTEX_ERRORCHECK) {
346 *type = atype;
347 return 0;
348 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800349 }
350 return EINVAL;
351}
352
353int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
354{
355 if (attr && type >= PTHREAD_MUTEX_NORMAL &&
356 type <= PTHREAD_MUTEX_ERRORCHECK ) {
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700357 *attr = (*attr & ~MUTEXATTR_TYPE_MASK) | type;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800358 return 0;
359 }
360 return EINVAL;
361}
362
363/* process-shared mutexes are not supported at the moment */
364
365int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared)
366{
367 if (!attr)
368 return EINVAL;
369
Mathias Agopianb7681162009-07-13 22:00:33 -0700370 switch (pshared) {
371 case PTHREAD_PROCESS_PRIVATE:
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700372 *attr &= ~MUTEXATTR_SHARED_MASK;
373 return 0;
374
Mathias Agopianb7681162009-07-13 22:00:33 -0700375 case PTHREAD_PROCESS_SHARED:
376 /* our current implementation of pthread actually supports shared
377 * mutexes but won't cleanup if a process dies with the mutex held.
378 * Nevertheless, it's better than nothing. Shared mutexes are used
379 * by surfaceflinger and audioflinger.
380 */
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700381 *attr |= MUTEXATTR_SHARED_MASK;
Mathias Agopianb7681162009-07-13 22:00:33 -0700382 return 0;
383 }
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700384 return EINVAL;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800385}
386
387int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared)
388{
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700389 if (!attr || !pshared)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800390 return EINVAL;
391
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700392 *pshared = (*attr & MUTEXATTR_SHARED_MASK) ? PTHREAD_PROCESS_SHARED
393 : PTHREAD_PROCESS_PRIVATE;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800394 return 0;
395}
396
397int pthread_mutex_init(pthread_mutex_t *mutex,
398 const pthread_mutexattr_t *attr)
399{
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700400 int value = 0;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800401
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700402 if (mutex == NULL)
403 return EINVAL;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800404
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700405 if (__predict_true(attr == NULL)) {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100406 mutex->value = MUTEX_TYPE_BITS_NORMAL;
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700407 return 0;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800408 }
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700409
410 if ((*attr & MUTEXATTR_SHARED_MASK) != 0)
411 value |= MUTEX_SHARED_MASK;
412
413 switch (*attr & MUTEXATTR_TYPE_MASK) {
414 case PTHREAD_MUTEX_NORMAL:
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100415 value |= MUTEX_TYPE_BITS_NORMAL;
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700416 break;
417 case PTHREAD_MUTEX_RECURSIVE:
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100418 value |= MUTEX_TYPE_BITS_RECURSIVE;
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700419 break;
420 case PTHREAD_MUTEX_ERRORCHECK:
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100421 value |= MUTEX_TYPE_BITS_ERRORCHECK;
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700422 break;
423 default:
424 return EINVAL;
425 }
426
427 mutex->value = value;
428 return 0;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800429}
430
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800431
432/*
433 * Lock a non-recursive mutex.
434 *
435 * As noted above, there are three states:
436 * 0 (unlocked, no contention)
437 * 1 (locked, no contention)
438 * 2 (locked, contention)
439 *
440 * Non-recursive mutexes don't use the thread-id or counter fields, and the
441 * "type" value is zero, so the only bits that will be set are the ones in
442 * the lock state field.
443 */
444static __inline__ void
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100445_normal_lock(pthread_mutex_t* mutex, int shared)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800446{
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100447 /* convenience shortcuts */
448 const int unlocked = shared | MUTEX_STATE_BITS_UNLOCKED;
449 const int locked_uncontended = shared | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800450 /*
451 * The common case is an unlocked mutex, so we begin by trying to
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100452 * change the lock's state from 0 (UNLOCKED) to 1 (LOCKED).
453 * __bionic_cmpxchg() returns 0 if it made the swap successfully.
454 * If the result is nonzero, this lock is already held by another thread.
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800455 */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100456 if (__bionic_cmpxchg(unlocked, locked_uncontended, &mutex->value) != 0) {
457 const int locked_contended = shared | MUTEX_STATE_BITS_LOCKED_CONTENDED;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800458 /*
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800459 * We want to go to sleep until the mutex is available, which
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100460 * requires promoting it to state 2 (CONTENDED). We need to
461 * swap in the new state value and then wait until somebody wakes us up.
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800462 *
David 'Digit' Turnere31bfae2011-11-15 15:47:02 +0100463 * __bionic_swap() returns the previous value. We swap 2 in and
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800464 * see if we got zero back; if so, we have acquired the lock. If
465 * not, another thread still holds the lock and we wait again.
466 *
467 * The second argument to the __futex_wait() call is compared
468 * against the current value. If it doesn't match, __futex_wait()
469 * returns immediately (otherwise, it sleeps for a time specified
470 * by the third argument; 0 means sleep forever). This ensures
471 * that the mutex is in state 2 when we go to sleep on it, which
472 * guarantees a wake-up call.
473 */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100474 while (__bionic_swap(locked_contended, &mutex->value) != unlocked)
475 __futex_wait_ex(&mutex->value, shared, locked_contended, 0);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800476 }
Andy McFaddenfcd00eb2010-05-28 13:31:45 -0700477 ANDROID_MEMBAR_FULL();
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800478}
479
480/*
481 * Release a non-recursive mutex. The caller is responsible for determining
482 * that we are in fact the owner of this lock.
483 */
484static __inline__ void
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100485_normal_unlock(pthread_mutex_t* mutex, int shared)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800486{
Andy McFaddenfcd00eb2010-05-28 13:31:45 -0700487 ANDROID_MEMBAR_FULL();
488
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800489 /*
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700490 * The mutex state will be 1 or (rarely) 2. We use an atomic decrement
David 'Digit' Turnere31bfae2011-11-15 15:47:02 +0100491 * to release the lock. __bionic_atomic_dec() returns the previous value;
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800492 * if it wasn't 1 we have to do some additional work.
493 */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100494 if (__bionic_atomic_dec(&mutex->value) != (shared|MUTEX_STATE_BITS_LOCKED_UNCONTENDED)) {
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800495 /*
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800496 * Start by releasing the lock. The decrement changed it from
497 * "contended lock" to "uncontended lock", which means we still
498 * hold it, and anybody who tries to sneak in will push it back
499 * to state 2.
500 *
501 * Once we set it to zero the lock is up for grabs. We follow
502 * this with a __futex_wake() to ensure that one of the waiting
503 * threads has a chance to grab it.
504 *
505 * This doesn't cause a race with the swap/wait pair in
506 * _normal_lock(), because the __futex_wait() call there will
507 * return immediately if the mutex value isn't 2.
508 */
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700509 mutex->value = shared;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800510
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800511 /*
512 * Wake up one waiting thread. We don't know which thread will be
513 * woken or when it'll start executing -- futexes make no guarantees
514 * here. There may not even be a thread waiting.
515 *
516 * The newly-woken thread will replace the 0 we just set above
517 * with 2, which means that when it eventually releases the mutex
518 * it will also call FUTEX_WAKE. This results in one extra wake
519 * call whenever a lock is contended, but lets us avoid forgetting
520 * anyone without requiring us to track the number of sleepers.
521 *
522 * It's possible for another thread to sneak in and grab the lock
523 * between the zero assignment above and the wake call below. If
524 * the new thread is "slow" and holds the lock for a while, we'll
525 * wake up a sleeper, which will swap in a 2 and then go back to
526 * sleep since the lock is still held. If the new thread is "fast",
527 * running to completion before we call wake, the thread we
528 * eventually wake will find an unlocked mutex and will execute.
529 * Either way we have correct behavior and nobody is orphaned on
530 * the wait queue.
531 */
David 'Digit' Turner6304d8b2010-06-02 18:12:12 -0700532 __futex_wake_ex(&mutex->value, shared, 1);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800533 }
534}
535
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100536/* This common inlined function is used to increment the counter of an
537 * errorcheck or recursive mutex.
538 *
539 * For errorcheck mutexes, it will return EDEADLK
540 * If the counter overflows, it will return EAGAIN
541 * Otherwise, it atomically increments the counter and returns 0
542 * after providing an acquire barrier.
543 *
544 * mtype is the current mutex type
545 * mvalue is the current mutex value (already loaded)
546 * mutex pointers to the mutex.
547 */
548static __inline__ __attribute__((always_inline)) int
549_recursive_increment(pthread_mutex_t* mutex, int mvalue, int mtype)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800550{
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100551 if (mtype == MUTEX_TYPE_BITS_ERRORCHECK) {
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100552 /* trying to re-lock a mutex we already acquired */
553 return EDEADLK;
554 }
555
556 /* Detect recursive lock overflow and return EAGAIN.
557 * This is safe because only the owner thread can modify the
David 'Digit' Turnerb57db752012-01-24 13:20:38 +0100558 * counter bits in the mutex value.
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100559 */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100560 if (MUTEX_COUNTER_BITS_WILL_OVERFLOW(mvalue)) {
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100561 return EAGAIN;
562 }
563
564 /* We own the mutex, but other threads are able to change
David 'Digit' Turnerb57db752012-01-24 13:20:38 +0100565 * the lower bits (e.g. promoting it to "contended"), so we
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100566 * need to use an atomic cmpxchg loop to update the counter.
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100567 */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100568 for (;;) {
569 /* increment counter, overflow was already checked */
570 int newval = mvalue + MUTEX_COUNTER_BITS_ONE;
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700571 if (__predict_true(__bionic_cmpxchg(mvalue, newval, &mutex->value) == 0)) {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100572 /* mutex is still locked, not need for a memory barrier */
573 return 0;
574 }
575 /* the value was changed, this happens when another thread changes
576 * the lower state bits from 1 to 2 to indicate contention. This
577 * cannot change the counter, so simply reload and try again.
578 */
579 mvalue = mutex->value;
580 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800581}
582
Mathias Agopian7c0c3792011-09-05 23:54:55 -0700583__LIBC_HIDDEN__
584int pthread_mutex_lock_impl(pthread_mutex_t *mutex)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800585{
Wink Savillea12c5442013-01-08 15:15:45 -0800586 int mvalue, mtype, tid, shared;
David 'Digit' Turnerba9c6f02010-03-10 16:44:08 -0800587
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700588 if (__predict_false(mutex == NULL))
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700589 return EINVAL;
David 'Digit' Turnerba9c6f02010-03-10 16:44:08 -0800590
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100591 mvalue = mutex->value;
592 mtype = (mvalue & MUTEX_TYPE_MASK);
593 shared = (mvalue & MUTEX_SHARED_MASK);
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800594
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700595 /* Handle normal case first */
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700596 if ( __predict_true(mtype == MUTEX_TYPE_BITS_NORMAL) ) {
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100597 _normal_lock(mutex, shared);
David 'Digit' Turnerba9c6f02010-03-10 16:44:08 -0800598 return 0;
599 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700600
601 /* Do we already own this recursive or error-check mutex ? */
Elliott Hughes40eabe22013-02-14 18:59:37 -0800602 tid = __get_thread()->tid;
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100603 if ( tid == MUTEX_OWNER_FROM_BITS(mvalue) )
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100604 return _recursive_increment(mutex, mvalue, mtype);
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700605
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100606 /* Add in shared state to avoid extra 'or' operations below */
David 'Digit' Turner6304d8b2010-06-02 18:12:12 -0700607 mtype |= shared;
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700608
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100609 /* First, if the mutex is unlocked, try to quickly acquire it.
610 * In the optimistic case where this works, set the state to 1 to
611 * indicate locked with no contention */
612 if (mvalue == mtype) {
613 int newval = MUTEX_OWNER_TO_BITS(tid) | mtype | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
614 if (__bionic_cmpxchg(mvalue, newval, &mutex->value) == 0) {
615 ANDROID_MEMBAR_FULL();
616 return 0;
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700617 }
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100618 /* argh, the value changed, reload before entering the loop */
619 mvalue = mutex->value;
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700620 }
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100621
622 for (;;) {
623 int newval;
624
625 /* if the mutex is unlocked, its value should be 'mtype' and
626 * we try to acquire it by setting its owner and state atomically.
627 * NOTE: We put the state to 2 since we _know_ there is contention
628 * when we are in this loop. This ensures all waiters will be
629 * unlocked.
630 */
631 if (mvalue == mtype) {
632 newval = MUTEX_OWNER_TO_BITS(tid) | mtype | MUTEX_STATE_BITS_LOCKED_CONTENDED;
633 /* TODO: Change this to __bionic_cmpxchg_acquire when we
634 * implement it to get rid of the explicit memory
635 * barrier below.
636 */
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700637 if (__predict_false(__bionic_cmpxchg(mvalue, newval, &mutex->value) != 0)) {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100638 mvalue = mutex->value;
639 continue;
640 }
641 ANDROID_MEMBAR_FULL();
642 return 0;
643 }
644
645 /* the mutex is already locked by another thread, if its state is 1
646 * we will change it to 2 to indicate contention. */
647 if (MUTEX_STATE_BITS_IS_LOCKED_UNCONTENDED(mvalue)) {
648 newval = MUTEX_STATE_BITS_FLIP_CONTENTION(mvalue); /* locked state 1 => state 2 */
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700649 if (__predict_false(__bionic_cmpxchg(mvalue, newval, &mutex->value) != 0)) {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100650 mvalue = mutex->value;
651 continue;
652 }
653 mvalue = newval;
654 }
655
656 /* wait until the mutex is unlocked */
657 __futex_wait_ex(&mutex->value, shared, mvalue, NULL);
658
659 mvalue = mutex->value;
660 }
661 /* NOTREACHED */
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800662}
663
Mathias Agopian7c0c3792011-09-05 23:54:55 -0700664int pthread_mutex_lock(pthread_mutex_t *mutex)
665{
666 int err = pthread_mutex_lock_impl(mutex);
667#ifdef PTHREAD_DEBUG
668 if (PTHREAD_DEBUG_ENABLED) {
669 if (!err) {
670 pthread_debug_mutex_lock_check(mutex);
671 }
672 }
673#endif
674 return err;
675}
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800676
Mathias Agopian7c0c3792011-09-05 23:54:55 -0700677__LIBC_HIDDEN__
678int pthread_mutex_unlock_impl(pthread_mutex_t *mutex)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800679{
Wink Savillea12c5442013-01-08 15:15:45 -0800680 int mvalue, mtype, tid, shared;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800681
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700682 if (__predict_false(mutex == NULL))
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700683 return EINVAL;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800684
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100685 mvalue = mutex->value;
686 mtype = (mvalue & MUTEX_TYPE_MASK);
687 shared = (mvalue & MUTEX_SHARED_MASK);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800688
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700689 /* Handle common case first */
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700690 if (__predict_true(mtype == MUTEX_TYPE_BITS_NORMAL)) {
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100691 _normal_unlock(mutex, shared);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800692 return 0;
693 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700694
695 /* Do we already own this recursive or error-check mutex ? */
Elliott Hughes40eabe22013-02-14 18:59:37 -0800696 tid = __get_thread()->tid;
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100697 if ( tid != MUTEX_OWNER_FROM_BITS(mvalue) )
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700698 return EPERM;
699
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100700 /* If the counter is > 0, we can simply decrement it atomically.
701 * Since other threads can mutate the lower state bits (and only the
702 * lower state bits), use a cmpxchg to do it.
703 */
704 if (!MUTEX_COUNTER_BITS_IS_ZERO(mvalue)) {
705 for (;;) {
706 int newval = mvalue - MUTEX_COUNTER_BITS_ONE;
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700707 if (__predict_true(__bionic_cmpxchg(mvalue, newval, &mutex->value) == 0)) {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100708 /* success: we still own the mutex, so no memory barrier */
709 return 0;
710 }
711 /* the value changed, so reload and loop */
712 mvalue = mutex->value;
713 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700714 }
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100715
716 /* the counter is 0, so we're going to unlock the mutex by resetting
717 * its value to 'unlocked'. We need to perform a swap in order
718 * to read the current state, which will be 2 if there are waiters
719 * to awake.
720 *
721 * TODO: Change this to __bionic_swap_release when we implement it
722 * to get rid of the explicit memory barrier below.
723 */
724 ANDROID_MEMBAR_FULL(); /* RELEASE BARRIER */
725 mvalue = __bionic_swap(mtype | shared | MUTEX_STATE_BITS_UNLOCKED, &mutex->value);
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700726
727 /* Wake one waiting thread, if any */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100728 if (MUTEX_STATE_BITS_IS_LOCKED_CONTENDED(mvalue)) {
David 'Digit' Turner6304d8b2010-06-02 18:12:12 -0700729 __futex_wake_ex(&mutex->value, shared, 1);
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700730 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700731 return 0;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800732}
733
Mathias Agopian7c0c3792011-09-05 23:54:55 -0700734int pthread_mutex_unlock(pthread_mutex_t *mutex)
735{
736#ifdef PTHREAD_DEBUG
737 if (PTHREAD_DEBUG_ENABLED) {
738 pthread_debug_mutex_unlock_check(mutex);
739 }
740#endif
741 return pthread_mutex_unlock_impl(mutex);
742}
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800743
Mathias Agopian7c0c3792011-09-05 23:54:55 -0700744__LIBC_HIDDEN__
745int pthread_mutex_trylock_impl(pthread_mutex_t *mutex)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800746{
Wink Savillea12c5442013-01-08 15:15:45 -0800747 int mvalue, mtype, tid, shared;
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700748
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700749 if (__predict_false(mutex == NULL))
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700750 return EINVAL;
751
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100752 mvalue = mutex->value;
753 mtype = (mvalue & MUTEX_TYPE_MASK);
754 shared = (mvalue & MUTEX_SHARED_MASK);
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700755
756 /* Handle common case first */
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700757 if ( __predict_true(mtype == MUTEX_TYPE_BITS_NORMAL) )
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800758 {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100759 if (__bionic_cmpxchg(shared|MUTEX_STATE_BITS_UNLOCKED,
760 shared|MUTEX_STATE_BITS_LOCKED_UNCONTENDED,
761 &mutex->value) == 0) {
Andy McFaddenfcd00eb2010-05-28 13:31:45 -0700762 ANDROID_MEMBAR_FULL();
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800763 return 0;
Andy McFaddenfcd00eb2010-05-28 13:31:45 -0700764 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700765
766 return EBUSY;
David 'Digit' Turnerba9c6f02010-03-10 16:44:08 -0800767 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700768
769 /* Do we already own this recursive or error-check mutex ? */
Elliott Hughes40eabe22013-02-14 18:59:37 -0800770 tid = __get_thread()->tid;
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100771 if ( tid == MUTEX_OWNER_FROM_BITS(mvalue) )
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100772 return _recursive_increment(mutex, mvalue, mtype);
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700773
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100774 /* Same as pthread_mutex_lock, except that we don't want to wait, and
775 * the only operation that can succeed is a single cmpxchg to acquire the
776 * lock if it is released / not owned by anyone. No need for a complex loop.
777 */
778 mtype |= shared | MUTEX_STATE_BITS_UNLOCKED;
779 mvalue = MUTEX_OWNER_TO_BITS(tid) | mtype | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700780
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700781 if (__predict_true(__bionic_cmpxchg(mtype, mvalue, &mutex->value) == 0)) {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100782 ANDROID_MEMBAR_FULL();
783 return 0;
784 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700785
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100786 return EBUSY;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800787}
788
Mathias Agopian7c0c3792011-09-05 23:54:55 -0700789int pthread_mutex_trylock(pthread_mutex_t *mutex)
790{
791 int err = pthread_mutex_trylock_impl(mutex);
792#ifdef PTHREAD_DEBUG
793 if (PTHREAD_DEBUG_ENABLED) {
794 if (!err) {
795 pthread_debug_mutex_lock_check(mutex);
796 }
797 }
798#endif
799 return err;
800}
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800801
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -0700802/* initialize 'ts' with the difference between 'abstime' and the current time
803 * according to 'clock'. Returns -1 if abstime already expired, or 0 otherwise.
804 */
805static int
806__timespec_to_absolute(struct timespec* ts, const struct timespec* abstime, clockid_t clock)
807{
808 clock_gettime(clock, ts);
809 ts->tv_sec = abstime->tv_sec - ts->tv_sec;
810 ts->tv_nsec = abstime->tv_nsec - ts->tv_nsec;
811 if (ts->tv_nsec < 0) {
812 ts->tv_sec--;
813 ts->tv_nsec += 1000000000;
814 }
David 'Digit' Turnerbc10cd22009-09-23 15:56:50 -0700815 if ((ts->tv_nsec < 0) || (ts->tv_sec < 0))
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -0700816 return -1;
817
818 return 0;
819}
820
821/* initialize 'abstime' to the current time according to 'clock' plus 'msecs'
822 * milliseconds.
823 */
824static void
825__timespec_to_relative_msec(struct timespec* abstime, unsigned msecs, clockid_t clock)
826{
827 clock_gettime(clock, abstime);
828 abstime->tv_sec += msecs/1000;
829 abstime->tv_nsec += (msecs%1000)*1000000;
830 if (abstime->tv_nsec >= 1000000000) {
831 abstime->tv_sec++;
832 abstime->tv_nsec -= 1000000000;
833 }
834}
835
Mathias Agopian7c0c3792011-09-05 23:54:55 -0700836__LIBC_HIDDEN__
837int pthread_mutex_lock_timeout_np_impl(pthread_mutex_t *mutex, unsigned msecs)
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -0700838{
839 clockid_t clock = CLOCK_MONOTONIC;
840 struct timespec abstime;
841 struct timespec ts;
Wink Savillea12c5442013-01-08 15:15:45 -0800842 int mvalue, mtype, tid, shared;
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -0700843
844 /* compute absolute expiration time */
845 __timespec_to_relative_msec(&abstime, msecs, clock);
846
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700847 if (__predict_false(mutex == NULL))
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700848 return EINVAL;
849
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100850 mvalue = mutex->value;
851 mtype = (mvalue & MUTEX_TYPE_MASK);
852 shared = (mvalue & MUTEX_SHARED_MASK);
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700853
854 /* Handle common case first */
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700855 if ( __predict_true(mtype == MUTEX_TYPE_BITS_NORMAL) )
David 'Digit' Turnerba9c6f02010-03-10 16:44:08 -0800856 {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100857 const int unlocked = shared | MUTEX_STATE_BITS_UNLOCKED;
858 const int locked_uncontended = shared | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
859 const int locked_contended = shared | MUTEX_STATE_BITS_LOCKED_CONTENDED;
860
861 /* fast path for uncontended lock. Note: MUTEX_TYPE_BITS_NORMAL is 0 */
862 if (__bionic_cmpxchg(unlocked, locked_uncontended, &mutex->value) == 0) {
Andy McFaddenfcd00eb2010-05-28 13:31:45 -0700863 ANDROID_MEMBAR_FULL();
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800864 return 0;
Andy McFaddenfcd00eb2010-05-28 13:31:45 -0700865 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700866
867 /* loop while needed */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100868 while (__bionic_swap(locked_contended, &mutex->value) != unlocked) {
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700869 if (__timespec_to_absolute(&ts, &abstime, clock) < 0)
870 return EBUSY;
871
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100872 __futex_wait_ex(&mutex->value, shared, locked_contended, &ts);
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800873 }
Andy McFaddenfcd00eb2010-05-28 13:31:45 -0700874 ANDROID_MEMBAR_FULL();
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700875 return 0;
David 'Digit' Turnerba9c6f02010-03-10 16:44:08 -0800876 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700877
878 /* Do we already own this recursive or error-check mutex ? */
Elliott Hughes40eabe22013-02-14 18:59:37 -0800879 tid = __get_thread()->tid;
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100880 if ( tid == MUTEX_OWNER_FROM_BITS(mvalue) )
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100881 return _recursive_increment(mutex, mvalue, mtype);
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700882
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100883 /* the following implements the same loop than pthread_mutex_lock_impl
884 * but adds checks to ensure that the operation never exceeds the
885 * absolute expiration time.
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700886 */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100887 mtype |= shared;
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700888
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100889 /* first try a quick lock */
890 if (mvalue == mtype) {
891 mvalue = MUTEX_OWNER_TO_BITS(tid) | mtype | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
Elliott Hughesd4e753f2013-07-16 12:45:46 -0700892 if (__predict_true(__bionic_cmpxchg(mtype, mvalue, &mutex->value) == 0)) {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100893 ANDROID_MEMBAR_FULL();
894 return 0;
895 }
896 mvalue = mutex->value;
897 }
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700898
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700899 for (;;) {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100900 struct timespec ts;
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700901
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100902 /* if the value is 'unlocked', try to acquire it directly */
903 /* NOTE: put state to 2 since we know there is contention */
904 if (mvalue == mtype) /* unlocked */ {
905 mvalue = MUTEX_OWNER_TO_BITS(tid) | mtype | MUTEX_STATE_BITS_LOCKED_CONTENDED;
906 if (__bionic_cmpxchg(mtype, mvalue, &mutex->value) == 0) {
907 ANDROID_MEMBAR_FULL();
908 return 0;
909 }
910 /* the value changed before we could lock it. We need to check
911 * the time to avoid livelocks, reload the value, then loop again. */
912 if (__timespec_to_absolute(&ts, &abstime, clock) < 0)
913 return EBUSY;
914
915 mvalue = mutex->value;
916 continue;
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700917 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700918
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100919 /* The value is locked. If 'uncontended', try to switch its state
920 * to 'contented' to ensure we get woken up later. */
921 if (MUTEX_STATE_BITS_IS_LOCKED_UNCONTENDED(mvalue)) {
922 int newval = MUTEX_STATE_BITS_FLIP_CONTENTION(mvalue);
923 if (__bionic_cmpxchg(mvalue, newval, &mutex->value) != 0) {
924 /* this failed because the value changed, reload it */
925 mvalue = mutex->value;
926 } else {
927 /* this succeeded, update mvalue */
928 mvalue = newval;
929 }
930 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700931
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100932 /* check time and update 'ts' */
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700933 if (__timespec_to_absolute(&ts, &abstime, clock) < 0)
934 return EBUSY;
935
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100936 /* Only wait to be woken up if the state is '2', otherwise we'll
937 * simply loop right now. This can happen when the second cmpxchg
938 * in our loop failed because the mutex was unlocked by another
939 * thread.
940 */
941 if (MUTEX_STATE_BITS_IS_LOCKED_CONTENDED(mvalue)) {
942 if (__futex_wait_ex(&mutex->value, shared, mvalue, &ts) == ETIMEDOUT) {
943 return EBUSY;
944 }
945 mvalue = mutex->value;
946 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -0700947 }
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100948 /* NOTREACHED */
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -0700949}
950
Mathias Agopian7c0c3792011-09-05 23:54:55 -0700951int pthread_mutex_lock_timeout_np(pthread_mutex_t *mutex, unsigned msecs)
952{
953 int err = pthread_mutex_lock_timeout_np_impl(mutex, msecs);
954#ifdef PTHREAD_DEBUG
955 if (PTHREAD_DEBUG_ENABLED) {
956 if (!err) {
957 pthread_debug_mutex_lock_check(mutex);
958 }
959 }
960#endif
961 return err;
962}
963
964int pthread_mutex_destroy(pthread_mutex_t *mutex)
965{
966 int ret;
967
968 /* use trylock to ensure that the mutex value is
969 * valid and is not already locked. */
970 ret = pthread_mutex_trylock_impl(mutex);
971 if (ret != 0)
972 return ret;
973
974 mutex->value = 0xdead10cc;
975 return 0;
976}
977
978
979
David 'Digit' Turneree7b0772010-03-18 14:07:42 -0700980int pthread_condattr_init(pthread_condattr_t *attr)
981{
982 if (attr == NULL)
983 return EINVAL;
984
985 *attr = PTHREAD_PROCESS_PRIVATE;
986 return 0;
987}
988
989int pthread_condattr_getpshared(pthread_condattr_t *attr, int *pshared)
990{
991 if (attr == NULL || pshared == NULL)
992 return EINVAL;
993
994 *pshared = *attr;
995 return 0;
996}
997
998int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared)
999{
1000 if (attr == NULL)
1001 return EINVAL;
1002
1003 if (pshared != PTHREAD_PROCESS_SHARED &&
1004 pshared != PTHREAD_PROCESS_PRIVATE)
1005 return EINVAL;
1006
1007 *attr = pshared;
1008 return 0;
1009}
1010
1011int pthread_condattr_destroy(pthread_condattr_t *attr)
1012{
1013 if (attr == NULL)
1014 return EINVAL;
1015
1016 *attr = 0xdeada11d;
1017 return 0;
1018}
1019
1020/* We use one bit in condition variable values as the 'shared' flag
1021 * The rest is a counter.
1022 */
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001023#define COND_SHARED_MASK 0x0001
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001024#define COND_COUNTER_INCREMENT 0x0002
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001025#define COND_COUNTER_MASK (~COND_SHARED_MASK)
1026
1027#define COND_IS_SHARED(c) (((c)->value & COND_SHARED_MASK) != 0)
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -07001028
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001029/* XXX *technically* there is a race condition that could allow
1030 * XXX a signal to be missed. If thread A is preempted in _wait()
1031 * XXX after unlocking the mutex and before waiting, and if other
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001032 * XXX threads call signal or broadcast UINT_MAX/2 times (exactly),
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001033 * XXX before thread A is scheduled again and calls futex_wait(),
1034 * XXX then the signal will be lost.
1035 */
1036
1037int pthread_cond_init(pthread_cond_t *cond,
1038 const pthread_condattr_t *attr)
1039{
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001040 if (cond == NULL)
1041 return EINVAL;
1042
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001043 cond->value = 0;
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001044
1045 if (attr != NULL && *attr == PTHREAD_PROCESS_SHARED)
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001046 cond->value |= COND_SHARED_MASK;
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001047
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001048 return 0;
1049}
1050
1051int pthread_cond_destroy(pthread_cond_t *cond)
1052{
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001053 if (cond == NULL)
1054 return EINVAL;
1055
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001056 cond->value = 0xdeadc04d;
1057 return 0;
1058}
1059
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001060/* This function is used by pthread_cond_broadcast and
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001061 * pthread_cond_signal to atomically decrement the counter
1062 * then wake-up 'counter' threads.
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001063 */
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001064static int
1065__pthread_cond_pulse(pthread_cond_t *cond, int counter)
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001066{
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001067 long flags;
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001068
Elliott Hughesd4e753f2013-07-16 12:45:46 -07001069 if (__predict_false(cond == NULL))
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001070 return EINVAL;
1071
1072 flags = (cond->value & ~COND_COUNTER_MASK);
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001073 for (;;) {
1074 long oldval = cond->value;
1075 long newval = ((oldval - COND_COUNTER_INCREMENT) & COND_COUNTER_MASK)
1076 | flags;
David 'Digit' Turnere31bfae2011-11-15 15:47:02 +01001077 if (__bionic_cmpxchg(oldval, newval, &cond->value) == 0)
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001078 break;
1079 }
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001080
Andy McFaddene2ac8982010-09-02 13:34:53 -07001081 /*
1082 * Ensure that all memory accesses previously made by this thread are
1083 * visible to the woken thread(s). On the other side, the "wait"
1084 * code will issue any necessary barriers when locking the mutex.
1085 *
1086 * This may not strictly be necessary -- if the caller follows
1087 * recommended practice and holds the mutex before signaling the cond
1088 * var, the mutex ops will provide correct semantics. If they don't
1089 * hold the mutex, they're subject to race conditions anyway.
1090 */
1091 ANDROID_MEMBAR_FULL();
1092
David 'Digit' Turner6304d8b2010-06-02 18:12:12 -07001093 __futex_wake_ex(&cond->value, COND_IS_SHARED(cond), counter);
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001094 return 0;
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001095}
1096
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001097int pthread_cond_broadcast(pthread_cond_t *cond)
1098{
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001099 return __pthread_cond_pulse(cond, INT_MAX);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001100}
1101
1102int pthread_cond_signal(pthread_cond_t *cond)
1103{
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001104 return __pthread_cond_pulse(cond, 1);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001105}
1106
1107int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
1108{
1109 return pthread_cond_timedwait(cond, mutex, NULL);
1110}
1111
1112int __pthread_cond_timedwait_relative(pthread_cond_t *cond,
1113 pthread_mutex_t * mutex,
1114 const struct timespec *reltime)
1115{
1116 int status;
1117 int oldvalue = cond->value;
1118
1119 pthread_mutex_unlock(mutex);
David 'Digit' Turner6304d8b2010-06-02 18:12:12 -07001120 status = __futex_wait_ex(&cond->value, COND_IS_SHARED(cond), oldvalue, reltime);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001121 pthread_mutex_lock(mutex);
1122
1123 if (status == (-ETIMEDOUT)) return ETIMEDOUT;
1124 return 0;
1125}
1126
1127int __pthread_cond_timedwait(pthread_cond_t *cond,
1128 pthread_mutex_t * mutex,
1129 const struct timespec *abstime,
1130 clockid_t clock)
1131{
1132 struct timespec ts;
1133 struct timespec * tsp;
1134
1135 if (abstime != NULL) {
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -07001136 if (__timespec_to_absolute(&ts, abstime, clock) < 0)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001137 return ETIMEDOUT;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001138 tsp = &ts;
1139 } else {
1140 tsp = NULL;
1141 }
1142
1143 return __pthread_cond_timedwait_relative(cond, mutex, tsp);
1144}
1145
1146int pthread_cond_timedwait(pthread_cond_t *cond,
1147 pthread_mutex_t * mutex,
1148 const struct timespec *abstime)
1149{
1150 return __pthread_cond_timedwait(cond, mutex, abstime, CLOCK_REALTIME);
1151}
1152
1153
Mathias Agopiana2f5e212009-07-13 15:00:46 -07001154/* this one exists only for backward binary compatibility */
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001155int pthread_cond_timedwait_monotonic(pthread_cond_t *cond,
1156 pthread_mutex_t * mutex,
1157 const struct timespec *abstime)
1158{
1159 return __pthread_cond_timedwait(cond, mutex, abstime, CLOCK_MONOTONIC);
1160}
1161
Mathias Agopiana2f5e212009-07-13 15:00:46 -07001162int pthread_cond_timedwait_monotonic_np(pthread_cond_t *cond,
1163 pthread_mutex_t * mutex,
1164 const struct timespec *abstime)
1165{
1166 return __pthread_cond_timedwait(cond, mutex, abstime, CLOCK_MONOTONIC);
1167}
1168
1169int pthread_cond_timedwait_relative_np(pthread_cond_t *cond,
1170 pthread_mutex_t * mutex,
1171 const struct timespec *reltime)
1172{
1173 return __pthread_cond_timedwait_relative(cond, mutex, reltime);
1174}
1175
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001176int pthread_cond_timeout_np(pthread_cond_t *cond,
1177 pthread_mutex_t * mutex,
1178 unsigned msecs)
1179{
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001180 struct timespec ts;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001181
1182 ts.tv_sec = msecs / 1000;
1183 ts.tv_nsec = (msecs % 1000) * 1000000;
1184
Matthieu CASTETa4e67f42008-12-27 00:04:10 +01001185 return __pthread_cond_timedwait_relative(cond, mutex, &ts);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001186}
1187
1188
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001189/* NOTE: this implementation doesn't support a init function that throws a C++ exception
1190 * or calls fork()
1191 */
Elliott Hughes9d23e042013-02-15 19:21:51 -08001192int pthread_once( pthread_once_t* once_control, void (*init_routine)(void) )
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001193{
Andy McFaddenb1c9cc22010-09-23 12:30:12 -07001194 volatile pthread_once_t* ocptr = once_control;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001195
David 'Digit' Turner6c6de442011-12-07 12:20:44 +01001196 /* PTHREAD_ONCE_INIT is 0, we use the following bit flags
1197 *
1198 * bit 0 set -> initialization is under way
1199 * bit 1 set -> initialization is complete
1200 */
1201#define ONCE_INITIALIZING (1 << 0)
1202#define ONCE_COMPLETED (1 << 1)
1203
1204 /* First check if the once is already initialized. This will be the common
1205 * case and we want to make this as fast as possible. Note that this still
1206 * requires a load_acquire operation here to ensure that all the
1207 * stores performed by the initialization function are observable on
1208 * this CPU after we exit.
1209 */
Elliott Hughesd4e753f2013-07-16 12:45:46 -07001210 if (__predict_true((*ocptr & ONCE_COMPLETED) != 0)) {
David 'Digit' Turner6c6de442011-12-07 12:20:44 +01001211 ANDROID_MEMBAR_FULL();
1212 return 0;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001213 }
David 'Digit' Turner6c6de442011-12-07 12:20:44 +01001214
1215 for (;;) {
1216 /* Try to atomically set the INITIALIZING flag.
1217 * This requires a cmpxchg loop, and we may need
Elliott Hughesbfeab1b2012-09-05 17:47:37 -07001218 * to exit prematurely if we detect that
David 'Digit' Turner6c6de442011-12-07 12:20:44 +01001219 * COMPLETED is now set.
1220 */
1221 int32_t oldval, newval;
1222
1223 do {
1224 oldval = *ocptr;
1225 if ((oldval & ONCE_COMPLETED) != 0)
1226 break;
1227
1228 newval = oldval | ONCE_INITIALIZING;
1229 } while (__bionic_cmpxchg(oldval, newval, ocptr) != 0);
1230
1231 if ((oldval & ONCE_COMPLETED) != 0) {
1232 /* We detected that COMPLETED was set while in our loop */
1233 ANDROID_MEMBAR_FULL();
1234 return 0;
1235 }
1236
1237 if ((oldval & ONCE_INITIALIZING) == 0) {
1238 /* We got there first, we can jump out of the loop to
1239 * handle the initialization */
1240 break;
1241 }
1242
1243 /* Another thread is running the initialization and hasn't completed
1244 * yet, so wait for it, then try again. */
1245 __futex_wait_ex(ocptr, 0, oldval, NULL);
1246 }
1247
1248 /* call the initialization function. */
1249 (*init_routine)();
1250
1251 /* Do a store_release indicating that initialization is complete */
1252 ANDROID_MEMBAR_FULL();
1253 *ocptr = ONCE_COMPLETED;
1254
1255 /* Wake up any waiters, if any */
1256 __futex_wake_ex(ocptr, 0, INT_MAX);
1257
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001258 return 0;
1259}
André Goddard Rosa78c1c042010-05-19 23:17:16 -03001260
Elliott Hughes40eabe22013-02-14 18:59:37 -08001261pid_t __pthread_gettid(pthread_t thid) {
1262 pthread_internal_t* thread = (pthread_internal_t*) thid;
1263 return thread->tid;
Glenn Kastend53cae02011-07-11 15:41:28 -07001264}
Jean-Baptiste Querufaca92f2012-03-26 15:25:19 -07001265
Elliott Hughes40eabe22013-02-14 18:59:37 -08001266int __pthread_settid(pthread_t thid, pid_t tid) {
1267 if (thid == 0) {
1268 return EINVAL;
1269 }
Jean-Baptiste Querufaca92f2012-03-26 15:25:19 -07001270
Elliott Hughes40eabe22013-02-14 18:59:37 -08001271 pthread_internal_t* thread = (pthread_internal_t*) thid;
1272 thread->tid = tid;
Jean-Baptiste Querufaca92f2012-03-26 15:25:19 -07001273
Elliott Hughes40eabe22013-02-14 18:59:37 -08001274 return 0;
Jean-Baptiste Querufaca92f2012-03-26 15:25:19 -07001275}