blob: 9bcd06330871af6395a206af6c230c34a3ea1ae0 [file] [log] [blame]
The Android Open Source Projectcbb10112009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
The Android Open Source Project7a4c8392009-03-05 14:34:35 -080017// #define LOG_NDEBUG 0
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080018#define LOG_TAG "libutils.threads"
19
Mark Salyzyn5bed8032014-04-30 11:10:46 -070020#include <assert.h>
21#include <errno.h>
22#include <memory.h>
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080023#include <stdio.h>
24#include <stdlib.h>
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080025#include <unistd.h>
26
27#if defined(HAVE_PTHREADS)
28# include <pthread.h>
29# include <sched.h>
30# include <sys/resource.h>
31#elif defined(HAVE_WIN32_THREADS)
32# include <windows.h>
33# include <stdint.h>
34# include <process.h>
35# define HAVE_CREATETHREAD // Cygwin, vs. HAVE__BEGINTHREADEX for MinGW
36#endif
37
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080038#if defined(HAVE_PRCTL)
39#include <sys/prctl.h>
40#endif
41
Mark Salyzyn5bed8032014-04-30 11:10:46 -070042#include <utils/threads.h>
43#include <utils/Log.h>
44
45#include <cutils/sched_policy.h>
46
47#ifdef HAVE_ANDROID_OS
48# define __android_unused
49#else
50# define __android_unused __attribute__((__unused__))
51#endif
52
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080053/*
54 * ===========================================================================
55 * Thread wrappers
56 * ===========================================================================
57 */
58
59using namespace android;
60
61// ----------------------------------------------------------------------------
62#if defined(HAVE_PTHREADS)
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080063// ----------------------------------------------------------------------------
64
65/*
Dianne Hackborn16d217e2010-09-03 17:07:07 -070066 * Create and run a new thread.
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080067 *
68 * We create it "detached", so it cleans up after itself.
69 */
70
71typedef void* (*android_pthread_entry)(void*);
72
73struct thread_data_t {
74 thread_func_t entryFunction;
75 void* userData;
76 int priority;
77 char * threadName;
78
79 // we use this trampoline when we need to set the priority with
Glenn Kastend731f072011-07-11 15:59:22 -070080 // nice/setpriority, and name with prctl.
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080081 static int trampoline(const thread_data_t* t) {
82 thread_func_t f = t->entryFunction;
83 void* u = t->userData;
84 int prio = t->priority;
85 char * name = t->threadName;
86 delete t;
87 setpriority(PRIO_PROCESS, 0, prio);
Glenn Kastenfe34e452012-04-30 16:03:30 -070088 if (prio >= ANDROID_PRIORITY_BACKGROUND) {
89 set_sched_policy(0, SP_BACKGROUND);
90 } else {
91 set_sched_policy(0, SP_FOREGROUND);
Dianne Hackborna78bab02010-09-09 15:50:18 -070092 }
93
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080094 if (name) {
Mathias Agopian6090df82013-03-07 15:34:28 -080095 androidSetThreadName(name);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080096 free(name);
97 }
98 return f(u);
99 }
100};
101
Mathias Agopian6090df82013-03-07 15:34:28 -0800102void androidSetThreadName(const char* name) {
103#if defined(HAVE_PRCTL)
104 // Mac OS doesn't have this, and we build libutil for the host too
105 int hasAt = 0;
106 int hasDot = 0;
107 const char *s = name;
108 while (*s) {
109 if (*s == '.') hasDot = 1;
110 else if (*s == '@') hasAt = 1;
111 s++;
112 }
113 int len = s - name;
114 if (len < 15 || hasAt || !hasDot) {
115 s = name;
116 } else {
117 s = name + len - 15;
118 }
119 prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
120#endif
121}
122
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800123int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
124 void *userData,
Mark Salyzyn5bed8032014-04-30 11:10:46 -0700125 const char* threadName __android_unused,
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800126 int32_t threadPriority,
127 size_t threadStackSize,
128 android_thread_id_t *threadId)
129{
130 pthread_attr_t attr;
131 pthread_attr_init(&attr);
132 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
133
134#ifdef HAVE_ANDROID_OS /* valgrind is rejecting RT-priority create reqs */
135 if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
Glenn Kastend731f072011-07-11 15:59:22 -0700136 // Now that the pthread_t has a method to find the associated
137 // android_thread_id_t (pid) from pthread_t, it would be possible to avoid
138 // this trampoline in some cases as the parent could set the properties
139 // for the child. However, there would be a race condition because the
140 // child becomes ready immediately, and it doesn't work for the name.
141 // prctl(PR_SET_NAME) only works for self; prctl(PR_SET_THREAD_NAME) was
142 // proposed but not yet accepted.
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800143 thread_data_t* t = new thread_data_t;
144 t->priority = threadPriority;
145 t->threadName = threadName ? strdup(threadName) : NULL;
146 t->entryFunction = entryFunction;
147 t->userData = userData;
148 entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
149 userData = t;
150 }
151#endif
152
153 if (threadStackSize) {
154 pthread_attr_setstacksize(&attr, threadStackSize);
155 }
156
157 errno = 0;
158 pthread_t thread;
159 int result = pthread_create(&thread, &attr,
160 (android_pthread_entry)entryFunction, userData);
Le-Chun Wud8734d12011-07-14 14:27:18 -0700161 pthread_attr_destroy(&attr);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800162 if (result != 0) {
Steve Block1b781ab2012-01-06 19:20:56 +0000163 ALOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800164 "(android threadPriority=%d)",
165 entryFunction, result, errno, threadPriority);
166 return 0;
167 }
168
Glenn Kastena538e262011-06-02 08:59:28 -0700169 // Note that *threadID is directly available to the parent only, as it is
170 // assigned after the child starts. Use memory barrier / lock if the child
171 // or other threads also need access.
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800172 if (threadId != NULL) {
173 *threadId = (android_thread_id_t)thread; // XXX: this is not portable
174 }
175 return 1;
176}
177
Glenn Kastend731f072011-07-11 15:59:22 -0700178#ifdef HAVE_ANDROID_OS
179static pthread_t android_thread_id_t_to_pthread(android_thread_id_t thread)
180{
181 return (pthread_t) thread;
182}
183#endif
184
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800185android_thread_id_t androidGetThreadId()
186{
187 return (android_thread_id_t)pthread_self();
188}
189
190// ----------------------------------------------------------------------------
191#elif defined(HAVE_WIN32_THREADS)
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800192// ----------------------------------------------------------------------------
193
194/*
195 * Trampoline to make us __stdcall-compliant.
196 *
197 * We're expected to delete "vDetails" when we're done.
198 */
199struct threadDetails {
200 int (*func)(void*);
201 void* arg;
202};
203static __stdcall unsigned int threadIntermediary(void* vDetails)
204{
205 struct threadDetails* pDetails = (struct threadDetails*) vDetails;
206 int result;
207
208 result = (*(pDetails->func))(pDetails->arg);
209
210 delete pDetails;
211
Steve Block8b4cf772011-10-12 17:27:03 +0100212 ALOG(LOG_VERBOSE, "thread", "thread exiting\n");
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800213 return (unsigned int) result;
214}
215
216/*
217 * Create and run a new thread.
218 */
219static bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_id_t *id)
220{
221 HANDLE hThread;
222 struct threadDetails* pDetails = new threadDetails; // must be on heap
223 unsigned int thrdaddr;
224
225 pDetails->func = fn;
226 pDetails->arg = arg;
227
228#if defined(HAVE__BEGINTHREADEX)
229 hThread = (HANDLE) _beginthreadex(NULL, 0, threadIntermediary, pDetails, 0,
230 &thrdaddr);
231 if (hThread == 0)
232#elif defined(HAVE_CREATETHREAD)
233 hThread = CreateThread(NULL, 0,
234 (LPTHREAD_START_ROUTINE) threadIntermediary,
235 (void*) pDetails, 0, (DWORD*) &thrdaddr);
236 if (hThread == NULL)
237#endif
238 {
Steve Block8b4cf772011-10-12 17:27:03 +0100239 ALOG(LOG_WARN, "thread", "WARNING: thread create failed\n");
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800240 return false;
241 }
242
243#if defined(HAVE_CREATETHREAD)
244 /* close the management handle */
245 CloseHandle(hThread);
246#endif
247
248 if (id != NULL) {
249 *id = (android_thread_id_t)thrdaddr;
250 }
251
252 return true;
253}
254
255int androidCreateRawThreadEtc(android_thread_func_t fn,
256 void *userData,
Mark Salyzyn5bed8032014-04-30 11:10:46 -0700257 const char* /*threadName*/,
258 int32_t /*threadPriority*/,
259 size_t /*threadStackSize*/,
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800260 android_thread_id_t *threadId)
261{
262 return doCreateThread( fn, userData, threadId);
263}
264
265android_thread_id_t androidGetThreadId()
266{
267 return (android_thread_id_t)GetCurrentThreadId();
268}
269
270// ----------------------------------------------------------------------------
271#else
272#error "Threads not supported"
273#endif
274
275// ----------------------------------------------------------------------------
276
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800277int androidCreateThread(android_thread_func_t fn, void* arg)
278{
279 return createThreadEtc(fn, arg);
280}
281
282int androidCreateThreadGetID(android_thread_func_t fn, void *arg, android_thread_id_t *id)
283{
284 return createThreadEtc(fn, arg, "android:unnamed_thread",
285 PRIORITY_DEFAULT, 0, id);
286}
287
288static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;
289
290int androidCreateThreadEtc(android_thread_func_t entryFunction,
291 void *userData,
292 const char* threadName,
293 int32_t threadPriority,
294 size_t threadStackSize,
295 android_thread_id_t *threadId)
296{
297 return gCreateThreadFn(entryFunction, userData, threadName,
298 threadPriority, threadStackSize, threadId);
299}
300
301void androidSetCreateThreadFunc(android_create_thread_fn func)
302{
303 gCreateThreadFn = func;
304}
305
Jeff Brown27e6eaa2012-03-16 22:18:39 -0700306#ifdef HAVE_ANDROID_OS
Dianne Hackborn235af972009-12-07 17:59:37 -0800307int androidSetThreadPriority(pid_t tid, int pri)
308{
309 int rc = 0;
Dianne Hackbornaaa7ef82009-12-08 19:45:59 -0800310
311#if defined(HAVE_PTHREADS)
Dianne Hackborn235af972009-12-07 17:59:37 -0800312 int lasterr = 0;
313
Glenn Kastenfe34e452012-04-30 16:03:30 -0700314 if (pri >= ANDROID_PRIORITY_BACKGROUND) {
315 rc = set_sched_policy(tid, SP_BACKGROUND);
316 } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
317 rc = set_sched_policy(tid, SP_FOREGROUND);
Dianne Hackborn235af972009-12-07 17:59:37 -0800318 }
319
320 if (rc) {
321 lasterr = errno;
322 }
323
324 if (setpriority(PRIO_PROCESS, tid, pri) < 0) {
325 rc = INVALID_OPERATION;
326 } else {
327 errno = lasterr;
328 }
Dianne Hackborn3432efa2009-12-08 16:38:01 -0800329#endif
Dianne Hackborn235af972009-12-07 17:59:37 -0800330
331 return rc;
332}
333
Andreas Huber8ddbed92011-09-15 12:21:40 -0700334int androidGetThreadPriority(pid_t tid) {
Andreas Huber7b4ce612011-09-16 11:47:13 -0700335#if defined(HAVE_PTHREADS)
Andreas Huber8ddbed92011-09-15 12:21:40 -0700336 return getpriority(PRIO_PROCESS, tid);
Andreas Huber7b4ce612011-09-16 11:47:13 -0700337#else
338 return ANDROID_PRIORITY_NORMAL;
339#endif
Andreas Huber8ddbed92011-09-15 12:21:40 -0700340}
341
Jeff Brown27e6eaa2012-03-16 22:18:39 -0700342#endif
Glenn Kasten6fbe0a82011-06-22 16:20:37 -0700343
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800344namespace android {
345
346/*
347 * ===========================================================================
348 * Mutex class
349 * ===========================================================================
350 */
351
Mathias Agopian15554362009-07-12 23:11:20 -0700352#if defined(HAVE_PTHREADS)
353// implemented as inlines in threads.h
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800354#elif defined(HAVE_WIN32_THREADS)
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800355
356Mutex::Mutex()
357{
358 HANDLE hMutex;
359
360 assert(sizeof(hMutex) == sizeof(mState));
361
362 hMutex = CreateMutex(NULL, FALSE, NULL);
363 mState = (void*) hMutex;
364}
365
366Mutex::Mutex(const char* name)
367{
368 // XXX: name not used for now
369 HANDLE hMutex;
370
David 'Digit' Turner9bafd122009-08-01 00:20:17 +0200371 assert(sizeof(hMutex) == sizeof(mState));
372
373 hMutex = CreateMutex(NULL, FALSE, NULL);
374 mState = (void*) hMutex;
375}
376
377Mutex::Mutex(int type, const char* name)
378{
379 // XXX: type and name not used for now
380 HANDLE hMutex;
381
382 assert(sizeof(hMutex) == sizeof(mState));
383
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800384 hMutex = CreateMutex(NULL, FALSE, NULL);
385 mState = (void*) hMutex;
386}
387
388Mutex::~Mutex()
389{
390 CloseHandle((HANDLE) mState);
391}
392
393status_t Mutex::lock()
394{
395 DWORD dwWaitResult;
396 dwWaitResult = WaitForSingleObject((HANDLE) mState, INFINITE);
397 return dwWaitResult != WAIT_OBJECT_0 ? -1 : NO_ERROR;
398}
399
400void Mutex::unlock()
401{
402 if (!ReleaseMutex((HANDLE) mState))
Steve Block8b4cf772011-10-12 17:27:03 +0100403 ALOG(LOG_WARN, "thread", "WARNING: bad result from unlocking mutex\n");
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800404}
405
406status_t Mutex::tryLock()
407{
408 DWORD dwWaitResult;
409
410 dwWaitResult = WaitForSingleObject((HANDLE) mState, 0);
411 if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT)
Steve Block8b4cf772011-10-12 17:27:03 +0100412 ALOG(LOG_WARN, "thread", "WARNING: bad result from try-locking mutex\n");
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800413 return (dwWaitResult == WAIT_OBJECT_0) ? 0 : -1;
414}
415
416#else
417#error "Somebody forgot to implement threads for this platform."
418#endif
419
420
421/*
422 * ===========================================================================
423 * Condition class
424 * ===========================================================================
425 */
426
Mathias Agopian15554362009-07-12 23:11:20 -0700427#if defined(HAVE_PTHREADS)
428// implemented as inlines in threads.h
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800429#elif defined(HAVE_WIN32_THREADS)
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800430
431/*
432 * Windows doesn't have a condition variable solution. It's possible
433 * to create one, but it's easy to get it wrong. For a discussion, and
434 * the origin of this implementation, see:
435 *
436 * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
437 *
438 * The implementation shown on the page does NOT follow POSIX semantics.
439 * As an optimization they require acquiring the external mutex before
440 * calling signal() and broadcast(), whereas POSIX only requires grabbing
441 * it before calling wait(). The implementation here has been un-optimized
442 * to have the correct behavior.
443 */
444typedef struct WinCondition {
445 // Number of waiting threads.
446 int waitersCount;
447
448 // Serialize access to waitersCount.
449 CRITICAL_SECTION waitersCountLock;
450
451 // Semaphore used to queue up threads waiting for the condition to
452 // become signaled.
453 HANDLE sema;
454
455 // An auto-reset event used by the broadcast/signal thread to wait
456 // for all the waiting thread(s) to wake up and be released from
457 // the semaphore.
458 HANDLE waitersDone;
459
460 // This mutex wouldn't be necessary if we required that the caller
461 // lock the external mutex before calling signal() and broadcast().
462 // I'm trying to mimic pthread semantics though.
463 HANDLE internalMutex;
464
465 // Keeps track of whether we were broadcasting or signaling. This
466 // allows us to optimize the code if we're just signaling.
467 bool wasBroadcast;
468
469 status_t wait(WinCondition* condState, HANDLE hMutex, nsecs_t* abstime)
470 {
471 // Increment the wait count, avoiding race conditions.
472 EnterCriticalSection(&condState->waitersCountLock);
473 condState->waitersCount++;
474 //printf("+++ wait: incr waitersCount to %d (tid=%ld)\n",
475 // condState->waitersCount, getThreadId());
476 LeaveCriticalSection(&condState->waitersCountLock);
477
478 DWORD timeout = INFINITE;
479 if (abstime) {
480 nsecs_t reltime = *abstime - systemTime();
481 if (reltime < 0)
482 reltime = 0;
483 timeout = reltime/1000000;
484 }
485
486 // Atomically release the external mutex and wait on the semaphore.
487 DWORD res =
488 SignalObjectAndWait(hMutex, condState->sema, timeout, FALSE);
489
490 //printf("+++ wait: awake (tid=%ld)\n", getThreadId());
491
492 // Reacquire lock to avoid race conditions.
493 EnterCriticalSection(&condState->waitersCountLock);
494
495 // No longer waiting.
496 condState->waitersCount--;
497
498 // Check to see if we're the last waiter after a broadcast.
499 bool lastWaiter = (condState->wasBroadcast && condState->waitersCount == 0);
500
501 //printf("+++ wait: lastWaiter=%d (wasBc=%d wc=%d)\n",
502 // lastWaiter, condState->wasBroadcast, condState->waitersCount);
503
504 LeaveCriticalSection(&condState->waitersCountLock);
505
506 // If we're the last waiter thread during this particular broadcast
507 // then signal broadcast() that we're all awake. It'll drop the
508 // internal mutex.
509 if (lastWaiter) {
510 // Atomically signal the "waitersDone" event and wait until we
511 // can acquire the internal mutex. We want to do this in one step
512 // because it ensures that everybody is in the mutex FIFO before
513 // any thread has a chance to run. Without it, another thread
514 // could wake up, do work, and hop back in ahead of us.
515 SignalObjectAndWait(condState->waitersDone, condState->internalMutex,
516 INFINITE, FALSE);
517 } else {
518 // Grab the internal mutex.
519 WaitForSingleObject(condState->internalMutex, INFINITE);
520 }
521
522 // Release the internal and grab the external.
523 ReleaseMutex(condState->internalMutex);
524 WaitForSingleObject(hMutex, INFINITE);
525
526 return res == WAIT_OBJECT_0 ? NO_ERROR : -1;
527 }
528} WinCondition;
529
530/*
531 * Constructor. Set up the WinCondition stuff.
532 */
533Condition::Condition()
534{
535 WinCondition* condState = new WinCondition;
536
537 condState->waitersCount = 0;
538 condState->wasBroadcast = false;
539 // semaphore: no security, initial value of 0
540 condState->sema = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
541 InitializeCriticalSection(&condState->waitersCountLock);
542 // auto-reset event, not signaled initially
543 condState->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
544 // used so we don't have to lock external mutex on signal/broadcast
545 condState->internalMutex = CreateMutex(NULL, FALSE, NULL);
546
547 mState = condState;
548}
549
550/*
551 * Destructor. Free Windows resources as well as our allocated storage.
552 */
553Condition::~Condition()
554{
555 WinCondition* condState = (WinCondition*) mState;
556 if (condState != NULL) {
557 CloseHandle(condState->sema);
558 CloseHandle(condState->waitersDone);
559 delete condState;
560 }
561}
562
563
564status_t Condition::wait(Mutex& mutex)
565{
566 WinCondition* condState = (WinCondition*) mState;
567 HANDLE hMutex = (HANDLE) mutex.mState;
568
569 return ((WinCondition*)mState)->wait(condState, hMutex, NULL);
570}
571
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800572status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
573{
David 'Digit' Turner9bafd122009-08-01 00:20:17 +0200574 WinCondition* condState = (WinCondition*) mState;
575 HANDLE hMutex = (HANDLE) mutex.mState;
576 nsecs_t absTime = systemTime()+reltime;
577
578 return ((WinCondition*)mState)->wait(condState, hMutex, &absTime);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800579}
580
581/*
582 * Signal the condition variable, allowing one thread to continue.
583 */
584void Condition::signal()
585{
586 WinCondition* condState = (WinCondition*) mState;
587
588 // Lock the internal mutex. This ensures that we don't clash with
589 // broadcast().
590 WaitForSingleObject(condState->internalMutex, INFINITE);
591
592 EnterCriticalSection(&condState->waitersCountLock);
593 bool haveWaiters = (condState->waitersCount > 0);
594 LeaveCriticalSection(&condState->waitersCountLock);
595
596 // If no waiters, then this is a no-op. Otherwise, knock the semaphore
597 // down a notch.
598 if (haveWaiters)
599 ReleaseSemaphore(condState->sema, 1, 0);
600
601 // Release internal mutex.
602 ReleaseMutex(condState->internalMutex);
603}
604
605/*
606 * Signal the condition variable, allowing all threads to continue.
607 *
608 * First we have to wake up all threads waiting on the semaphore, then
609 * we wait until all of the threads have actually been woken before
610 * releasing the internal mutex. This ensures that all threads are woken.
611 */
612void Condition::broadcast()
613{
614 WinCondition* condState = (WinCondition*) mState;
615
616 // Lock the internal mutex. This keeps the guys we're waking up
617 // from getting too far.
618 WaitForSingleObject(condState->internalMutex, INFINITE);
619
620 EnterCriticalSection(&condState->waitersCountLock);
621 bool haveWaiters = false;
622
623 if (condState->waitersCount > 0) {
624 haveWaiters = true;
625 condState->wasBroadcast = true;
626 }
627
628 if (haveWaiters) {
629 // Wake up all the waiters.
630 ReleaseSemaphore(condState->sema, condState->waitersCount, 0);
631
632 LeaveCriticalSection(&condState->waitersCountLock);
633
634 // Wait for all awakened threads to acquire the counting semaphore.
635 // The last guy who was waiting sets this.
636 WaitForSingleObject(condState->waitersDone, INFINITE);
637
638 // Reset wasBroadcast. (No crit section needed because nobody
639 // else can wake up to poke at it.)
640 condState->wasBroadcast = 0;
641 } else {
642 // nothing to do
643 LeaveCriticalSection(&condState->waitersCountLock);
644 }
645
646 // Release internal mutex.
647 ReleaseMutex(condState->internalMutex);
648}
649
650#else
651#error "condition variables not supported on this platform"
652#endif
653
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800654// ----------------------------------------------------------------------------
655
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800656/*
657 * This is our thread object!
658 */
659
660Thread::Thread(bool canCallJava)
661 : mCanCallJava(canCallJava),
662 mThread(thread_id_t(-1)),
663 mLock("Thread::mLock"),
664 mStatus(NO_ERROR),
665 mExitPending(false), mRunning(false)
Glenn Kasten966a48f2011-02-01 11:32:29 -0800666#ifdef HAVE_ANDROID_OS
667 , mTid(-1)
668#endif
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800669{
670}
671
672Thread::~Thread()
673{
674}
675
676status_t Thread::readyToRun()
677{
678 return NO_ERROR;
679}
680
681status_t Thread::run(const char* name, int32_t priority, size_t stack)
682{
683 Mutex::Autolock _l(mLock);
684
685 if (mRunning) {
686 // thread already started
687 return INVALID_OPERATION;
688 }
689
690 // reset status and exitPending to their default value, so we can
691 // try again after an error happened (either below, or in readyToRun())
692 mStatus = NO_ERROR;
693 mExitPending = false;
694 mThread = thread_id_t(-1);
695
696 // hold a strong reference on ourself
697 mHoldSelf = this;
698
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800699 mRunning = true;
700
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800701 bool res;
702 if (mCanCallJava) {
703 res = createThreadEtc(_threadLoop,
704 this, name, priority, stack, &mThread);
705 } else {
706 res = androidCreateRawThreadEtc(_threadLoop,
707 this, name, priority, stack, &mThread);
708 }
709
710 if (res == false) {
711 mStatus = UNKNOWN_ERROR; // something happened!
712 mRunning = false;
713 mThread = thread_id_t(-1);
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800714 mHoldSelf.clear(); // "this" may have gone away after this.
715
716 return UNKNOWN_ERROR;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800717 }
718
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800719 // Do not refer to mStatus here: The thread is already running (may, in fact
720 // already have exited with a valid mStatus result). The NO_ERROR indication
721 // here merely indicates successfully starting the thread and does not
722 // imply successful termination/execution.
723 return NO_ERROR;
Glenn Kasten966a48f2011-02-01 11:32:29 -0800724
725 // Exiting scope of mLock is a memory barrier and allows new thread to run
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800726}
727
728int Thread::_threadLoop(void* user)
729{
730 Thread* const self = static_cast<Thread*>(user);
Glenn Kasten966a48f2011-02-01 11:32:29 -0800731
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800732 sp<Thread> strong(self->mHoldSelf);
733 wp<Thread> weak(strong);
734 self->mHoldSelf.clear();
735
Kenny Rootdafff0b2011-02-16 10:13:53 -0800736#ifdef HAVE_ANDROID_OS
Mathias Agopian51ce3ad2009-09-09 02:38:13 -0700737 // this is very useful for debugging with gdb
738 self->mTid = gettid();
739#endif
740
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800741 bool first = true;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800742
743 do {
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800744 bool result;
745 if (first) {
746 first = false;
747 self->mStatus = self->readyToRun();
748 result = (self->mStatus == NO_ERROR);
749
Glenn Kasten966a48f2011-02-01 11:32:29 -0800750 if (result && !self->exitPending()) {
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800751 // Binder threads (and maybe others) rely on threadLoop
752 // running at least once after a successful ::readyToRun()
753 // (unless, of course, the thread has already been asked to exit
754 // at that point).
755 // This is because threads are essentially used like this:
756 // (new ThreadSubclass())->run();
757 // The caller therefore does not retain a strong reference to
758 // the thread and the thread would simply disappear after the
759 // successful ::readyToRun() call instead of entering the
760 // threadLoop at least once.
761 result = self->threadLoop();
762 }
763 } else {
764 result = self->threadLoop();
765 }
766
Glenn Kasten966a48f2011-02-01 11:32:29 -0800767 // establish a scope for mLock
768 {
769 Mutex::Autolock _l(self->mLock);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800770 if (result == false || self->mExitPending) {
771 self->mExitPending = true;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800772 self->mRunning = false;
Eric Laurentfe2c4632011-01-04 11:58:04 -0800773 // clear thread ID so that requestExitAndWait() does not exit if
774 // called by a new thread using the same thread ID as this one.
775 self->mThread = thread_id_t(-1);
Glenn Kasten966a48f2011-02-01 11:32:29 -0800776 // note that interested observers blocked in requestExitAndWait are
777 // awoken by broadcast, but blocked on mLock until break exits scope
Mathias Agopian51ce3ad2009-09-09 02:38:13 -0700778 self->mThreadExitedCondition.broadcast();
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800779 break;
780 }
Glenn Kasten966a48f2011-02-01 11:32:29 -0800781 }
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800782
783 // Release our strong reference, to let a chance to the thread
784 // to die a peaceful death.
785 strong.clear();
Mathias Agopian51ce3ad2009-09-09 02:38:13 -0700786 // And immediately, re-acquire a strong reference for the next loop
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800787 strong = weak.promote();
788 } while(strong != 0);
789
790 return 0;
791}
792
793void Thread::requestExit()
794{
Glenn Kasten966a48f2011-02-01 11:32:29 -0800795 Mutex::Autolock _l(mLock);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800796 mExitPending = true;
797}
798
799status_t Thread::requestExitAndWait()
800{
Glenn Kastena538e262011-06-02 08:59:28 -0700801 Mutex::Autolock _l(mLock);
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800802 if (mThread == getThreadId()) {
Steve Block61d341b2012-01-05 23:22:43 +0000803 ALOGW(
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800804 "Thread (this=%p): don't call waitForExit() from this "
805 "Thread object's thread. It's a guaranteed deadlock!",
806 this);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800807
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800808 return WOULD_BLOCK;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800809 }
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800810
Glenn Kastena538e262011-06-02 08:59:28 -0700811 mExitPending = true;
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800812
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800813 while (mRunning == true) {
814 mThreadExitedCondition.wait(mLock);
815 }
Glenn Kasten966a48f2011-02-01 11:32:29 -0800816 // This next line is probably not needed any more, but is being left for
817 // historical reference. Note that each interested party will clear flag.
The Android Open Source Project7a4c8392009-03-05 14:34:35 -0800818 mExitPending = false;
819
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800820 return mStatus;
821}
822
Glenn Kasten6839e8e2011-06-23 12:55:29 -0700823status_t Thread::join()
824{
825 Mutex::Autolock _l(mLock);
826 if (mThread == getThreadId()) {
Steve Block61d341b2012-01-05 23:22:43 +0000827 ALOGW(
Glenn Kasten6839e8e2011-06-23 12:55:29 -0700828 "Thread (this=%p): don't call join() from this "
829 "Thread object's thread. It's a guaranteed deadlock!",
830 this);
831
832 return WOULD_BLOCK;
833 }
834
835 while (mRunning == true) {
836 mThreadExitedCondition.wait(mLock);
837 }
838
839 return mStatus;
840}
841
Romain Guy31ba37f2013-03-11 14:34:56 -0700842bool Thread::isRunning() const {
843 Mutex::Autolock _l(mLock);
844 return mRunning;
845}
846
Glenn Kastend731f072011-07-11 15:59:22 -0700847#ifdef HAVE_ANDROID_OS
848pid_t Thread::getTid() const
849{
850 // mTid is not defined until the child initializes it, and the caller may need it earlier
851 Mutex::Autolock _l(mLock);
852 pid_t tid;
853 if (mRunning) {
854 pthread_t pthread = android_thread_id_t_to_pthread(mThread);
Elliott Hughes7bf5f202014-09-12 10:19:08 -0700855 tid = pthread_gettid_np(pthread);
Glenn Kastend731f072011-07-11 15:59:22 -0700856 } else {
857 ALOGW("Thread (this=%p): getTid() is undefined before run()", this);
858 tid = -1;
859 }
860 return tid;
861}
862#endif
863
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800864bool Thread::exitPending() const
865{
Glenn Kasten966a48f2011-02-01 11:32:29 -0800866 Mutex::Autolock _l(mLock);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800867 return mExitPending;
868}
869
870
871
872}; // namespace android