blob: 3564c7321856fd0a856f353c0ceb38253c20201b [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>
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080034#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"
Elliott Hughesad88a082012-10-24 18:37:21 -070040#include "bionic_ssp.h"
Pierre Peifferd0c884d2012-02-22 16:40:15 +010041#include "bionic_tls.h"
Elliott Hughes1e980b62013-01-17 18:36:06 -080042#include "debug_format.h"
Pierre Peifferd0c884d2012-02-22 16:40:15 +010043#include "pthread_internal.h"
44#include "thread_private.h"
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080045
Mathias Agopian7c0c3792011-09-05 23:54:55 -070046extern void pthread_debug_mutex_lock_check(pthread_mutex_t *mutex);
47extern void pthread_debug_mutex_unlock_check(pthread_mutex_t *mutex);
48
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080049extern int __pthread_clone(int (*fn)(void*), void *child_stack, int flags, void *arg);
50extern void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode);
51extern void _exit_thread(int retCode);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080052
David 'Digit' Turner6304d8b2010-06-02 18:12:12 -070053int __futex_wake_ex(volatile void *ftx, int pshared, int val)
54{
55 return __futex_syscall3(ftx, pshared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, val);
56}
57
58int __futex_wait_ex(volatile void *ftx, int pshared, int val, const struct timespec *timeout)
59{
60 return __futex_syscall4(ftx, pshared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, val, timeout);
61}
62
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -070063#define __likely(cond) __builtin_expect(!!(cond), 1)
64#define __unlikely(cond) __builtin_expect(!!(cond), 0)
65
Bruce Beare8e551a62011-03-28 09:47:35 -070066#ifdef __i386__
67#define ATTRIBUTES __attribute__((noinline)) __attribute__((fastcall))
68#else
69#define ATTRIBUTES __attribute__((noinline))
70#endif
71
72void ATTRIBUTES _thread_created_hook(pid_t thread_id);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080073
Pierre Peifferd0c884d2012-02-22 16:40:15 +010074static const int kPthreadInitFailed = 1;
75
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080076static pthread_mutex_t mmap_lock = PTHREAD_MUTEX_INITIALIZER;
77
Elliott Hughes44b53ad2013-02-11 20:18:47 +000078__LIBC_HIDDEN__ pthread_internal_t* gThreadList = NULL;
79__LIBC_HIDDEN__ pthread_mutex_t gThreadListLock = PTHREAD_MUTEX_INITIALIZER;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080080static pthread_mutex_t gDebuggerNotificationLock = PTHREAD_MUTEX_INITIALIZER;
81
Elliott Hughes4f251be2012-11-01 16:33:29 -070082static void _pthread_internal_remove_locked(pthread_internal_t* thread) {
83 if (thread->next != NULL) {
Elliott Hughesbfeab1b2012-09-05 17:47:37 -070084 thread->next->prev = thread->prev;
Elliott Hughes4f251be2012-11-01 16:33:29 -070085 }
86 if (thread->prev != NULL) {
87 thread->prev->next = thread->next;
88 } else {
89 gThreadList = thread->next;
90 }
91
92 // The main thread is not heap-allocated. See __libc_init_tls for the declaration,
93 // and __libc_init_common for the point where it's added to the thread list.
94 if (thread->allocated_on_heap) {
95 free(thread);
96 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080097}
98
Elliott Hughes4f251be2012-11-01 16:33:29 -070099static void _pthread_internal_remove(pthread_internal_t* thread) {
100 pthread_mutex_lock(&gThreadListLock);
101 _pthread_internal_remove_locked(thread);
102 pthread_mutex_unlock(&gThreadListLock);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800103}
104
Elliott Hughes4f251be2012-11-01 16:33:29 -0700105__LIBC_ABI_PRIVATE__ void _pthread_internal_add(pthread_internal_t* thread) {
106 pthread_mutex_lock(&gThreadListLock);
Elliott Hughesbfeab1b2012-09-05 17:47:37 -0700107
Elliott Hughes4f251be2012-11-01 16:33:29 -0700108 // We insert at the head.
109 thread->next = gThreadList;
110 thread->prev = NULL;
111 if (thread->next != NULL) {
112 thread->next->prev = thread;
113 }
114 gThreadList = thread;
Elliott Hughesbfeab1b2012-09-05 17:47:37 -0700115
Elliott Hughes4f251be2012-11-01 16:33:29 -0700116 pthread_mutex_unlock(&gThreadListLock);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800117}
118
Evgeniy Stepanov1a78fbb2012-03-22 18:01:53 +0400119__LIBC_ABI_PRIVATE__ pthread_internal_t*
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800120__get_thread(void)
121{
122 void** tls = (void**)__get_tls();
123
124 return (pthread_internal_t*) tls[TLS_SLOT_THREAD_ID];
125}
126
127
128void*
129__get_stack_base(int *p_stack_size)
130{
131 pthread_internal_t* thread = __get_thread();
132
133 *p_stack_size = thread->attr.stack_size;
134 return thread->attr.stack_base;
135}
136
137
Elliott Hughes5419b942012-10-16 15:54:46 -0700138void __init_tls(void** tls, void* thread) {
139 ((pthread_internal_t*) thread)->tls = tls;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800140
Elliott Hughes5419b942012-10-16 15:54:46 -0700141 // Zero-initialize all the slots.
142 for (size_t i = 0; i < BIONIC_TLS_SLOTS; ++i) {
143 tls[i] = NULL;
144 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800145
Elliott Hughesad88a082012-10-24 18:37:21 -0700146 // Slot 0 must point to itself. The x86 Linux kernel reads the TLS from %fs:0.
Elliott Hughesd3920b32013-02-07 18:39:34 -0800147 tls[TLS_SLOT_SELF] = tls;
Elliott Hughes5419b942012-10-16 15:54:46 -0700148 tls[TLS_SLOT_THREAD_ID] = thread;
Elliott Hughesd3920b32013-02-07 18:39:34 -0800149 // GCC looks in the TLS for the stack guard on x86, so copy it there from our global.
150 tls[TLS_SLOT_STACK_GUARD] = (void*) __stack_chk_guard;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800151
Elliott Hughes5419b942012-10-16 15:54:46 -0700152 __set_tls((void*) tls);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800153}
154
155
156/*
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100157 * This trampoline is called from the assembly _pthread_clone() function.
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800158 */
159void __thread_entry(int (*func)(void*), void *arg, void **tls)
160{
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800161 // Wait for our creating thread to release us. This lets it have time to
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100162 // notify gdb about this thread before we start doing anything.
Andy McFaddene2ac8982010-09-02 13:34:53 -0700163 //
164 // This also provides the memory barrier needed to ensure that all memory
165 // accesses previously made by the creating thread are visible to us.
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100166 pthread_mutex_t* start_mutex = (pthread_mutex_t*) &tls[TLS_SLOT_SELF];
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800167 pthread_mutex_lock(start_mutex);
168 pthread_mutex_destroy(start_mutex);
169
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100170 pthread_internal_t* thread = (pthread_internal_t*) tls[TLS_SLOT_THREAD_ID];
171 __init_tls(tls, thread);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800172
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100173 if ((thread->internal_flags & kPthreadInitFailed) != 0) {
174 pthread_exit(NULL);
175 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800176
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100177 int result = func(arg);
178 pthread_exit((void*) result);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800179}
180
Dave Burke88f1ea82012-09-17 20:37:38 -0700181#include <private/logd.h>
182
Evgeniy Stepanov1a78fbb2012-03-22 18:01:53 +0400183__LIBC_ABI_PRIVATE__
Elliott Hughes6d339182013-02-12 16:36:04 -0800184int _init_thread(pthread_internal_t* thread, pid_t kernel_id, bool add_to_thread_list) {
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100185 int error = 0;
186
Xi Wangae8eb742012-10-27 02:02:01 -0400187 thread->kernel_id = kernel_id;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800188
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100189 // Set the scheduling policy/priority of the thread.
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800190 if (thread->attr.sched_policy != SCHED_NORMAL) {
191 struct sched_param param;
192 param.sched_priority = thread->attr.sched_priority;
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100193 if (sched_setscheduler(kernel_id, thread->attr.sched_policy, &param) == -1) {
Xi Wangae8eb742012-10-27 02:02:01 -0400194 // For backwards compatibility reasons, we just warn about failures here.
195 // error = errno;
Dave Burke88f1ea82012-09-17 20:37:38 -0700196 const char* msg = "pthread_create sched_setscheduler call failed: %s\n";
Elliott Hughes1e980b62013-01-17 18:36:06 -0800197 __libc_format_log(ANDROID_LOG_WARN, "libc", msg, strerror(errno));
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100198 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800199 }
200
201 pthread_cond_init(&thread->join_cond, NULL);
202 thread->join_count = 0;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800203 thread->cleanup_stack = NULL;
204
Elliott Hughesbfeab1b2012-09-05 17:47:37 -0700205 if (add_to_thread_list) {
206 _pthread_internal_add(thread);
207 }
208
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100209 return error;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800210}
211
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800212static void *mkstack(size_t size, size_t guard_size)
213{
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800214 pthread_mutex_lock(&mmap_lock);
215
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100216 int prot = PROT_READ | PROT_WRITE;
217 int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
Elliott Hughes9c3eca72012-05-08 13:26:28 -0700218 void* stack = mmap(NULL, size, prot, flags, -1, 0);
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100219 if (stack == MAP_FAILED) {
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800220 stack = NULL;
221 goto done;
222 }
223
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100224 if (mprotect(stack, guard_size, PROT_NONE) == -1) {
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800225 munmap(stack, size);
226 stack = NULL;
227 goto done;
228 }
229
230done:
231 pthread_mutex_unlock(&mmap_lock);
232 return stack;
233}
234
235/*
Andy McFaddene2ac8982010-09-02 13:34:53 -0700236 * Create a new thread. The thread's stack is laid out like so:
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800237 *
238 * +---------------------------+
239 * | pthread_internal_t |
240 * +---------------------------+
241 * | |
242 * | TLS area |
243 * | |
244 * +---------------------------+
245 * | |
246 * . .
247 * . stack area .
248 * . .
249 * | |
250 * +---------------------------+
251 * | guard page |
252 * +---------------------------+
253 *
254 * note that TLS[0] must be a pointer to itself, this is required
255 * by the thread-local storage implementation of the x86 Linux
256 * kernel, where the TLS pointer is read by reading fs:[0]
257 */
258int pthread_create(pthread_t *thread_out, pthread_attr_t const * attr,
259 void *(*start_routine)(void *), void * arg)
260{
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100261 int old_errno = errno;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800262
263 /* this will inform the rest of the C library that at least one thread
264 * was created. this will enforce certain functions to acquire/release
265 * locks (e.g. atexit()) to protect shared global structures.
266 *
267 * this works because pthread_create() is not called by the C library
268 * initialization routine that sets up the main thread's data structures.
269 */
270 __isthreaded = 1;
271
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100272 pthread_internal_t* thread = calloc(sizeof(*thread), 1);
273 if (thread == NULL) {
Elliott Hughes3e898472013-02-12 16:40:24 +0000274 return EAGAIN;
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100275 }
Elliott Hughes4f251be2012-11-01 16:33:29 -0700276 thread->allocated_on_heap = true;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800277
278 if (attr == NULL) {
Elliott Hughes6d339182013-02-12 16:36:04 -0800279 pthread_attr_init(&thread->attr);
280 } else {
281 thread->attr = *attr;
282 attr = NULL; // Prevent misuse below.
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800283 }
284
Elliott Hughes6d339182013-02-12 16:36:04 -0800285 // Make sure the stack size is PAGE_SIZE aligned.
286 size_t stack_size = (thread->attr.stack_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
287
288 if (thread->attr.stack_base == NULL) {
289 // The caller didn't provide a stack, so allocate one.
290 thread->attr.stack_base = mkstack(stack_size, thread->attr.guard_size);
291 if (thread->attr.stack_base == NULL) {
Elliott Hughes4f251be2012-11-01 16:33:29 -0700292 free(thread);
Elliott Hughes3e898472013-02-12 16:40:24 +0000293 return EAGAIN;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800294 }
Elliott Hughes6d339182013-02-12 16:36:04 -0800295 } else {
296 // The caller did provide a stack, so remember we're not supposed to free it.
297 thread->attr.flags |= PTHREAD_ATTR_FLAG_USER_STACK;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800298 }
299
Elliott Hughes6d339182013-02-12 16:36:04 -0800300 // Make room for TLS.
301 void** tls = (void**)((uint8_t*)(thread->attr.stack_base) + stack_size - BIONIC_TLS_SLOTS * sizeof(void*));
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800302
303 // Create a mutex for the thread in TLS_SLOT_SELF to wait on once it starts so we can keep
304 // it from doing anything until after we notify the debugger about it
Andy McFaddene2ac8982010-09-02 13:34:53 -0700305 //
306 // This also provides the memory barrier we need to ensure that all
307 // memory accesses previously performed by this thread are visible to
308 // the new thread.
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100309 pthread_mutex_t* start_mutex = (pthread_mutex_t*) &tls[TLS_SLOT_SELF];
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800310 pthread_mutex_init(start_mutex, NULL);
311 pthread_mutex_lock(start_mutex);
312
313 tls[TLS_SLOT_THREAD_ID] = thread;
314
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100315 int flags = CLONE_FILES | CLONE_FS | CLONE_VM | CLONE_SIGHAND |
316 CLONE_THREAD | CLONE_SYSVSEM | CLONE_DETACHED;
317 int tid = __pthread_clone((int(*)(void*))start_routine, tls, flags, arg);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800318
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100319 if (tid < 0) {
320 int clone_errno = errno;
321 pthread_mutex_unlock(start_mutex);
Elliott Hughes6d339182013-02-12 16:36:04 -0800322 if ((thread->attr.flags & PTHREAD_ATTR_FLAG_USER_STACK) == 0) {
323 munmap(thread->attr.stack_base, stack_size);
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100324 }
Elliott Hughes4f251be2012-11-01 16:33:29 -0700325 free(thread);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800326 errno = old_errno;
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100327 return clone_errno;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800328 }
329
Elliott Hughes6d339182013-02-12 16:36:04 -0800330 int init_errno = _init_thread(thread, tid, true);
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100331 if (init_errno != 0) {
332 // Mark the thread detached and let its __thread_entry run to
333 // completion. (It'll just exit immediately, cleaning up its resources.)
334 thread->internal_flags |= kPthreadInitFailed;
335 thread->attr.flags |= PTHREAD_ATTR_FLAG_DETACHED;
336 pthread_mutex_unlock(start_mutex);
337 errno = old_errno;
338 return init_errno;
339 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800340
Pierre Peifferd0c884d2012-02-22 16:40:15 +0100341 // Notify any debuggers about the new thread.
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800342 pthread_mutex_lock(&gDebuggerNotificationLock);
343 _thread_created_hook(tid);
344 pthread_mutex_unlock(&gDebuggerNotificationLock);
345
Jurijs Oniscuks2932f042012-07-05 14:57:38 +0200346 // Publish the pthread_t and let the thread run.
347 *thread_out = (pthread_t) thread;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800348 pthread_mutex_unlock(start_mutex);
349
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800350 return 0;
351}
352
353
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800354/* CAVEAT: our implementation of pthread_cleanup_push/pop doesn't support C++ exceptions
355 * and thread cancelation
356 */
357
358void __pthread_cleanup_push( __pthread_cleanup_t* c,
359 __pthread_cleanup_func_t routine,
360 void* arg )
361{
362 pthread_internal_t* thread = __get_thread();
363
364 c->__cleanup_routine = routine;
365 c->__cleanup_arg = arg;
366 c->__cleanup_prev = thread->cleanup_stack;
367 thread->cleanup_stack = c;
368}
369
370void __pthread_cleanup_pop( __pthread_cleanup_t* c, int execute )
371{
372 pthread_internal_t* thread = __get_thread();
373
374 thread->cleanup_stack = c->__cleanup_prev;
375 if (execute)
376 c->__cleanup_routine(c->__cleanup_arg);
377}
378
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800379void pthread_exit(void * retval)
380{
381 pthread_internal_t* thread = __get_thread();
382 void* stack_base = thread->attr.stack_base;
383 int stack_size = thread->attr.stack_size;
384 int user_stack = (thread->attr.flags & PTHREAD_ATTR_FLAG_USER_STACK) != 0;
Jack Rene480fc82011-09-21 12:44:11 +0200385 sigset_t mask;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800386
387 // call the cleanup handlers first
388 while (thread->cleanup_stack) {
389 __pthread_cleanup_t* c = thread->cleanup_stack;
390 thread->cleanup_stack = c->__cleanup_prev;
391 c->__cleanup_routine(c->__cleanup_arg);
392 }
393
394 // call the TLS destructors, it is important to do that before removing this
395 // thread from the global list. this will ensure that if someone else deletes
396 // a TLS key, the corresponding value will be set to NULL in this thread's TLS
397 // space (see pthread_key_delete)
398 pthread_key_clean_all();
399
400 // if the thread is detached, destroy the pthread_internal_t
Sergey Melnikov10ce9692012-10-26 14:06:43 +0400401 // otherwise, keep it in memory and signal any joiners.
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800402 if (thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) {
403 _pthread_internal_remove(thread);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800404 } else {
Bjorn Andersson0753dc62012-05-03 17:12:39 -0700405 pthread_mutex_lock(&gThreadListLock);
406
407 /* make sure that the thread struct doesn't have stale pointers to a stack that
408 * will be unmapped after the exit call below.
409 */
410 if (!user_stack) {
411 thread->attr.stack_base = NULL;
412 thread->attr.stack_size = 0;
413 thread->tls = NULL;
414 }
415
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800416 /* the join_count field is used to store the number of threads waiting for
417 * the termination of this thread with pthread_join(),
418 *
419 * if it is positive we need to signal the waiters, and we do not touch
420 * the count (it will be decremented by the waiters, the last one will
421 * also remove/free the thread structure
422 *
423 * if it is zero, we set the count value to -1 to indicate that the
424 * thread is in 'zombie' state: it has stopped executing, and its stack
425 * is gone (as well as its TLS area). when another thread calls pthread_join()
426 * on it, it will immediately free the thread and return.
427 */
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800428 thread->return_value = retval;
429 if (thread->join_count > 0) {
430 pthread_cond_broadcast(&thread->join_cond);
431 } else {
432 thread->join_count = -1; /* zombie thread */
433 }
434 pthread_mutex_unlock(&gThreadListLock);
435 }
436
Jack Rene480fc82011-09-21 12:44:11 +0200437 sigfillset(&mask);
438 sigdelset(&mask, SIGSEGV);
439 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
440
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800441 // destroy the thread stack
442 if (user_stack)
443 _exit_thread((int)retval);
444 else
445 _exit_with_stack_teardown(stack_base, stack_size, (int)retval);
446}
447
448int pthread_join(pthread_t thid, void ** ret_val)
449{
450 pthread_internal_t* thread = (pthread_internal_t*)thid;
Elliott Hughes14f19592012-10-29 10:19:44 -0700451 if (thid == pthread_self()) {
452 return EDEADLK;
453 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800454
455 // check that the thread still exists and is not detached
456 pthread_mutex_lock(&gThreadListLock);
457
Elliott Hughes14f19592012-10-29 10:19:44 -0700458 for (thread = gThreadList; thread != NULL; thread = thread->next) {
459 if (thread == (pthread_internal_t*)thid) {
André Goddard Rosaa28336c2010-02-05 16:21:07 -0200460 goto FoundIt;
Elliott Hughes14f19592012-10-29 10:19:44 -0700461 }
462 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800463
André Goddard Rosaa28336c2010-02-05 16:21:07 -0200464 pthread_mutex_unlock(&gThreadListLock);
465 return ESRCH;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800466
André Goddard Rosaa28336c2010-02-05 16:21:07 -0200467FoundIt:
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800468 if (thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) {
469 pthread_mutex_unlock(&gThreadListLock);
470 return EINVAL;
471 }
472
473 /* wait for thread death when needed
474 *
475 * if the 'join_count' is negative, this is a 'zombie' thread that
476 * is already dead and without stack/TLS
477 *
478 * otherwise, we need to increment 'join-count' and wait to be signaled
479 */
Elliott Hughes14f19592012-10-29 10:19:44 -0700480 int count = thread->join_count;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800481 if (count >= 0) {
482 thread->join_count += 1;
483 pthread_cond_wait( &thread->join_cond, &gThreadListLock );
484 count = --thread->join_count;
485 }
Sergey Melnikov10ce9692012-10-26 14:06:43 +0400486 if (ret_val) {
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800487 *ret_val = thread->return_value;
Sergey Melnikov10ce9692012-10-26 14:06:43 +0400488 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800489
490 /* remove thread descriptor when we're the last joiner or when the
491 * thread was already a zombie.
492 */
493 if (count <= 0) {
494 _pthread_internal_remove_locked(thread);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800495 }
496 pthread_mutex_unlock(&gThreadListLock);
497 return 0;
498}
499
500int pthread_detach( pthread_t thid )
501{
502 pthread_internal_t* thread;
503 int result = 0;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800504
505 pthread_mutex_lock(&gThreadListLock);
Sergey Melnikov10ce9692012-10-26 14:06:43 +0400506 for (thread = gThreadList; thread != NULL; thread = thread->next) {
507 if (thread == (pthread_internal_t*)thid) {
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800508 goto FoundIt;
Sergey Melnikov10ce9692012-10-26 14:06:43 +0400509 }
510 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800511
512 result = ESRCH;
513 goto Exit;
514
515FoundIt:
Sergey Melnikov10ce9692012-10-26 14:06:43 +0400516 if (thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) {
517 result = EINVAL; // Already detached.
518 goto Exit;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800519 }
Sergey Melnikov10ce9692012-10-26 14:06:43 +0400520
521 if (thread->join_count > 0) {
522 result = 0; // Already being joined; silently do nothing, like glibc.
523 goto Exit;
524 }
525
526 thread->attr.flags |= PTHREAD_ATTR_FLAG_DETACHED;
527
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800528Exit:
529 pthread_mutex_unlock(&gThreadListLock);
530 return result;
531}
532
533pthread_t pthread_self(void)
534{
535 return (pthread_t)__get_thread();
536}
537
538int pthread_equal(pthread_t one, pthread_t two)
539{
540 return (one == two ? 1 : 0);
541}
542
543int pthread_getschedparam(pthread_t thid, int * policy,
544 struct sched_param * param)
545{
546 int old_errno = errno;
547
548 pthread_internal_t * thread = (pthread_internal_t *)thid;
549 int err = sched_getparam(thread->kernel_id, param);
550 if (!err) {
551 *policy = sched_getscheduler(thread->kernel_id);
552 } else {
553 err = errno;
554 errno = old_errno;
555 }
556 return err;
557}
558
559int pthread_setschedparam(pthread_t thid, int policy,
560 struct sched_param const * param)
561{
562 pthread_internal_t * thread = (pthread_internal_t *)thid;
563 int old_errno = errno;
564 int ret;
565
566 ret = sched_setscheduler(thread->kernel_id, policy, param);
567 if (ret < 0) {
568 ret = errno;
569 errno = old_errno;
570 }
571 return ret;
572}
573
574
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800575/* a mutex is implemented as a 32-bit integer holding the following fields
576 *
577 * bits: name description
578 * 31-16 tid owner thread's kernel id (recursive and errorcheck only)
579 * 15-14 type mutex type
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700580 * 13 shared process-shared flag
581 * 12-2 counter counter of recursive mutexes
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800582 * 1-0 state lock state (0, 1 or 2)
583 */
584
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100585/* Convenience macro, creates a mask of 'bits' bits that starts from
586 * the 'shift'-th least significant bit in a 32-bit word.
587 *
588 * Examples: FIELD_MASK(0,4) -> 0xf
589 * FIELD_MASK(16,9) -> 0x1ff0000
590 */
591#define FIELD_MASK(shift,bits) (((1 << (bits))-1) << (shift))
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800592
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100593/* This one is used to create a bit pattern from a given field value */
594#define FIELD_TO_BITS(val,shift,bits) (((val) & ((1 << (bits))-1)) << (shift))
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100595
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100596/* And this one does the opposite, i.e. extract a field's value from a bit pattern */
597#define FIELD_FROM_BITS(val,shift,bits) (((val) >> (shift)) & ((1 << (bits))-1))
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800598
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100599/* Mutex state:
600 *
601 * 0 for unlocked
602 * 1 for locked, no waiters
603 * 2 for locked, maybe waiters
604 */
605#define MUTEX_STATE_SHIFT 0
606#define MUTEX_STATE_LEN 2
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800607
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100608#define MUTEX_STATE_MASK FIELD_MASK(MUTEX_STATE_SHIFT, MUTEX_STATE_LEN)
609#define MUTEX_STATE_FROM_BITS(v) FIELD_FROM_BITS(v, MUTEX_STATE_SHIFT, MUTEX_STATE_LEN)
610#define MUTEX_STATE_TO_BITS(v) FIELD_TO_BITS(v, MUTEX_STATE_SHIFT, MUTEX_STATE_LEN)
611
612#define MUTEX_STATE_UNLOCKED 0 /* must be 0 to match __PTHREAD_MUTEX_INIT_VALUE */
613#define MUTEX_STATE_LOCKED_UNCONTENDED 1 /* must be 1 due to atomic dec in unlock operation */
614#define MUTEX_STATE_LOCKED_CONTENDED 2 /* must be 1 + LOCKED_UNCONTENDED due to atomic dec */
615
616#define MUTEX_STATE_FROM_BITS(v) FIELD_FROM_BITS(v, MUTEX_STATE_SHIFT, MUTEX_STATE_LEN)
617#define MUTEX_STATE_TO_BITS(v) FIELD_TO_BITS(v, MUTEX_STATE_SHIFT, MUTEX_STATE_LEN)
618
619#define MUTEX_STATE_BITS_UNLOCKED MUTEX_STATE_TO_BITS(MUTEX_STATE_UNLOCKED)
620#define MUTEX_STATE_BITS_LOCKED_UNCONTENDED MUTEX_STATE_TO_BITS(MUTEX_STATE_LOCKED_UNCONTENDED)
621#define MUTEX_STATE_BITS_LOCKED_CONTENDED MUTEX_STATE_TO_BITS(MUTEX_STATE_LOCKED_CONTENDED)
622
623/* return true iff the mutex if locked with no waiters */
624#define MUTEX_STATE_BITS_IS_LOCKED_UNCONTENDED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_UNCONTENDED)
625
626/* return true iff the mutex if locked with maybe waiters */
627#define MUTEX_STATE_BITS_IS_LOCKED_CONTENDED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_CONTENDED)
628
629/* used to flip from LOCKED_UNCONTENDED to LOCKED_CONTENDED */
630#define MUTEX_STATE_BITS_FLIP_CONTENTION(v) ((v) ^ (MUTEX_STATE_BITS_LOCKED_CONTENDED ^ MUTEX_STATE_BITS_LOCKED_UNCONTENDED))
631
632/* Mutex counter:
633 *
634 * We need to check for overflow before incrementing, and we also need to
635 * detect when the counter is 0
636 */
637#define MUTEX_COUNTER_SHIFT 2
638#define MUTEX_COUNTER_LEN 11
639#define MUTEX_COUNTER_MASK FIELD_MASK(MUTEX_COUNTER_SHIFT, MUTEX_COUNTER_LEN)
640
641#define MUTEX_COUNTER_BITS_WILL_OVERFLOW(v) (((v) & MUTEX_COUNTER_MASK) == MUTEX_COUNTER_MASK)
642#define MUTEX_COUNTER_BITS_IS_ZERO(v) (((v) & MUTEX_COUNTER_MASK) == 0)
643
644/* Used to increment the counter directly after overflow has been checked */
645#define MUTEX_COUNTER_BITS_ONE FIELD_TO_BITS(1,MUTEX_COUNTER_SHIFT,MUTEX_COUNTER_LEN)
646
647/* Returns true iff the counter is 0 */
648#define MUTEX_COUNTER_BITS_ARE_ZERO(v) (((v) & MUTEX_COUNTER_MASK) == 0)
649
650/* Mutex shared bit flag
651 *
652 * This flag is set to indicate that the mutex is shared among processes.
653 * This changes the futex opcode we use for futex wait/wake operations
654 * (non-shared operations are much faster).
655 */
656#define MUTEX_SHARED_SHIFT 13
657#define MUTEX_SHARED_MASK FIELD_MASK(MUTEX_SHARED_SHIFT,1)
658
659/* Mutex type:
660 *
661 * We support normal, recursive and errorcheck mutexes.
662 *
663 * The constants defined here *cannot* be changed because they must match
664 * the C library ABI which defines the following initialization values in
665 * <pthread.h>:
666 *
667 * __PTHREAD_MUTEX_INIT_VALUE
668 * __PTHREAD_RECURSIVE_MUTEX_VALUE
669 * __PTHREAD_ERRORCHECK_MUTEX_INIT_VALUE
670 */
671#define MUTEX_TYPE_SHIFT 14
672#define MUTEX_TYPE_LEN 2
673#define MUTEX_TYPE_MASK FIELD_MASK(MUTEX_TYPE_SHIFT,MUTEX_TYPE_LEN)
674
675#define MUTEX_TYPE_NORMAL 0 /* Must be 0 to match __PTHREAD_MUTEX_INIT_VALUE */
676#define MUTEX_TYPE_RECURSIVE 1
677#define MUTEX_TYPE_ERRORCHECK 2
678
679#define MUTEX_TYPE_TO_BITS(t) FIELD_TO_BITS(t, MUTEX_TYPE_SHIFT, MUTEX_TYPE_LEN)
680
681#define MUTEX_TYPE_BITS_NORMAL MUTEX_TYPE_TO_BITS(MUTEX_TYPE_NORMAL)
682#define MUTEX_TYPE_BITS_RECURSIVE MUTEX_TYPE_TO_BITS(MUTEX_TYPE_RECURSIVE)
683#define MUTEX_TYPE_BITS_ERRORCHECK MUTEX_TYPE_TO_BITS(MUTEX_TYPE_ERRORCHECK)
684
685/* Mutex owner field:
686 *
687 * This is only used for recursive and errorcheck mutexes. It holds the
688 * kernel TID of the owning thread. Note that this works because the Linux
689 * kernel _only_ uses 16-bit values for thread ids.
690 *
691 * More specifically, it will wrap to 10000 when it reaches over 32768 for
692 * application processes. You can check this by running the following inside
693 * an adb shell session:
694 *
695 OLDPID=$$;
696 while true; do
697 NEWPID=$(sh -c 'echo $$')
698 if [ "$NEWPID" -gt 32768 ]; then
699 echo "AARGH: new PID $NEWPID is too high!"
700 exit 1
701 fi
702 if [ "$NEWPID" -lt "$OLDPID" ]; then
703 echo "****** Wrapping from PID $OLDPID to $NEWPID. *******"
704 else
705 echo -n "$NEWPID!"
706 fi
707 OLDPID=$NEWPID
708 done
709
710 * Note that you can run the same example on a desktop Linux system,
711 * the wrapping will also happen at 32768, but will go back to 300 instead.
712 */
713#define MUTEX_OWNER_SHIFT 16
714#define MUTEX_OWNER_LEN 16
715
716#define MUTEX_OWNER_FROM_BITS(v) FIELD_FROM_BITS(v,MUTEX_OWNER_SHIFT,MUTEX_OWNER_LEN)
717#define MUTEX_OWNER_TO_BITS(v) FIELD_TO_BITS(v,MUTEX_OWNER_SHIFT,MUTEX_OWNER_LEN)
718
719/* Convenience macros.
720 *
721 * These are used to form or modify the bit pattern of a given mutex value
722 */
723
724
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800725
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700726/* a mutex attribute holds the following fields
727 *
728 * bits: name description
729 * 0-3 type type of mutex
730 * 4 shared process-shared flag
731 */
732#define MUTEXATTR_TYPE_MASK 0x000f
733#define MUTEXATTR_SHARED_MASK 0x0010
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800734
735
736int pthread_mutexattr_init(pthread_mutexattr_t *attr)
737{
738 if (attr) {
739 *attr = PTHREAD_MUTEX_DEFAULT;
740 return 0;
741 } else {
742 return EINVAL;
743 }
744}
745
746int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
747{
748 if (attr) {
749 *attr = -1;
750 return 0;
751 } else {
752 return EINVAL;
753 }
754}
755
756int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
757{
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700758 if (attr) {
759 int atype = (*attr & MUTEXATTR_TYPE_MASK);
760
761 if (atype >= PTHREAD_MUTEX_NORMAL &&
762 atype <= PTHREAD_MUTEX_ERRORCHECK) {
763 *type = atype;
764 return 0;
765 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800766 }
767 return EINVAL;
768}
769
770int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
771{
772 if (attr && type >= PTHREAD_MUTEX_NORMAL &&
773 type <= PTHREAD_MUTEX_ERRORCHECK ) {
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700774 *attr = (*attr & ~MUTEXATTR_TYPE_MASK) | type;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800775 return 0;
776 }
777 return EINVAL;
778}
779
780/* process-shared mutexes are not supported at the moment */
781
782int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared)
783{
784 if (!attr)
785 return EINVAL;
786
Mathias Agopianb7681162009-07-13 22:00:33 -0700787 switch (pshared) {
788 case PTHREAD_PROCESS_PRIVATE:
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700789 *attr &= ~MUTEXATTR_SHARED_MASK;
790 return 0;
791
Mathias Agopianb7681162009-07-13 22:00:33 -0700792 case PTHREAD_PROCESS_SHARED:
793 /* our current implementation of pthread actually supports shared
794 * mutexes but won't cleanup if a process dies with the mutex held.
795 * Nevertheless, it's better than nothing. Shared mutexes are used
796 * by surfaceflinger and audioflinger.
797 */
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700798 *attr |= MUTEXATTR_SHARED_MASK;
Mathias Agopianb7681162009-07-13 22:00:33 -0700799 return 0;
800 }
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700801 return EINVAL;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800802}
803
804int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared)
805{
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700806 if (!attr || !pshared)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800807 return EINVAL;
808
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700809 *pshared = (*attr & MUTEXATTR_SHARED_MASK) ? PTHREAD_PROCESS_SHARED
810 : PTHREAD_PROCESS_PRIVATE;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800811 return 0;
812}
813
814int pthread_mutex_init(pthread_mutex_t *mutex,
815 const pthread_mutexattr_t *attr)
816{
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700817 int value = 0;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800818
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700819 if (mutex == NULL)
820 return EINVAL;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800821
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700822 if (__likely(attr == NULL)) {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100823 mutex->value = MUTEX_TYPE_BITS_NORMAL;
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700824 return 0;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800825 }
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700826
827 if ((*attr & MUTEXATTR_SHARED_MASK) != 0)
828 value |= MUTEX_SHARED_MASK;
829
830 switch (*attr & MUTEXATTR_TYPE_MASK) {
831 case PTHREAD_MUTEX_NORMAL:
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100832 value |= MUTEX_TYPE_BITS_NORMAL;
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700833 break;
834 case PTHREAD_MUTEX_RECURSIVE:
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100835 value |= MUTEX_TYPE_BITS_RECURSIVE;
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700836 break;
837 case PTHREAD_MUTEX_ERRORCHECK:
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100838 value |= MUTEX_TYPE_BITS_ERRORCHECK;
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700839 break;
840 default:
841 return EINVAL;
842 }
843
844 mutex->value = value;
845 return 0;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800846}
847
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800848
849/*
850 * Lock a non-recursive mutex.
851 *
852 * As noted above, there are three states:
853 * 0 (unlocked, no contention)
854 * 1 (locked, no contention)
855 * 2 (locked, contention)
856 *
857 * Non-recursive mutexes don't use the thread-id or counter fields, and the
858 * "type" value is zero, so the only bits that will be set are the ones in
859 * the lock state field.
860 */
861static __inline__ void
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100862_normal_lock(pthread_mutex_t* mutex, int shared)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800863{
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100864 /* convenience shortcuts */
865 const int unlocked = shared | MUTEX_STATE_BITS_UNLOCKED;
866 const int locked_uncontended = shared | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800867 /*
868 * The common case is an unlocked mutex, so we begin by trying to
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100869 * change the lock's state from 0 (UNLOCKED) to 1 (LOCKED).
870 * __bionic_cmpxchg() returns 0 if it made the swap successfully.
871 * If the result is nonzero, this lock is already held by another thread.
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800872 */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100873 if (__bionic_cmpxchg(unlocked, locked_uncontended, &mutex->value) != 0) {
874 const int locked_contended = shared | MUTEX_STATE_BITS_LOCKED_CONTENDED;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800875 /*
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800876 * We want to go to sleep until the mutex is available, which
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100877 * requires promoting it to state 2 (CONTENDED). We need to
878 * swap in the new state value and then wait until somebody wakes us up.
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800879 *
David 'Digit' Turnere31bfae2011-11-15 15:47:02 +0100880 * __bionic_swap() returns the previous value. We swap 2 in and
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800881 * see if we got zero back; if so, we have acquired the lock. If
882 * not, another thread still holds the lock and we wait again.
883 *
884 * The second argument to the __futex_wait() call is compared
885 * against the current value. If it doesn't match, __futex_wait()
886 * returns immediately (otherwise, it sleeps for a time specified
887 * by the third argument; 0 means sleep forever). This ensures
888 * that the mutex is in state 2 when we go to sleep on it, which
889 * guarantees a wake-up call.
890 */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100891 while (__bionic_swap(locked_contended, &mutex->value) != unlocked)
892 __futex_wait_ex(&mutex->value, shared, locked_contended, 0);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800893 }
Andy McFaddenfcd00eb2010-05-28 13:31:45 -0700894 ANDROID_MEMBAR_FULL();
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800895}
896
897/*
898 * Release a non-recursive mutex. The caller is responsible for determining
899 * that we are in fact the owner of this lock.
900 */
901static __inline__ void
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100902_normal_unlock(pthread_mutex_t* mutex, int shared)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800903{
Andy McFaddenfcd00eb2010-05-28 13:31:45 -0700904 ANDROID_MEMBAR_FULL();
905
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800906 /*
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700907 * The mutex state will be 1 or (rarely) 2. We use an atomic decrement
David 'Digit' Turnere31bfae2011-11-15 15:47:02 +0100908 * to release the lock. __bionic_atomic_dec() returns the previous value;
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800909 * if it wasn't 1 we have to do some additional work.
910 */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100911 if (__bionic_atomic_dec(&mutex->value) != (shared|MUTEX_STATE_BITS_LOCKED_UNCONTENDED)) {
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800912 /*
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800913 * Start by releasing the lock. The decrement changed it from
914 * "contended lock" to "uncontended lock", which means we still
915 * hold it, and anybody who tries to sneak in will push it back
916 * to state 2.
917 *
918 * Once we set it to zero the lock is up for grabs. We follow
919 * this with a __futex_wake() to ensure that one of the waiting
920 * threads has a chance to grab it.
921 *
922 * This doesn't cause a race with the swap/wait pair in
923 * _normal_lock(), because the __futex_wait() call there will
924 * return immediately if the mutex value isn't 2.
925 */
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -0700926 mutex->value = shared;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800927
Fabrice Di Meglio86418332010-03-11 14:47:47 -0800928 /*
929 * Wake up one waiting thread. We don't know which thread will be
930 * woken or when it'll start executing -- futexes make no guarantees
931 * here. There may not even be a thread waiting.
932 *
933 * The newly-woken thread will replace the 0 we just set above
934 * with 2, which means that when it eventually releases the mutex
935 * it will also call FUTEX_WAKE. This results in one extra wake
936 * call whenever a lock is contended, but lets us avoid forgetting
937 * anyone without requiring us to track the number of sleepers.
938 *
939 * It's possible for another thread to sneak in and grab the lock
940 * between the zero assignment above and the wake call below. If
941 * the new thread is "slow" and holds the lock for a while, we'll
942 * wake up a sleeper, which will swap in a 2 and then go back to
943 * sleep since the lock is still held. If the new thread is "fast",
944 * running to completion before we call wake, the thread we
945 * eventually wake will find an unlocked mutex and will execute.
946 * Either way we have correct behavior and nobody is orphaned on
947 * the wait queue.
948 */
David 'Digit' Turner6304d8b2010-06-02 18:12:12 -0700949 __futex_wake_ex(&mutex->value, shared, 1);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800950 }
951}
952
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100953/* This common inlined function is used to increment the counter of an
954 * errorcheck or recursive mutex.
955 *
956 * For errorcheck mutexes, it will return EDEADLK
957 * If the counter overflows, it will return EAGAIN
958 * Otherwise, it atomically increments the counter and returns 0
959 * after providing an acquire barrier.
960 *
961 * mtype is the current mutex type
962 * mvalue is the current mutex value (already loaded)
963 * mutex pointers to the mutex.
964 */
965static __inline__ __attribute__((always_inline)) int
966_recursive_increment(pthread_mutex_t* mutex, int mvalue, int mtype)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800967{
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100968 if (mtype == MUTEX_TYPE_BITS_ERRORCHECK) {
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100969 /* trying to re-lock a mutex we already acquired */
970 return EDEADLK;
971 }
972
973 /* Detect recursive lock overflow and return EAGAIN.
974 * This is safe because only the owner thread can modify the
David 'Digit' Turnerb57db752012-01-24 13:20:38 +0100975 * counter bits in the mutex value.
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100976 */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100977 if (MUTEX_COUNTER_BITS_WILL_OVERFLOW(mvalue)) {
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100978 return EAGAIN;
979 }
980
981 /* We own the mutex, but other threads are able to change
David 'Digit' Turnerb57db752012-01-24 13:20:38 +0100982 * the lower bits (e.g. promoting it to "contended"), so we
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100983 * need to use an atomic cmpxchg loop to update the counter.
David 'Digit' Turner022d3032011-12-07 14:02:17 +0100984 */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +0100985 for (;;) {
986 /* increment counter, overflow was already checked */
987 int newval = mvalue + MUTEX_COUNTER_BITS_ONE;
988 if (__likely(__bionic_cmpxchg(mvalue, newval, &mutex->value) == 0)) {
989 /* mutex is still locked, not need for a memory barrier */
990 return 0;
991 }
992 /* the value was changed, this happens when another thread changes
993 * the lower state bits from 1 to 2 to indicate contention. This
994 * cannot change the counter, so simply reload and try again.
995 */
996 mvalue = mutex->value;
997 }
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800998}
999
Mathias Agopian7c0c3792011-09-05 23:54:55 -07001000__LIBC_HIDDEN__
1001int pthread_mutex_lock_impl(pthread_mutex_t *mutex)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001002{
Wink Savillea12c5442013-01-08 15:15:45 -08001003 int mvalue, mtype, tid, shared;
David 'Digit' Turnerba9c6f02010-03-10 16:44:08 -08001004
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001005 if (__unlikely(mutex == NULL))
1006 return EINVAL;
David 'Digit' Turnerba9c6f02010-03-10 16:44:08 -08001007
David 'Digit' Turner022d3032011-12-07 14:02:17 +01001008 mvalue = mutex->value;
1009 mtype = (mvalue & MUTEX_TYPE_MASK);
1010 shared = (mvalue & MUTEX_SHARED_MASK);
Fabrice Di Meglio86418332010-03-11 14:47:47 -08001011
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001012 /* Handle normal case first */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001013 if ( __likely(mtype == MUTEX_TYPE_BITS_NORMAL) ) {
David 'Digit' Turner022d3032011-12-07 14:02:17 +01001014 _normal_lock(mutex, shared);
David 'Digit' Turnerba9c6f02010-03-10 16:44:08 -08001015 return 0;
1016 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001017
1018 /* Do we already own this recursive or error-check mutex ? */
1019 tid = __get_thread()->kernel_id;
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001020 if ( tid == MUTEX_OWNER_FROM_BITS(mvalue) )
David 'Digit' Turner022d3032011-12-07 14:02:17 +01001021 return _recursive_increment(mutex, mvalue, mtype);
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001022
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001023 /* Add in shared state to avoid extra 'or' operations below */
David 'Digit' Turner6304d8b2010-06-02 18:12:12 -07001024 mtype |= shared;
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -07001025
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001026 /* First, if the mutex is unlocked, try to quickly acquire it.
1027 * In the optimistic case where this works, set the state to 1 to
1028 * indicate locked with no contention */
1029 if (mvalue == mtype) {
1030 int newval = MUTEX_OWNER_TO_BITS(tid) | mtype | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
1031 if (__bionic_cmpxchg(mvalue, newval, &mutex->value) == 0) {
1032 ANDROID_MEMBAR_FULL();
1033 return 0;
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001034 }
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001035 /* argh, the value changed, reload before entering the loop */
1036 mvalue = mutex->value;
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001037 }
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001038
1039 for (;;) {
1040 int newval;
1041
1042 /* if the mutex is unlocked, its value should be 'mtype' and
1043 * we try to acquire it by setting its owner and state atomically.
1044 * NOTE: We put the state to 2 since we _know_ there is contention
1045 * when we are in this loop. This ensures all waiters will be
1046 * unlocked.
1047 */
1048 if (mvalue == mtype) {
1049 newval = MUTEX_OWNER_TO_BITS(tid) | mtype | MUTEX_STATE_BITS_LOCKED_CONTENDED;
1050 /* TODO: Change this to __bionic_cmpxchg_acquire when we
1051 * implement it to get rid of the explicit memory
1052 * barrier below.
1053 */
1054 if (__unlikely(__bionic_cmpxchg(mvalue, newval, &mutex->value) != 0)) {
1055 mvalue = mutex->value;
1056 continue;
1057 }
1058 ANDROID_MEMBAR_FULL();
1059 return 0;
1060 }
1061
1062 /* the mutex is already locked by another thread, if its state is 1
1063 * we will change it to 2 to indicate contention. */
1064 if (MUTEX_STATE_BITS_IS_LOCKED_UNCONTENDED(mvalue)) {
1065 newval = MUTEX_STATE_BITS_FLIP_CONTENTION(mvalue); /* locked state 1 => state 2 */
1066 if (__unlikely(__bionic_cmpxchg(mvalue, newval, &mutex->value) != 0)) {
1067 mvalue = mutex->value;
1068 continue;
1069 }
1070 mvalue = newval;
1071 }
1072
1073 /* wait until the mutex is unlocked */
1074 __futex_wait_ex(&mutex->value, shared, mvalue, NULL);
1075
1076 mvalue = mutex->value;
1077 }
1078 /* NOTREACHED */
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001079}
1080
Mathias Agopian7c0c3792011-09-05 23:54:55 -07001081int pthread_mutex_lock(pthread_mutex_t *mutex)
1082{
1083 int err = pthread_mutex_lock_impl(mutex);
1084#ifdef PTHREAD_DEBUG
1085 if (PTHREAD_DEBUG_ENABLED) {
1086 if (!err) {
1087 pthread_debug_mutex_lock_check(mutex);
1088 }
1089 }
1090#endif
1091 return err;
1092}
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001093
Mathias Agopian7c0c3792011-09-05 23:54:55 -07001094__LIBC_HIDDEN__
1095int pthread_mutex_unlock_impl(pthread_mutex_t *mutex)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001096{
Wink Savillea12c5442013-01-08 15:15:45 -08001097 int mvalue, mtype, tid, shared;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001098
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001099 if (__unlikely(mutex == NULL))
1100 return EINVAL;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001101
David 'Digit' Turner022d3032011-12-07 14:02:17 +01001102 mvalue = mutex->value;
1103 mtype = (mvalue & MUTEX_TYPE_MASK);
1104 shared = (mvalue & MUTEX_SHARED_MASK);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001105
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001106 /* Handle common case first */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001107 if (__likely(mtype == MUTEX_TYPE_BITS_NORMAL)) {
David 'Digit' Turner022d3032011-12-07 14:02:17 +01001108 _normal_unlock(mutex, shared);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001109 return 0;
1110 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001111
1112 /* Do we already own this recursive or error-check mutex ? */
1113 tid = __get_thread()->kernel_id;
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001114 if ( tid != MUTEX_OWNER_FROM_BITS(mvalue) )
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001115 return EPERM;
1116
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001117 /* If the counter is > 0, we can simply decrement it atomically.
1118 * Since other threads can mutate the lower state bits (and only the
1119 * lower state bits), use a cmpxchg to do it.
1120 */
1121 if (!MUTEX_COUNTER_BITS_IS_ZERO(mvalue)) {
1122 for (;;) {
1123 int newval = mvalue - MUTEX_COUNTER_BITS_ONE;
1124 if (__likely(__bionic_cmpxchg(mvalue, newval, &mutex->value) == 0)) {
1125 /* success: we still own the mutex, so no memory barrier */
1126 return 0;
1127 }
1128 /* the value changed, so reload and loop */
1129 mvalue = mutex->value;
1130 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001131 }
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001132
1133 /* the counter is 0, so we're going to unlock the mutex by resetting
1134 * its value to 'unlocked'. We need to perform a swap in order
1135 * to read the current state, which will be 2 if there are waiters
1136 * to awake.
1137 *
1138 * TODO: Change this to __bionic_swap_release when we implement it
1139 * to get rid of the explicit memory barrier below.
1140 */
1141 ANDROID_MEMBAR_FULL(); /* RELEASE BARRIER */
1142 mvalue = __bionic_swap(mtype | shared | MUTEX_STATE_BITS_UNLOCKED, &mutex->value);
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001143
1144 /* Wake one waiting thread, if any */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001145 if (MUTEX_STATE_BITS_IS_LOCKED_CONTENDED(mvalue)) {
David 'Digit' Turner6304d8b2010-06-02 18:12:12 -07001146 __futex_wake_ex(&mutex->value, shared, 1);
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -07001147 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001148 return 0;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001149}
1150
Mathias Agopian7c0c3792011-09-05 23:54:55 -07001151int pthread_mutex_unlock(pthread_mutex_t *mutex)
1152{
1153#ifdef PTHREAD_DEBUG
1154 if (PTHREAD_DEBUG_ENABLED) {
1155 pthread_debug_mutex_unlock_check(mutex);
1156 }
1157#endif
1158 return pthread_mutex_unlock_impl(mutex);
1159}
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001160
Mathias Agopian7c0c3792011-09-05 23:54:55 -07001161__LIBC_HIDDEN__
1162int pthread_mutex_trylock_impl(pthread_mutex_t *mutex)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001163{
Wink Savillea12c5442013-01-08 15:15:45 -08001164 int mvalue, mtype, tid, shared;
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001165
1166 if (__unlikely(mutex == NULL))
1167 return EINVAL;
1168
David 'Digit' Turner022d3032011-12-07 14:02:17 +01001169 mvalue = mutex->value;
1170 mtype = (mvalue & MUTEX_TYPE_MASK);
1171 shared = (mvalue & MUTEX_SHARED_MASK);
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001172
1173 /* Handle common case first */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001174 if ( __likely(mtype == MUTEX_TYPE_BITS_NORMAL) )
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001175 {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001176 if (__bionic_cmpxchg(shared|MUTEX_STATE_BITS_UNLOCKED,
1177 shared|MUTEX_STATE_BITS_LOCKED_UNCONTENDED,
1178 &mutex->value) == 0) {
Andy McFaddenfcd00eb2010-05-28 13:31:45 -07001179 ANDROID_MEMBAR_FULL();
Fabrice Di Meglio86418332010-03-11 14:47:47 -08001180 return 0;
Andy McFaddenfcd00eb2010-05-28 13:31:45 -07001181 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001182
1183 return EBUSY;
David 'Digit' Turnerba9c6f02010-03-10 16:44:08 -08001184 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001185
1186 /* Do we already own this recursive or error-check mutex ? */
1187 tid = __get_thread()->kernel_id;
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001188 if ( tid == MUTEX_OWNER_FROM_BITS(mvalue) )
David 'Digit' Turner022d3032011-12-07 14:02:17 +01001189 return _recursive_increment(mutex, mvalue, mtype);
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001190
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001191 /* Same as pthread_mutex_lock, except that we don't want to wait, and
1192 * the only operation that can succeed is a single cmpxchg to acquire the
1193 * lock if it is released / not owned by anyone. No need for a complex loop.
1194 */
1195 mtype |= shared | MUTEX_STATE_BITS_UNLOCKED;
1196 mvalue = MUTEX_OWNER_TO_BITS(tid) | mtype | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -07001197
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001198 if (__likely(__bionic_cmpxchg(mtype, mvalue, &mutex->value) == 0)) {
1199 ANDROID_MEMBAR_FULL();
1200 return 0;
1201 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001202
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001203 return EBUSY;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001204}
1205
Mathias Agopian7c0c3792011-09-05 23:54:55 -07001206int pthread_mutex_trylock(pthread_mutex_t *mutex)
1207{
1208 int err = pthread_mutex_trylock_impl(mutex);
1209#ifdef PTHREAD_DEBUG
1210 if (PTHREAD_DEBUG_ENABLED) {
1211 if (!err) {
1212 pthread_debug_mutex_lock_check(mutex);
1213 }
1214 }
1215#endif
1216 return err;
1217}
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001218
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -07001219/* initialize 'ts' with the difference between 'abstime' and the current time
1220 * according to 'clock'. Returns -1 if abstime already expired, or 0 otherwise.
1221 */
1222static int
1223__timespec_to_absolute(struct timespec* ts, const struct timespec* abstime, clockid_t clock)
1224{
1225 clock_gettime(clock, ts);
1226 ts->tv_sec = abstime->tv_sec - ts->tv_sec;
1227 ts->tv_nsec = abstime->tv_nsec - ts->tv_nsec;
1228 if (ts->tv_nsec < 0) {
1229 ts->tv_sec--;
1230 ts->tv_nsec += 1000000000;
1231 }
David 'Digit' Turnerbc10cd22009-09-23 15:56:50 -07001232 if ((ts->tv_nsec < 0) || (ts->tv_sec < 0))
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -07001233 return -1;
1234
1235 return 0;
1236}
1237
1238/* initialize 'abstime' to the current time according to 'clock' plus 'msecs'
1239 * milliseconds.
1240 */
1241static void
1242__timespec_to_relative_msec(struct timespec* abstime, unsigned msecs, clockid_t clock)
1243{
1244 clock_gettime(clock, abstime);
1245 abstime->tv_sec += msecs/1000;
1246 abstime->tv_nsec += (msecs%1000)*1000000;
1247 if (abstime->tv_nsec >= 1000000000) {
1248 abstime->tv_sec++;
1249 abstime->tv_nsec -= 1000000000;
1250 }
1251}
1252
Mathias Agopian7c0c3792011-09-05 23:54:55 -07001253__LIBC_HIDDEN__
1254int pthread_mutex_lock_timeout_np_impl(pthread_mutex_t *mutex, unsigned msecs)
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -07001255{
1256 clockid_t clock = CLOCK_MONOTONIC;
1257 struct timespec abstime;
1258 struct timespec ts;
Wink Savillea12c5442013-01-08 15:15:45 -08001259 int mvalue, mtype, tid, shared;
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -07001260
1261 /* compute absolute expiration time */
1262 __timespec_to_relative_msec(&abstime, msecs, clock);
1263
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001264 if (__unlikely(mutex == NULL))
1265 return EINVAL;
1266
David 'Digit' Turner022d3032011-12-07 14:02:17 +01001267 mvalue = mutex->value;
1268 mtype = (mvalue & MUTEX_TYPE_MASK);
1269 shared = (mvalue & MUTEX_SHARED_MASK);
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001270
1271 /* Handle common case first */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001272 if ( __likely(mtype == MUTEX_TYPE_BITS_NORMAL) )
David 'Digit' Turnerba9c6f02010-03-10 16:44:08 -08001273 {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001274 const int unlocked = shared | MUTEX_STATE_BITS_UNLOCKED;
1275 const int locked_uncontended = shared | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
1276 const int locked_contended = shared | MUTEX_STATE_BITS_LOCKED_CONTENDED;
1277
1278 /* fast path for uncontended lock. Note: MUTEX_TYPE_BITS_NORMAL is 0 */
1279 if (__bionic_cmpxchg(unlocked, locked_uncontended, &mutex->value) == 0) {
Andy McFaddenfcd00eb2010-05-28 13:31:45 -07001280 ANDROID_MEMBAR_FULL();
Fabrice Di Meglio86418332010-03-11 14:47:47 -08001281 return 0;
Andy McFaddenfcd00eb2010-05-28 13:31:45 -07001282 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001283
1284 /* loop while needed */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001285 while (__bionic_swap(locked_contended, &mutex->value) != unlocked) {
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001286 if (__timespec_to_absolute(&ts, &abstime, clock) < 0)
1287 return EBUSY;
1288
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001289 __futex_wait_ex(&mutex->value, shared, locked_contended, &ts);
Fabrice Di Meglio86418332010-03-11 14:47:47 -08001290 }
Andy McFaddenfcd00eb2010-05-28 13:31:45 -07001291 ANDROID_MEMBAR_FULL();
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001292 return 0;
David 'Digit' Turnerba9c6f02010-03-10 16:44:08 -08001293 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001294
1295 /* Do we already own this recursive or error-check mutex ? */
1296 tid = __get_thread()->kernel_id;
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001297 if ( tid == MUTEX_OWNER_FROM_BITS(mvalue) )
David 'Digit' Turner022d3032011-12-07 14:02:17 +01001298 return _recursive_increment(mutex, mvalue, mtype);
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001299
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001300 /* the following implements the same loop than pthread_mutex_lock_impl
1301 * but adds checks to ensure that the operation never exceeds the
1302 * absolute expiration time.
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001303 */
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001304 mtype |= shared;
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001305
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001306 /* first try a quick lock */
1307 if (mvalue == mtype) {
1308 mvalue = MUTEX_OWNER_TO_BITS(tid) | mtype | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
1309 if (__likely(__bionic_cmpxchg(mtype, mvalue, &mutex->value) == 0)) {
1310 ANDROID_MEMBAR_FULL();
1311 return 0;
1312 }
1313 mvalue = mutex->value;
1314 }
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -07001315
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001316 for (;;) {
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001317 struct timespec ts;
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001318
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001319 /* if the value is 'unlocked', try to acquire it directly */
1320 /* NOTE: put state to 2 since we know there is contention */
1321 if (mvalue == mtype) /* unlocked */ {
1322 mvalue = MUTEX_OWNER_TO_BITS(tid) | mtype | MUTEX_STATE_BITS_LOCKED_CONTENDED;
1323 if (__bionic_cmpxchg(mtype, mvalue, &mutex->value) == 0) {
1324 ANDROID_MEMBAR_FULL();
1325 return 0;
1326 }
1327 /* the value changed before we could lock it. We need to check
1328 * the time to avoid livelocks, reload the value, then loop again. */
1329 if (__timespec_to_absolute(&ts, &abstime, clock) < 0)
1330 return EBUSY;
1331
1332 mvalue = mutex->value;
1333 continue;
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001334 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001335
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001336 /* The value is locked. If 'uncontended', try to switch its state
1337 * to 'contented' to ensure we get woken up later. */
1338 if (MUTEX_STATE_BITS_IS_LOCKED_UNCONTENDED(mvalue)) {
1339 int newval = MUTEX_STATE_BITS_FLIP_CONTENTION(mvalue);
1340 if (__bionic_cmpxchg(mvalue, newval, &mutex->value) != 0) {
1341 /* this failed because the value changed, reload it */
1342 mvalue = mutex->value;
1343 } else {
1344 /* this succeeded, update mvalue */
1345 mvalue = newval;
1346 }
1347 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001348
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001349 /* check time and update 'ts' */
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001350 if (__timespec_to_absolute(&ts, &abstime, clock) < 0)
1351 return EBUSY;
1352
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001353 /* Only wait to be woken up if the state is '2', otherwise we'll
1354 * simply loop right now. This can happen when the second cmpxchg
1355 * in our loop failed because the mutex was unlocked by another
1356 * thread.
1357 */
1358 if (MUTEX_STATE_BITS_IS_LOCKED_CONTENDED(mvalue)) {
1359 if (__futex_wait_ex(&mutex->value, shared, mvalue, &ts) == ETIMEDOUT) {
1360 return EBUSY;
1361 }
1362 mvalue = mutex->value;
1363 }
David 'Digit' Turner40e6b822010-03-17 11:25:46 -07001364 }
David 'Digit' Turnere1414aa2012-01-24 15:26:54 +01001365 /* NOTREACHED */
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -07001366}
1367
Mathias Agopian7c0c3792011-09-05 23:54:55 -07001368int pthread_mutex_lock_timeout_np(pthread_mutex_t *mutex, unsigned msecs)
1369{
1370 int err = pthread_mutex_lock_timeout_np_impl(mutex, msecs);
1371#ifdef PTHREAD_DEBUG
1372 if (PTHREAD_DEBUG_ENABLED) {
1373 if (!err) {
1374 pthread_debug_mutex_lock_check(mutex);
1375 }
1376 }
1377#endif
1378 return err;
1379}
1380
1381int pthread_mutex_destroy(pthread_mutex_t *mutex)
1382{
1383 int ret;
1384
1385 /* use trylock to ensure that the mutex value is
1386 * valid and is not already locked. */
1387 ret = pthread_mutex_trylock_impl(mutex);
1388 if (ret != 0)
1389 return ret;
1390
1391 mutex->value = 0xdead10cc;
1392 return 0;
1393}
1394
1395
1396
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001397int pthread_condattr_init(pthread_condattr_t *attr)
1398{
1399 if (attr == NULL)
1400 return EINVAL;
1401
1402 *attr = PTHREAD_PROCESS_PRIVATE;
1403 return 0;
1404}
1405
1406int pthread_condattr_getpshared(pthread_condattr_t *attr, int *pshared)
1407{
1408 if (attr == NULL || pshared == NULL)
1409 return EINVAL;
1410
1411 *pshared = *attr;
1412 return 0;
1413}
1414
1415int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared)
1416{
1417 if (attr == NULL)
1418 return EINVAL;
1419
1420 if (pshared != PTHREAD_PROCESS_SHARED &&
1421 pshared != PTHREAD_PROCESS_PRIVATE)
1422 return EINVAL;
1423
1424 *attr = pshared;
1425 return 0;
1426}
1427
1428int pthread_condattr_destroy(pthread_condattr_t *attr)
1429{
1430 if (attr == NULL)
1431 return EINVAL;
1432
1433 *attr = 0xdeada11d;
1434 return 0;
1435}
1436
1437/* We use one bit in condition variable values as the 'shared' flag
1438 * The rest is a counter.
1439 */
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001440#define COND_SHARED_MASK 0x0001
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001441#define COND_COUNTER_INCREMENT 0x0002
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001442#define COND_COUNTER_MASK (~COND_SHARED_MASK)
1443
1444#define COND_IS_SHARED(c) (((c)->value & COND_SHARED_MASK) != 0)
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -07001445
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001446/* XXX *technically* there is a race condition that could allow
1447 * XXX a signal to be missed. If thread A is preempted in _wait()
1448 * XXX after unlocking the mutex and before waiting, and if other
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001449 * XXX threads call signal or broadcast UINT_MAX/2 times (exactly),
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001450 * XXX before thread A is scheduled again and calls futex_wait(),
1451 * XXX then the signal will be lost.
1452 */
1453
1454int pthread_cond_init(pthread_cond_t *cond,
1455 const pthread_condattr_t *attr)
1456{
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001457 if (cond == NULL)
1458 return EINVAL;
1459
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001460 cond->value = 0;
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001461
1462 if (attr != NULL && *attr == PTHREAD_PROCESS_SHARED)
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001463 cond->value |= COND_SHARED_MASK;
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001464
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001465 return 0;
1466}
1467
1468int pthread_cond_destroy(pthread_cond_t *cond)
1469{
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001470 if (cond == NULL)
1471 return EINVAL;
1472
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001473 cond->value = 0xdeadc04d;
1474 return 0;
1475}
1476
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001477/* This function is used by pthread_cond_broadcast and
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001478 * pthread_cond_signal to atomically decrement the counter
1479 * then wake-up 'counter' threads.
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001480 */
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001481static int
1482__pthread_cond_pulse(pthread_cond_t *cond, int counter)
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001483{
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001484 long flags;
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001485
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001486 if (__unlikely(cond == NULL))
1487 return EINVAL;
1488
1489 flags = (cond->value & ~COND_COUNTER_MASK);
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001490 for (;;) {
1491 long oldval = cond->value;
1492 long newval = ((oldval - COND_COUNTER_INCREMENT) & COND_COUNTER_MASK)
1493 | flags;
David 'Digit' Turnere31bfae2011-11-15 15:47:02 +01001494 if (__bionic_cmpxchg(oldval, newval, &cond->value) == 0)
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001495 break;
1496 }
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001497
Andy McFaddene2ac8982010-09-02 13:34:53 -07001498 /*
1499 * Ensure that all memory accesses previously made by this thread are
1500 * visible to the woken thread(s). On the other side, the "wait"
1501 * code will issue any necessary barriers when locking the mutex.
1502 *
1503 * This may not strictly be necessary -- if the caller follows
1504 * recommended practice and holds the mutex before signaling the cond
1505 * var, the mutex ops will provide correct semantics. If they don't
1506 * hold the mutex, they're subject to race conditions anyway.
1507 */
1508 ANDROID_MEMBAR_FULL();
1509
David 'Digit' Turner6304d8b2010-06-02 18:12:12 -07001510 __futex_wake_ex(&cond->value, COND_IS_SHARED(cond), counter);
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001511 return 0;
David 'Digit' Turneree7b0772010-03-18 14:07:42 -07001512}
1513
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001514int pthread_cond_broadcast(pthread_cond_t *cond)
1515{
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001516 return __pthread_cond_pulse(cond, INT_MAX);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001517}
1518
1519int pthread_cond_signal(pthread_cond_t *cond)
1520{
David 'Digit' Turnerb5e4a412010-03-19 17:59:23 -07001521 return __pthread_cond_pulse(cond, 1);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001522}
1523
1524int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
1525{
1526 return pthread_cond_timedwait(cond, mutex, NULL);
1527}
1528
1529int __pthread_cond_timedwait_relative(pthread_cond_t *cond,
1530 pthread_mutex_t * mutex,
1531 const struct timespec *reltime)
1532{
1533 int status;
1534 int oldvalue = cond->value;
1535
1536 pthread_mutex_unlock(mutex);
David 'Digit' Turner6304d8b2010-06-02 18:12:12 -07001537 status = __futex_wait_ex(&cond->value, COND_IS_SHARED(cond), oldvalue, reltime);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001538 pthread_mutex_lock(mutex);
1539
1540 if (status == (-ETIMEDOUT)) return ETIMEDOUT;
1541 return 0;
1542}
1543
1544int __pthread_cond_timedwait(pthread_cond_t *cond,
1545 pthread_mutex_t * mutex,
1546 const struct timespec *abstime,
1547 clockid_t clock)
1548{
1549 struct timespec ts;
1550 struct timespec * tsp;
1551
1552 if (abstime != NULL) {
David 'Digit' Turner3f56b7f2009-09-22 12:40:22 -07001553 if (__timespec_to_absolute(&ts, abstime, clock) < 0)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001554 return ETIMEDOUT;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001555 tsp = &ts;
1556 } else {
1557 tsp = NULL;
1558 }
1559
1560 return __pthread_cond_timedwait_relative(cond, mutex, tsp);
1561}
1562
1563int pthread_cond_timedwait(pthread_cond_t *cond,
1564 pthread_mutex_t * mutex,
1565 const struct timespec *abstime)
1566{
1567 return __pthread_cond_timedwait(cond, mutex, abstime, CLOCK_REALTIME);
1568}
1569
1570
Mathias Agopiana2f5e212009-07-13 15:00:46 -07001571/* this one exists only for backward binary compatibility */
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001572int pthread_cond_timedwait_monotonic(pthread_cond_t *cond,
1573 pthread_mutex_t * mutex,
1574 const struct timespec *abstime)
1575{
1576 return __pthread_cond_timedwait(cond, mutex, abstime, CLOCK_MONOTONIC);
1577}
1578
Mathias Agopiana2f5e212009-07-13 15:00:46 -07001579int pthread_cond_timedwait_monotonic_np(pthread_cond_t *cond,
1580 pthread_mutex_t * mutex,
1581 const struct timespec *abstime)
1582{
1583 return __pthread_cond_timedwait(cond, mutex, abstime, CLOCK_MONOTONIC);
1584}
1585
1586int pthread_cond_timedwait_relative_np(pthread_cond_t *cond,
1587 pthread_mutex_t * mutex,
1588 const struct timespec *reltime)
1589{
1590 return __pthread_cond_timedwait_relative(cond, mutex, reltime);
1591}
1592
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001593int pthread_cond_timeout_np(pthread_cond_t *cond,
1594 pthread_mutex_t * mutex,
1595 unsigned msecs)
1596{
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001597 struct timespec ts;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001598
1599 ts.tv_sec = msecs / 1000;
1600 ts.tv_nsec = (msecs % 1000) * 1000000;
1601
Matthieu CASTETa4e67f42008-12-27 00:04:10 +01001602 return __pthread_cond_timedwait_relative(cond, mutex, &ts);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001603}
1604
1605
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001606// man says this should be in <linux/unistd.h>, but it isn't
Jeff Brown10c8ce52011-11-18 15:17:07 -08001607extern int tgkill(int tgid, int tid, int sig);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001608
1609int pthread_kill(pthread_t tid, int sig)
1610{
1611 int ret;
1612 int old_errno = errno;
1613 pthread_internal_t * thread = (pthread_internal_t *)tid;
1614
Jeff Brown10c8ce52011-11-18 15:17:07 -08001615 ret = tgkill(getpid(), thread->kernel_id, sig);
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001616 if (ret < 0) {
1617 ret = errno;
1618 errno = old_errno;
1619 }
1620
1621 return ret;
1622}
1623
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001624
1625int pthread_getcpuclockid(pthread_t tid, clockid_t *clockid)
1626{
1627 const int CLOCK_IDTYPE_BITS = 3;
1628 pthread_internal_t* thread = (pthread_internal_t*)tid;
1629
1630 if (!thread)
1631 return ESRCH;
1632
1633 *clockid = CLOCK_THREAD_CPUTIME_ID | (thread->kernel_id << CLOCK_IDTYPE_BITS);
1634 return 0;
1635}
1636
1637
1638/* NOTE: this implementation doesn't support a init function that throws a C++ exception
1639 * or calls fork()
1640 */
1641int pthread_once( pthread_once_t* once_control, void (*init_routine)(void) )
1642{
Andy McFaddenb1c9cc22010-09-23 12:30:12 -07001643 volatile pthread_once_t* ocptr = once_control;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001644
David 'Digit' Turner6c6de442011-12-07 12:20:44 +01001645 /* PTHREAD_ONCE_INIT is 0, we use the following bit flags
1646 *
1647 * bit 0 set -> initialization is under way
1648 * bit 1 set -> initialization is complete
1649 */
1650#define ONCE_INITIALIZING (1 << 0)
1651#define ONCE_COMPLETED (1 << 1)
1652
1653 /* First check if the once is already initialized. This will be the common
1654 * case and we want to make this as fast as possible. Note that this still
1655 * requires a load_acquire operation here to ensure that all the
1656 * stores performed by the initialization function are observable on
1657 * this CPU after we exit.
1658 */
1659 if (__likely((*ocptr & ONCE_COMPLETED) != 0)) {
1660 ANDROID_MEMBAR_FULL();
1661 return 0;
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001662 }
David 'Digit' Turner6c6de442011-12-07 12:20:44 +01001663
1664 for (;;) {
1665 /* Try to atomically set the INITIALIZING flag.
1666 * This requires a cmpxchg loop, and we may need
Elliott Hughesbfeab1b2012-09-05 17:47:37 -07001667 * to exit prematurely if we detect that
David 'Digit' Turner6c6de442011-12-07 12:20:44 +01001668 * COMPLETED is now set.
1669 */
1670 int32_t oldval, newval;
1671
1672 do {
1673 oldval = *ocptr;
1674 if ((oldval & ONCE_COMPLETED) != 0)
1675 break;
1676
1677 newval = oldval | ONCE_INITIALIZING;
1678 } while (__bionic_cmpxchg(oldval, newval, ocptr) != 0);
1679
1680 if ((oldval & ONCE_COMPLETED) != 0) {
1681 /* We detected that COMPLETED was set while in our loop */
1682 ANDROID_MEMBAR_FULL();
1683 return 0;
1684 }
1685
1686 if ((oldval & ONCE_INITIALIZING) == 0) {
1687 /* We got there first, we can jump out of the loop to
1688 * handle the initialization */
1689 break;
1690 }
1691
1692 /* Another thread is running the initialization and hasn't completed
1693 * yet, so wait for it, then try again. */
1694 __futex_wait_ex(ocptr, 0, oldval, NULL);
1695 }
1696
1697 /* call the initialization function. */
1698 (*init_routine)();
1699
1700 /* Do a store_release indicating that initialization is complete */
1701 ANDROID_MEMBAR_FULL();
1702 *ocptr = ONCE_COMPLETED;
1703
1704 /* Wake up any waiters, if any */
1705 __futex_wake_ex(ocptr, 0, INT_MAX);
1706
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001707 return 0;
1708}
André Goddard Rosa78c1c042010-05-19 23:17:16 -03001709
Glenn Kastend53cae02011-07-11 15:41:28 -07001710/* Return the kernel thread ID for a pthread.
1711 * This is only defined for implementations where pthread <-> kernel is 1:1, which this is.
1712 * Not the same as pthread_getthreadid_np, which is commonly defined to be opaque.
1713 * Internal, not an NDK API.
1714 */
1715
1716pid_t __pthread_gettid(pthread_t thid)
1717{
1718 pthread_internal_t* thread = (pthread_internal_t*)thid;
1719 return thread->kernel_id;
1720}
Jean-Baptiste Querufaca92f2012-03-26 15:25:19 -07001721
1722int __pthread_settid(pthread_t thid, pid_t tid)
1723{
1724 if (thid == 0)
1725 return EINVAL;
1726
1727 pthread_internal_t* thread = (pthread_internal_t*)thid;
1728 thread->kernel_id = tid;
1729
1730 return 0;
1731}