OSDN Git Service

21d789e74a9f4e9b474f08669901d7a2c6b819a4
[gb-231r1-is01/GB_2.3_IS01.git] / frameworks / base / libs / utils / Threads.cpp
1 /*
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
17 // #define LOG_NDEBUG 0
18 #define LOG_TAG "libutils.threads"
19
20 #include <utils/threads.h>
21 #include <utils/Log.h>
22
23 #include <cutils/sched_policy.h>
24 #include <cutils/properties.h>
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <memory.h>
29 #include <errno.h>
30 #include <assert.h>
31 #include <unistd.h>
32
33 #if defined(HAVE_PTHREADS)
34 # include <pthread.h>
35 # include <sched.h>
36 # include <sys/resource.h>
37 #elif defined(HAVE_WIN32_THREADS)
38 # include <windows.h>
39 # include <stdint.h>
40 # include <process.h>
41 # define HAVE_CREATETHREAD  // Cygwin, vs. HAVE__BEGINTHREADEX for MinGW
42 #endif
43
44 #if defined(HAVE_PRCTL)
45 #include <sys/prctl.h>
46 #endif
47
48 /*
49  * ===========================================================================
50  *      Thread wrappers
51  * ===========================================================================
52  */
53
54 using namespace android;
55
56 // ----------------------------------------------------------------------------
57 #if defined(HAVE_PTHREADS)
58 // ----------------------------------------------------------------------------
59
60 /*
61  * Create and run a new thread.
62  *
63  * We create it "detached", so it cleans up after itself.
64  */
65
66 typedef void* (*android_pthread_entry)(void*);
67
68 static pthread_once_t gDoSchedulingGroupOnce = PTHREAD_ONCE_INIT;
69 static bool gDoSchedulingGroup = true;
70
71 static void checkDoSchedulingGroup(void) {
72     char buf[PROPERTY_VALUE_MAX];
73     int len = property_get("debug.sys.noschedgroups", buf, "");
74     if (len > 0) {
75         int temp;
76         if (sscanf(buf, "%d", &temp) == 1) {
77             gDoSchedulingGroup = temp == 0;
78         }
79     }
80 }
81
82 struct thread_data_t {
83     thread_func_t   entryFunction;
84     void*           userData;
85     int             priority;
86     char *          threadName;
87
88     // we use this trampoline when we need to set the priority with
89     // nice/setpriority.
90     static int trampoline(const thread_data_t* t) {
91         thread_func_t f = t->entryFunction;
92         void* u = t->userData;
93         int prio = t->priority;
94         char * name = t->threadName;
95         delete t;
96         setpriority(PRIO_PROCESS, 0, prio);
97         pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
98         if (gDoSchedulingGroup) {
99             if (prio >= ANDROID_PRIORITY_BACKGROUND) {
100                 set_sched_policy(androidGetTid(), SP_BACKGROUND);
101             } else {
102                 set_sched_policy(androidGetTid(), SP_FOREGROUND);
103             }
104         }
105         
106         if (name) {
107 #if defined(HAVE_PRCTL)
108             // Mac OS doesn't have this, and we build libutil for the host too
109             int hasAt = 0;
110             int hasDot = 0;
111             char *s = name;
112             while (*s) {
113                 if (*s == '.') hasDot = 1;
114                 else if (*s == '@') hasAt = 1;
115                 s++;
116             }
117             int len = s - name;
118             if (len < 15 || hasAt || !hasDot) {
119                 s = name;
120             } else {
121                 s = name + len - 15;
122             }
123             prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
124 #endif
125             free(name);
126         }
127         return f(u);
128     }
129 };
130
131 int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
132                                void *userData,
133                                const char* threadName,
134                                int32_t threadPriority,
135                                size_t threadStackSize,
136                                android_thread_id_t *threadId)
137 {
138     pthread_attr_t attr; 
139     pthread_attr_init(&attr);
140     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
141
142 #ifdef HAVE_ANDROID_OS  /* valgrind is rejecting RT-priority create reqs */
143     if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
144         // We could avoid the trampoline if there was a way to get to the
145         // android_thread_id_t (pid) from pthread_t
146         thread_data_t* t = new thread_data_t;
147         t->priority = threadPriority;
148         t->threadName = threadName ? strdup(threadName) : NULL;
149         t->entryFunction = entryFunction;
150         t->userData = userData;
151         entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
152         userData = t;            
153     }
154 #endif
155
156     if (threadStackSize) {
157         pthread_attr_setstacksize(&attr, threadStackSize);
158     }
159     
160     errno = 0;
161     pthread_t thread;
162     int result = pthread_create(&thread, &attr,
163                     (android_pthread_entry)entryFunction, userData);
164     if (result != 0) {
165         LOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
166              "(android threadPriority=%d)",
167             entryFunction, result, errno, threadPriority);
168         return 0;
169     }
170
171     if (threadId != NULL) {
172         *threadId = (android_thread_id_t)thread; // XXX: this is not portable
173     }
174     return 1;
175 }
176
177 android_thread_id_t androidGetThreadId()
178 {
179     return (android_thread_id_t)pthread_self();
180 }
181
182 // ----------------------------------------------------------------------------
183 #elif defined(HAVE_WIN32_THREADS)
184 // ----------------------------------------------------------------------------
185
186 /*
187  * Trampoline to make us __stdcall-compliant.
188  *
189  * We're expected to delete "vDetails" when we're done.
190  */
191 struct threadDetails {
192     int (*func)(void*);
193     void* arg;
194 };
195 static __stdcall unsigned int threadIntermediary(void* vDetails)
196 {
197     struct threadDetails* pDetails = (struct threadDetails*) vDetails;
198     int result;
199
200     result = (*(pDetails->func))(pDetails->arg);
201
202     delete pDetails;
203
204     LOG(LOG_VERBOSE, "thread", "thread exiting\n");
205     return (unsigned int) result;
206 }
207
208 /*
209  * Create and run a new thread.
210  */
211 static bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_id_t *id)
212 {
213     HANDLE hThread;
214     struct threadDetails* pDetails = new threadDetails; // must be on heap
215     unsigned int thrdaddr;
216
217     pDetails->func = fn;
218     pDetails->arg = arg;
219
220 #if defined(HAVE__BEGINTHREADEX)
221     hThread = (HANDLE) _beginthreadex(NULL, 0, threadIntermediary, pDetails, 0,
222                     &thrdaddr);
223     if (hThread == 0)
224 #elif defined(HAVE_CREATETHREAD)
225     hThread = CreateThread(NULL, 0,
226                     (LPTHREAD_START_ROUTINE) threadIntermediary,
227                     (void*) pDetails, 0, (DWORD*) &thrdaddr);
228     if (hThread == NULL)
229 #endif
230     {
231         LOG(LOG_WARN, "thread", "WARNING: thread create failed\n");
232         return false;
233     }
234
235 #if defined(HAVE_CREATETHREAD)
236     /* close the management handle */
237     CloseHandle(hThread);
238 #endif
239
240     if (id != NULL) {
241         *id = (android_thread_id_t)thrdaddr;
242     }
243
244     return true;
245 }
246
247 int androidCreateRawThreadEtc(android_thread_func_t fn,
248                                void *userData,
249                                const char* threadName,
250                                int32_t threadPriority,
251                                size_t threadStackSize,
252                                android_thread_id_t *threadId)
253 {
254     return doCreateThread(  fn, userData, threadId);
255 }
256
257 android_thread_id_t androidGetThreadId()
258 {
259     return (android_thread_id_t)GetCurrentThreadId();
260 }
261
262 // ----------------------------------------------------------------------------
263 #else
264 #error "Threads not supported"
265 #endif
266
267 // ----------------------------------------------------------------------------
268
269 int androidCreateThread(android_thread_func_t fn, void* arg)
270 {
271     return createThreadEtc(fn, arg);
272 }
273
274 int androidCreateThreadGetID(android_thread_func_t fn, void *arg, android_thread_id_t *id)
275 {
276     return createThreadEtc(fn, arg, "android:unnamed_thread",
277                            PRIORITY_DEFAULT, 0, id);
278 }
279
280 static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;
281
282 int androidCreateThreadEtc(android_thread_func_t entryFunction,
283                             void *userData,
284                             const char* threadName,
285                             int32_t threadPriority,
286                             size_t threadStackSize,
287                             android_thread_id_t *threadId)
288 {
289     return gCreateThreadFn(entryFunction, userData, threadName,
290         threadPriority, threadStackSize, threadId);
291 }
292
293 void androidSetCreateThreadFunc(android_create_thread_fn func)
294 {
295     gCreateThreadFn = func;
296 }
297
298 pid_t androidGetTid()
299 {
300 #ifdef HAVE_GETTID
301     return gettid();
302 #else
303     return getpid();
304 #endif
305 }
306
307 int androidSetThreadSchedulingGroup(pid_t tid, int grp)
308 {
309     if (grp > ANDROID_TGROUP_MAX || grp < 0) { 
310         return BAD_VALUE;
311     }
312
313 #if defined(HAVE_PTHREADS)
314     pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
315     if (gDoSchedulingGroup) {
316         if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
317                                           SP_BACKGROUND : SP_FOREGROUND)) {
318             return PERMISSION_DENIED;
319         }
320     }
321 #endif
322     
323     return NO_ERROR;
324 }
325
326 int androidSetThreadPriority(pid_t tid, int pri)
327 {
328     int rc = 0;
329     
330 #if defined(HAVE_PTHREADS)
331     int lasterr = 0;
332
333     pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
334     if (gDoSchedulingGroup) {
335         if (pri >= ANDROID_PRIORITY_BACKGROUND) {
336             rc = set_sched_policy(tid, SP_BACKGROUND);
337         } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
338             rc = set_sched_policy(tid, SP_FOREGROUND);
339         }
340     }
341
342     if (rc) {
343         lasterr = errno;
344     }
345
346     if (setpriority(PRIO_PROCESS, tid, pri) < 0) {
347         rc = INVALID_OPERATION;
348     } else {
349         errno = lasterr;
350     }
351 #endif
352     
353     return rc;
354 }
355
356 namespace android {
357
358 /*
359  * ===========================================================================
360  *      Mutex class
361  * ===========================================================================
362  */
363
364 #if defined(HAVE_PTHREADS)
365 Condition::Condition() {
366     pthread_cond_init(&mCond, NULL);
367 }
368 Condition::Condition(int type) {
369     if (type == SHARED) {
370         pthread_condattr_t attr;
371         pthread_condattr_init(&attr);
372         pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
373         pthread_cond_init(&mCond, &attr);
374         pthread_condattr_destroy(&attr);
375     } else {
376         pthread_cond_init(&mCond, NULL);
377     }
378 }
379 Condition::~Condition() {
380     pthread_cond_destroy(&mCond);
381 }
382 status_t Condition::wait(Mutex& mutex) {
383     return -pthread_cond_wait(&mCond, &mutex.mMutex);
384 }
385 status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
386 #if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
387     struct timespec ts;
388     ts.tv_sec  = reltime/1000000000;
389     ts.tv_nsec = reltime%1000000000;
390     return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
391 #else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
392     struct timespec ts;
393 #if defined(HAVE_POSIX_CLOCKS)
394     clock_gettime(CLOCK_REALTIME, &ts);
395 #else // HAVE_POSIX_CLOCKS
396     // we don't support the clocks here.
397     struct timeval t;
398     gettimeofday(&t, NULL);
399     ts.tv_sec = t.tv_sec;
400     ts.tv_nsec= t.tv_usec*1000;
401 #endif // HAVE_POSIX_CLOCKS
402     ts.tv_sec += reltime/1000000000;
403     ts.tv_nsec+= reltime%1000000000;
404     if (ts.tv_nsec >= 1000000000) {
405         ts.tv_nsec -= 1000000000;
406         ts.tv_sec  += 1;
407     }
408     return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);
409 #endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
410 }
411 void Condition::signal() {
412     pthread_cond_signal(&mCond);
413 }
414 void Condition::broadcast() {
415     pthread_cond_broadcast(&mCond);
416 }
417
418 #elif defined(HAVE_WIN32_THREADS)
419 Mutex::Mutex()
420
421   HANDLE hMutex;
422     assert(sizeof(hMutex) == sizeof(mState));
423     hMutex = CreateMutex(NULL, FALSE, NULL);
424    mState = (void*) hMutex;
425
426 Mutex::Mutex(const char* name)
427
428    // XXX: name not used for now
429    HANDLE hMutex;
430     assert(sizeof(hMutex) == sizeof(mState));
431     hMutex = CreateMutex(NULL, FALSE, NULL);
432     mState = (void*) hMutex;
433 }
434
435 Mutex::Mutex(int type, const char* name)
436 {
437     // XXX: type and name not used for now
438     HANDLE hMutex;
439
440     assert(sizeof(hMutex) == sizeof(mState));
441
442     hMutex = CreateMutex(NULL, FALSE, NULL);
443     mState = (void*) hMutex;
444 }
445
446 Mutex::~Mutex()
447 {
448     CloseHandle((HANDLE) mState);
449 }
450
451 status_t Mutex::lock()
452 {
453     DWORD dwWaitResult;
454     dwWaitResult = WaitForSingleObject((HANDLE) mState, INFINITE);
455     return dwWaitResult != WAIT_OBJECT_0 ? -1 : NO_ERROR;
456 }
457
458 void Mutex::unlock()
459 {
460     if (!ReleaseMutex((HANDLE) mState))
461         LOG(LOG_WARN, "thread", "WARNING: bad result from unlocking mutex\n");
462 }
463
464 status_t Mutex::tryLock()
465 {
466     DWORD dwWaitResult;
467
468     dwWaitResult = WaitForSingleObject((HANDLE) mState, 0);
469     if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT)
470         LOG(LOG_WARN, "thread", "WARNING: bad result from try-locking mutex\n");
471     return (dwWaitResult == WAIT_OBJECT_0) ? 0 : -1;
472 }
473
474 #else
475 #error "Somebody forgot to implement threads for this platform."
476 #endif
477
478
479 /*
480  * ===========================================================================
481  *      Condition class
482  * ===========================================================================
483  */
484
485 #if defined(HAVE_PTHREADS)
486 Mutex::Mutex() {
487     pthread_mutex_init(&mMutex, NULL);
488 }
489 Mutex::Mutex(const char* name) {
490     pthread_mutex_init(&mMutex, NULL);
491 }
492 Mutex::Mutex(int type, const char* name) {
493     if (type == SHARED) {
494         pthread_mutexattr_t attr;
495         pthread_mutexattr_init(&attr);
496         pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
497         pthread_mutex_init(&mMutex, &attr);
498         pthread_mutexattr_destroy(&attr);
499     } else {
500         pthread_mutex_init(&mMutex, NULL);
501     }
502 }
503 Mutex::~Mutex() {
504     pthread_mutex_destroy(&mMutex);
505 }
506 status_t Mutex::lock() {
507     return -pthread_mutex_lock(&mMutex);
508 }
509 void Mutex::unlock() {
510     pthread_mutex_unlock(&mMutex);
511 }
512 status_t Mutex::tryLock() {
513     return -pthread_mutex_trylock(&mMutex);
514 }
515
516
517 #elif defined(HAVE_WIN32_THREADS)
518
519 /*
520  * Windows doesn't have a condition variable solution.  It's possible
521  * to create one, but it's easy to get it wrong.  For a discussion, and
522  * the origin of this implementation, see:
523  *
524  *  http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
525  *
526  * The implementation shown on the page does NOT follow POSIX semantics.
527  * As an optimization they require acquiring the external mutex before
528  * calling signal() and broadcast(), whereas POSIX only requires grabbing
529  * it before calling wait().  The implementation here has been un-optimized
530  * to have the correct behavior.
531  */
532 typedef struct WinCondition {
533     // Number of waiting threads.
534     int                 waitersCount;
535
536     // Serialize access to waitersCount.
537     CRITICAL_SECTION    waitersCountLock;
538
539     // Semaphore used to queue up threads waiting for the condition to
540     // become signaled.
541     HANDLE              sema;
542
543     // An auto-reset event used by the broadcast/signal thread to wait
544     // for all the waiting thread(s) to wake up and be released from
545     // the semaphore.
546     HANDLE              waitersDone;
547
548     // This mutex wouldn't be necessary if we required that the caller
549     // lock the external mutex before calling signal() and broadcast().
550     // I'm trying to mimic pthread semantics though.
551     HANDLE              internalMutex;
552
553     // Keeps track of whether we were broadcasting or signaling.  This
554     // allows us to optimize the code if we're just signaling.
555     bool                wasBroadcast;
556
557     status_t wait(WinCondition* condState, HANDLE hMutex, nsecs_t* abstime)
558     {
559         // Increment the wait count, avoiding race conditions.
560         EnterCriticalSection(&condState->waitersCountLock);
561         condState->waitersCount++;
562         //printf("+++ wait: incr waitersCount to %d (tid=%ld)\n",
563         //    condState->waitersCount, getThreadId());
564         LeaveCriticalSection(&condState->waitersCountLock);
565     
566         DWORD timeout = INFINITE;
567         if (abstime) {
568             nsecs_t reltime = *abstime - systemTime();
569             if (reltime < 0)
570                 reltime = 0;
571             timeout = reltime/1000000;
572         }
573         
574         // Atomically release the external mutex and wait on the semaphore.
575         DWORD res =
576             SignalObjectAndWait(hMutex, condState->sema, timeout, FALSE);
577     
578         //printf("+++ wait: awake (tid=%ld)\n", getThreadId());
579     
580         // Reacquire lock to avoid race conditions.
581         EnterCriticalSection(&condState->waitersCountLock);
582     
583         // No longer waiting.
584         condState->waitersCount--;
585     
586         // Check to see if we're the last waiter after a broadcast.
587         bool lastWaiter = (condState->wasBroadcast && condState->waitersCount == 0);
588     
589         //printf("+++ wait: lastWaiter=%d (wasBc=%d wc=%d)\n",
590         //    lastWaiter, condState->wasBroadcast, condState->waitersCount);
591     
592         LeaveCriticalSection(&condState->waitersCountLock);
593     
594         // If we're the last waiter thread during this particular broadcast
595         // then signal broadcast() that we're all awake.  It'll drop the
596         // internal mutex.
597         if (lastWaiter) {
598             // Atomically signal the "waitersDone" event and wait until we
599             // can acquire the internal mutex.  We want to do this in one step
600             // because it ensures that everybody is in the mutex FIFO before
601             // any thread has a chance to run.  Without it, another thread
602             // could wake up, do work, and hop back in ahead of us.
603             SignalObjectAndWait(condState->waitersDone, condState->internalMutex,
604                 INFINITE, FALSE);
605         } else {
606             // Grab the internal mutex.
607             WaitForSingleObject(condState->internalMutex, INFINITE);
608         }
609     
610         // Release the internal and grab the external.
611         ReleaseMutex(condState->internalMutex);
612         WaitForSingleObject(hMutex, INFINITE);
613     
614         return res == WAIT_OBJECT_0 ? NO_ERROR : -1;
615     }
616 } WinCondition;
617
618 /*
619  * Constructor.  Set up the WinCondition stuff.
620  */
621 Condition::Condition()
622 {
623     WinCondition* condState = new WinCondition;
624
625     condState->waitersCount = 0;
626     condState->wasBroadcast = false;
627     // semaphore: no security, initial value of 0
628     condState->sema = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
629     InitializeCriticalSection(&condState->waitersCountLock);
630     // auto-reset event, not signaled initially
631     condState->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
632     // used so we don't have to lock external mutex on signal/broadcast
633     condState->internalMutex = CreateMutex(NULL, FALSE, NULL);
634
635     mState = condState;
636 }
637
638 /*
639  * Destructor.  Free Windows resources as well as our allocated storage.
640  */
641 Condition::~Condition()
642 {
643     WinCondition* condState = (WinCondition*) mState;
644     if (condState != NULL) {
645         CloseHandle(condState->sema);
646         CloseHandle(condState->waitersDone);
647         delete condState;
648     }
649 }
650
651
652 status_t Condition::wait(Mutex& mutex)
653 {
654     WinCondition* condState = (WinCondition*) mState;
655     HANDLE hMutex = (HANDLE) mutex.mState;
656     
657     return ((WinCondition*)mState)->wait(condState, hMutex, NULL);
658 }
659
660 status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
661 {
662     WinCondition* condState = (WinCondition*) mState;
663     HANDLE hMutex = (HANDLE) mutex.mState;
664     nsecs_t absTime = systemTime()+reltime;
665
666     return ((WinCondition*)mState)->wait(condState, hMutex, &absTime);
667 }
668
669 /*
670  * Signal the condition variable, allowing one thread to continue.
671  */
672 void Condition::signal()
673 {
674     WinCondition* condState = (WinCondition*) mState;
675
676     // Lock the internal mutex.  This ensures that we don't clash with
677     // broadcast().
678     WaitForSingleObject(condState->internalMutex, INFINITE);
679
680     EnterCriticalSection(&condState->waitersCountLock);
681     bool haveWaiters = (condState->waitersCount > 0);
682     LeaveCriticalSection(&condState->waitersCountLock);
683
684     // If no waiters, then this is a no-op.  Otherwise, knock the semaphore
685     // down a notch.
686     if (haveWaiters)
687         ReleaseSemaphore(condState->sema, 1, 0);
688
689     // Release internal mutex.
690     ReleaseMutex(condState->internalMutex);
691 }
692
693 /*
694  * Signal the condition variable, allowing all threads to continue.
695  *
696  * First we have to wake up all threads waiting on the semaphore, then
697  * we wait until all of the threads have actually been woken before
698  * releasing the internal mutex.  This ensures that all threads are woken.
699  */
700 void Condition::broadcast()
701 {
702     WinCondition* condState = (WinCondition*) mState;
703
704     // Lock the internal mutex.  This keeps the guys we're waking up
705     // from getting too far.
706     WaitForSingleObject(condState->internalMutex, INFINITE);
707
708     EnterCriticalSection(&condState->waitersCountLock);
709     bool haveWaiters = false;
710
711     if (condState->waitersCount > 0) {
712         haveWaiters = true;
713         condState->wasBroadcast = true;
714     }
715
716     if (haveWaiters) {
717         // Wake up all the waiters.
718         ReleaseSemaphore(condState->sema, condState->waitersCount, 0);
719
720         LeaveCriticalSection(&condState->waitersCountLock);
721
722         // Wait for all awakened threads to acquire the counting semaphore.
723         // The last guy who was waiting sets this.
724         WaitForSingleObject(condState->waitersDone, INFINITE);
725
726         // Reset wasBroadcast.  (No crit section needed because nobody
727         // else can wake up to poke at it.)
728         condState->wasBroadcast = 0;
729     } else {
730         // nothing to do
731         LeaveCriticalSection(&condState->waitersCountLock);
732     }
733
734     // Release internal mutex.
735     ReleaseMutex(condState->internalMutex);
736 }
737
738 #else
739 #error "condition variables not supported on this platform"
740 #endif
741
742 // ----------------------------------------------------------------------------
743
744 /*
745  * This is our thread object!
746  */
747
748 Thread::Thread(bool canCallJava)
749     :   mCanCallJava(canCallJava),
750         mThread(thread_id_t(-1)),
751         mLock("Thread::mLock"),
752         mStatus(NO_ERROR),
753         mExitPending(false), mRunning(false)
754 {
755 }
756
757 Thread::~Thread()
758 {
759 }
760
761 status_t Thread::readyToRun()
762 {
763     return NO_ERROR;
764 }
765
766 status_t Thread::run(const char* name, int32_t priority, size_t stack)
767 {
768     Mutex::Autolock _l(mLock);
769
770     if (mRunning) {
771         // thread already started
772         return INVALID_OPERATION;
773     }
774
775     // reset status and exitPending to their default value, so we can
776     // try again after an error happened (either below, or in readyToRun())
777     mStatus = NO_ERROR;
778     mExitPending = false;
779     mThread = thread_id_t(-1);
780     
781     // hold a strong reference on ourself
782     mHoldSelf = this;
783
784     mRunning = true;
785
786     bool res;
787     if (mCanCallJava) {
788         res = createThreadEtc(_threadLoop,
789                 this, name, priority, stack, &mThread);
790     } else {
791         res = androidCreateRawThreadEtc(_threadLoop,
792                 this, name, priority, stack, &mThread);
793     }
794     
795     if (res == false) {
796         mStatus = UNKNOWN_ERROR;   // something happened!
797         mRunning = false;
798         mThread = thread_id_t(-1);
799         mHoldSelf.clear();  // "this" may have gone away after this.
800
801         return UNKNOWN_ERROR;
802     }
803     
804     // Do not refer to mStatus here: The thread is already running (may, in fact
805     // already have exited with a valid mStatus result). The NO_ERROR indication
806     // here merely indicates successfully starting the thread and does not
807     // imply successful termination/execution.
808     return NO_ERROR;
809 }
810
811 int Thread::_threadLoop(void* user)
812 {
813     Thread* const self = static_cast<Thread*>(user);
814     sp<Thread> strong(self->mHoldSelf);
815     wp<Thread> weak(strong);
816     self->mHoldSelf.clear();
817
818 #if HAVE_ANDROID_OS
819     // this is very useful for debugging with gdb
820     self->mTid = gettid();
821 #endif
822
823     bool first = true;
824
825     do {
826         bool result;
827         if (first) {
828             first = false;
829             self->mStatus = self->readyToRun();
830             result = (self->mStatus == NO_ERROR);
831
832             if (result && !self->mExitPending) {
833                 // Binder threads (and maybe others) rely on threadLoop
834                 // running at least once after a successful ::readyToRun()
835                 // (unless, of course, the thread has already been asked to exit
836                 // at that point).
837                 // This is because threads are essentially used like this:
838                 //   (new ThreadSubclass())->run();
839                 // The caller therefore does not retain a strong reference to
840                 // the thread and the thread would simply disappear after the
841                 // successful ::readyToRun() call instead of entering the
842                 // threadLoop at least once.
843                 result = self->threadLoop();
844             }
845         } else {
846             result = self->threadLoop();
847         }
848
849         if (result == false || self->mExitPending) {
850             self->mExitPending = true;
851             self->mLock.lock();
852             self->mRunning = false;
853             self->mThreadExitedCondition.broadcast();
854             self->mThread = thread_id_t(-1); // thread id could be reused
855             self->mLock.unlock();
856             break;
857         }
858         
859         // Release our strong reference, to let a chance to the thread
860         // to die a peaceful death.
861         strong.clear();
862         // And immediately, re-acquire a strong reference for the next loop
863         strong = weak.promote();
864     } while(strong != 0);
865     
866     return 0;
867 }
868
869 void Thread::requestExit()
870 {
871     mExitPending = true;
872 }
873
874 status_t Thread::requestExitAndWait()
875 {
876     if (mThread == getThreadId()) {
877         LOGW(
878         "Thread (this=%p): don't call waitForExit() from this "
879         "Thread object's thread. It's a guaranteed deadlock!",
880         this);
881
882         return WOULD_BLOCK;
883     }
884     
885     requestExit();
886
887     Mutex::Autolock _l(mLock);
888     while (mRunning == true) {
889         mThreadExitedCondition.wait(mLock);
890     }
891     mExitPending = false;
892
893     return mStatus;
894 }
895
896 bool Thread::exitPending() const
897 {
898     return mExitPending;
899 }
900
901
902
903 };  // namespace android