Home | History | Annotate | Download | only in utils
      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     pthread_attr_destroy(&attr);
    165     if (result != 0) {
    166         LOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
    167              "(android threadPriority=%d)",
    168             entryFunction, result, errno, threadPriority);
    169         return 0;
    170     }
    171 
    172     // Note that *threadID is directly available to the parent only, as it is
    173     // assigned after the child starts.  Use memory barrier / lock if the child
    174     // or other threads also need access.
    175     if (threadId != NULL) {
    176         *threadId = (android_thread_id_t)thread; // XXX: this is not portable
    177     }
    178     return 1;
    179 }
    180 
    181 android_thread_id_t androidGetThreadId()
    182 {
    183     return (android_thread_id_t)pthread_self();
    184 }
    185 
    186 // ----------------------------------------------------------------------------
    187 #elif defined(HAVE_WIN32_THREADS)
    188 // ----------------------------------------------------------------------------
    189 
    190 /*
    191  * Trampoline to make us __stdcall-compliant.
    192  *
    193  * We're expected to delete "vDetails" when we're done.
    194  */
    195 struct threadDetails {
    196     int (*func)(void*);
    197     void* arg;
    198 };
    199 static __stdcall unsigned int threadIntermediary(void* vDetails)
    200 {
    201     struct threadDetails* pDetails = (struct threadDetails*) vDetails;
    202     int result;
    203 
    204     result = (*(pDetails->func))(pDetails->arg);
    205 
    206     delete pDetails;
    207 
    208     LOG(LOG_VERBOSE, "thread", "thread exiting\n");
    209     return (unsigned int) result;
    210 }
    211 
    212 /*
    213  * Create and run a new thread.
    214  */
    215 static bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_id_t *id)
    216 {
    217     HANDLE hThread;
    218     struct threadDetails* pDetails = new threadDetails; // must be on heap
    219     unsigned int thrdaddr;
    220 
    221     pDetails->func = fn;
    222     pDetails->arg = arg;
    223 
    224 #if defined(HAVE__BEGINTHREADEX)
    225     hThread = (HANDLE) _beginthreadex(NULL, 0, threadIntermediary, pDetails, 0,
    226                     &thrdaddr);
    227     if (hThread == 0)
    228 #elif defined(HAVE_CREATETHREAD)
    229     hThread = CreateThread(NULL, 0,
    230                     (LPTHREAD_START_ROUTINE) threadIntermediary,
    231                     (void*) pDetails, 0, (DWORD*) &thrdaddr);
    232     if (hThread == NULL)
    233 #endif
    234     {
    235         LOG(LOG_WARN, "thread", "WARNING: thread create failed\n");
    236         return false;
    237     }
    238 
    239 #if defined(HAVE_CREATETHREAD)
    240     /* close the management handle */
    241     CloseHandle(hThread);
    242 #endif
    243 
    244     if (id != NULL) {
    245       	*id = (android_thread_id_t)thrdaddr;
    246     }
    247 
    248     return true;
    249 }
    250 
    251 int androidCreateRawThreadEtc(android_thread_func_t fn,
    252                                void *userData,
    253                                const char* threadName,
    254                                int32_t threadPriority,
    255                                size_t threadStackSize,
    256                                android_thread_id_t *threadId)
    257 {
    258     return doCreateThread(  fn, userData, threadId);
    259 }
    260 
    261 android_thread_id_t androidGetThreadId()
    262 {
    263     return (android_thread_id_t)GetCurrentThreadId();
    264 }
    265 
    266 // ----------------------------------------------------------------------------
    267 #else
    268 #error "Threads not supported"
    269 #endif
    270 
    271 // ----------------------------------------------------------------------------
    272 
    273 int androidCreateThread(android_thread_func_t fn, void* arg)
    274 {
    275     return createThreadEtc(fn, arg);
    276 }
    277 
    278 int androidCreateThreadGetID(android_thread_func_t fn, void *arg, android_thread_id_t *id)
    279 {
    280     return createThreadEtc(fn, arg, "android:unnamed_thread",
    281                            PRIORITY_DEFAULT, 0, id);
    282 }
    283 
    284 static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;
    285 
    286 int androidCreateThreadEtc(android_thread_func_t entryFunction,
    287                             void *userData,
    288                             const char* threadName,
    289                             int32_t threadPriority,
    290                             size_t threadStackSize,
    291                             android_thread_id_t *threadId)
    292 {
    293     return gCreateThreadFn(entryFunction, userData, threadName,
    294         threadPriority, threadStackSize, threadId);
    295 }
    296 
    297 void androidSetCreateThreadFunc(android_create_thread_fn func)
    298 {
    299     gCreateThreadFn = func;
    300 }
    301 
    302 pid_t androidGetTid()
    303 {
    304 #ifdef HAVE_GETTID
    305     return gettid();
    306 #else
    307     return getpid();
    308 #endif
    309 }
    310 
    311 int androidSetThreadSchedulingGroup(pid_t tid, int grp)
    312 {
    313     if (grp > ANDROID_TGROUP_MAX || grp < 0) {
    314         return BAD_VALUE;
    315     }
    316 
    317 #if defined(HAVE_PTHREADS)
    318     pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
    319     if (gDoSchedulingGroup) {
    320         // set_sched_policy does not support tid == 0
    321         if (tid == 0) {
    322             tid = androidGetTid();
    323         }
    324         if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
    325                                           SP_BACKGROUND : SP_FOREGROUND)) {
    326             return PERMISSION_DENIED;
    327         }
    328     }
    329 #endif
    330 
    331     return NO_ERROR;
    332 }
    333 
    334 int androidSetThreadPriority(pid_t tid, int pri)
    335 {
    336     int rc = 0;
    337 
    338 #if defined(HAVE_PTHREADS)
    339     int lasterr = 0;
    340 
    341     pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
    342     if (gDoSchedulingGroup) {
    343         // set_sched_policy does not support tid == 0
    344         int policy_tid;
    345         if (tid == 0) {
    346             policy_tid = androidGetTid();
    347         } else {
    348             policy_tid = tid;
    349         }
    350         if (pri >= ANDROID_PRIORITY_BACKGROUND) {
    351             rc = set_sched_policy(policy_tid, SP_BACKGROUND);
    352         } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
    353             rc = set_sched_policy(policy_tid, SP_FOREGROUND);
    354         }
    355     }
    356 
    357     if (rc) {
    358         lasterr = errno;
    359     }
    360 
    361     if (setpriority(PRIO_PROCESS, tid, pri) < 0) {
    362         rc = INVALID_OPERATION;
    363     } else {
    364         errno = lasterr;
    365     }
    366 #endif
    367 
    368     return rc;
    369 }
    370 
    371 int androidGetThreadPriority(pid_t tid) {
    372 #if defined(HAVE_PTHREADS)
    373     return getpriority(PRIO_PROCESS, tid);
    374 #else
    375     return ANDROID_PRIORITY_NORMAL;
    376 #endif
    377 }
    378 
    379 int androidGetThreadSchedulingGroup(pid_t tid)
    380 {
    381     int ret = ANDROID_TGROUP_DEFAULT;
    382 
    383 #if defined(HAVE_PTHREADS)
    384     // convention is to not call get/set_sched_policy methods if disabled by property
    385     pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
    386     if (gDoSchedulingGroup) {
    387         SchedPolicy policy;
    388         // get_sched_policy does not support tid == 0
    389         if (tid == 0) {
    390             tid = androidGetTid();
    391         }
    392         if (get_sched_policy(tid, &policy) < 0) {
    393             ret = INVALID_OPERATION;
    394         } else {
    395             switch (policy) {
    396             case SP_BACKGROUND:
    397                 ret = ANDROID_TGROUP_BG_NONINTERACT;
    398                 break;
    399             case SP_FOREGROUND:
    400                 ret = ANDROID_TGROUP_FG_BOOST;
    401                 break;
    402             default:
    403                 // should not happen, as enum SchedPolicy does not have any other values
    404                 ret = INVALID_OPERATION;
    405                 break;
    406             }
    407         }
    408     }
    409 #endif
    410 
    411     return ret;
    412 }
    413 
    414 namespace android {
    415 
    416 /*
    417  * ===========================================================================
    418  *      Mutex class
    419  * ===========================================================================
    420  */
    421 
    422 #if defined(HAVE_PTHREADS)
    423 // implemented as inlines in threads.h
    424 #elif defined(HAVE_WIN32_THREADS)
    425 
    426 Mutex::Mutex()
    427 {
    428     HANDLE hMutex;
    429 
    430     assert(sizeof(hMutex) == sizeof(mState));
    431 
    432     hMutex = CreateMutex(NULL, FALSE, NULL);
    433     mState = (void*) hMutex;
    434 }
    435 
    436 Mutex::Mutex(const char* name)
    437 {
    438     // XXX: name not used for now
    439     HANDLE hMutex;
    440 
    441     assert(sizeof(hMutex) == sizeof(mState));
    442 
    443     hMutex = CreateMutex(NULL, FALSE, NULL);
    444     mState = (void*) hMutex;
    445 }
    446 
    447 Mutex::Mutex(int type, const char* name)
    448 {
    449     // XXX: type and name not used for now
    450     HANDLE hMutex;
    451 
    452     assert(sizeof(hMutex) == sizeof(mState));
    453 
    454     hMutex = CreateMutex(NULL, FALSE, NULL);
    455     mState = (void*) hMutex;
    456 }
    457 
    458 Mutex::~Mutex()
    459 {
    460     CloseHandle((HANDLE) mState);
    461 }
    462 
    463 status_t Mutex::lock()
    464 {
    465     DWORD dwWaitResult;
    466     dwWaitResult = WaitForSingleObject((HANDLE) mState, INFINITE);
    467     return dwWaitResult != WAIT_OBJECT_0 ? -1 : NO_ERROR;
    468 }
    469 
    470 void Mutex::unlock()
    471 {
    472     if (!ReleaseMutex((HANDLE) mState))
    473         LOG(LOG_WARN, "thread", "WARNING: bad result from unlocking mutex\n");
    474 }
    475 
    476 status_t Mutex::tryLock()
    477 {
    478     DWORD dwWaitResult;
    479 
    480     dwWaitResult = WaitForSingleObject((HANDLE) mState, 0);
    481     if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT)
    482         LOG(LOG_WARN, "thread", "WARNING: bad result from try-locking mutex\n");
    483     return (dwWaitResult == WAIT_OBJECT_0) ? 0 : -1;
    484 }
    485 
    486 #else
    487 #error "Somebody forgot to implement threads for this platform."
    488 #endif
    489 
    490 
    491 /*
    492  * ===========================================================================
    493  *      Condition class
    494  * ===========================================================================
    495  */
    496 
    497 #if defined(HAVE_PTHREADS)
    498 // implemented as inlines in threads.h
    499 #elif defined(HAVE_WIN32_THREADS)
    500 
    501 /*
    502  * Windows doesn't have a condition variable solution.  It's possible
    503  * to create one, but it's easy to get it wrong.  For a discussion, and
    504  * the origin of this implementation, see:
    505  *
    506  *  http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
    507  *
    508  * The implementation shown on the page does NOT follow POSIX semantics.
    509  * As an optimization they require acquiring the external mutex before
    510  * calling signal() and broadcast(), whereas POSIX only requires grabbing
    511  * it before calling wait().  The implementation here has been un-optimized
    512  * to have the correct behavior.
    513  */
    514 typedef struct WinCondition {
    515     // Number of waiting threads.
    516     int                 waitersCount;
    517 
    518     // Serialize access to waitersCount.
    519     CRITICAL_SECTION    waitersCountLock;
    520 
    521     // Semaphore used to queue up threads waiting for the condition to
    522     // become signaled.
    523     HANDLE              sema;
    524 
    525     // An auto-reset event used by the broadcast/signal thread to wait
    526     // for all the waiting thread(s) to wake up and be released from
    527     // the semaphore.
    528     HANDLE              waitersDone;
    529 
    530     // This mutex wouldn't be necessary if we required that the caller
    531     // lock the external mutex before calling signal() and broadcast().
    532     // I'm trying to mimic pthread semantics though.
    533     HANDLE              internalMutex;
    534 
    535     // Keeps track of whether we were broadcasting or signaling.  This
    536     // allows us to optimize the code if we're just signaling.
    537     bool                wasBroadcast;
    538 
    539     status_t wait(WinCondition* condState, HANDLE hMutex, nsecs_t* abstime)
    540     {
    541         // Increment the wait count, avoiding race conditions.
    542         EnterCriticalSection(&condState->waitersCountLock);
    543         condState->waitersCount++;
    544         //printf("+++ wait: incr waitersCount to %d (tid=%ld)\n",
    545         //    condState->waitersCount, getThreadId());
    546         LeaveCriticalSection(&condState->waitersCountLock);
    547 
    548         DWORD timeout = INFINITE;
    549         if (abstime) {
    550             nsecs_t reltime = *abstime - systemTime();
    551             if (reltime < 0)
    552                 reltime = 0;
    553             timeout = reltime/1000000;
    554         }
    555 
    556         // Atomically release the external mutex and wait on the semaphore.
    557         DWORD res =
    558             SignalObjectAndWait(hMutex, condState->sema, timeout, FALSE);
    559 
    560         //printf("+++ wait: awake (tid=%ld)\n", getThreadId());
    561 
    562         // Reacquire lock to avoid race conditions.
    563         EnterCriticalSection(&condState->waitersCountLock);
    564 
    565         // No longer waiting.
    566         condState->waitersCount--;
    567 
    568         // Check to see if we're the last waiter after a broadcast.
    569         bool lastWaiter = (condState->wasBroadcast && condState->waitersCount == 0);
    570 
    571         //printf("+++ wait: lastWaiter=%d (wasBc=%d wc=%d)\n",
    572         //    lastWaiter, condState->wasBroadcast, condState->waitersCount);
    573 
    574         LeaveCriticalSection(&condState->waitersCountLock);
    575 
    576         // If we're the last waiter thread during this particular broadcast
    577         // then signal broadcast() that we're all awake.  It'll drop the
    578         // internal mutex.
    579         if (lastWaiter) {
    580             // Atomically signal the "waitersDone" event and wait until we
    581             // can acquire the internal mutex.  We want to do this in one step
    582             // because it ensures that everybody is in the mutex FIFO before
    583             // any thread has a chance to run.  Without it, another thread
    584             // could wake up, do work, and hop back in ahead of us.
    585             SignalObjectAndWait(condState->waitersDone, condState->internalMutex,
    586                 INFINITE, FALSE);
    587         } else {
    588             // Grab the internal mutex.
    589             WaitForSingleObject(condState->internalMutex, INFINITE);
    590         }
    591 
    592         // Release the internal and grab the external.
    593         ReleaseMutex(condState->internalMutex);
    594         WaitForSingleObject(hMutex, INFINITE);
    595 
    596         return res == WAIT_OBJECT_0 ? NO_ERROR : -1;
    597     }
    598 } WinCondition;
    599 
    600 /*
    601  * Constructor.  Set up the WinCondition stuff.
    602  */
    603 Condition::Condition()
    604 {
    605     WinCondition* condState = new WinCondition;
    606 
    607     condState->waitersCount = 0;
    608     condState->wasBroadcast = false;
    609     // semaphore: no security, initial value of 0
    610     condState->sema = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
    611     InitializeCriticalSection(&condState->waitersCountLock);
    612     // auto-reset event, not signaled initially
    613     condState->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
    614     // used so we don't have to lock external mutex on signal/broadcast
    615     condState->internalMutex = CreateMutex(NULL, FALSE, NULL);
    616 
    617     mState = condState;
    618 }
    619 
    620 /*
    621  * Destructor.  Free Windows resources as well as our allocated storage.
    622  */
    623 Condition::~Condition()
    624 {
    625     WinCondition* condState = (WinCondition*) mState;
    626     if (condState != NULL) {
    627         CloseHandle(condState->sema);
    628         CloseHandle(condState->waitersDone);
    629         delete condState;
    630     }
    631 }
    632 
    633 
    634 status_t Condition::wait(Mutex& mutex)
    635 {
    636     WinCondition* condState = (WinCondition*) mState;
    637     HANDLE hMutex = (HANDLE) mutex.mState;
    638 
    639     return ((WinCondition*)mState)->wait(condState, hMutex, NULL);
    640 }
    641 
    642 status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
    643 {
    644     WinCondition* condState = (WinCondition*) mState;
    645     HANDLE hMutex = (HANDLE) mutex.mState;
    646     nsecs_t absTime = systemTime()+reltime;
    647 
    648     return ((WinCondition*)mState)->wait(condState, hMutex, &absTime);
    649 }
    650 
    651 /*
    652  * Signal the condition variable, allowing one thread to continue.
    653  */
    654 void Condition::signal()
    655 {
    656     WinCondition* condState = (WinCondition*) mState;
    657 
    658     // Lock the internal mutex.  This ensures that we don't clash with
    659     // broadcast().
    660     WaitForSingleObject(condState->internalMutex, INFINITE);
    661 
    662     EnterCriticalSection(&condState->waitersCountLock);
    663     bool haveWaiters = (condState->waitersCount > 0);
    664     LeaveCriticalSection(&condState->waitersCountLock);
    665 
    666     // If no waiters, then this is a no-op.  Otherwise, knock the semaphore
    667     // down a notch.
    668     if (haveWaiters)
    669         ReleaseSemaphore(condState->sema, 1, 0);
    670 
    671     // Release internal mutex.
    672     ReleaseMutex(condState->internalMutex);
    673 }
    674 
    675 /*
    676  * Signal the condition variable, allowing all threads to continue.
    677  *
    678  * First we have to wake up all threads waiting on the semaphore, then
    679  * we wait until all of the threads have actually been woken before
    680  * releasing the internal mutex.  This ensures that all threads are woken.
    681  */
    682 void Condition::broadcast()
    683 {
    684     WinCondition* condState = (WinCondition*) mState;
    685 
    686     // Lock the internal mutex.  This keeps the guys we're waking up
    687     // from getting too far.
    688     WaitForSingleObject(condState->internalMutex, INFINITE);
    689 
    690     EnterCriticalSection(&condState->waitersCountLock);
    691     bool haveWaiters = false;
    692 
    693     if (condState->waitersCount > 0) {
    694         haveWaiters = true;
    695         condState->wasBroadcast = true;
    696     }
    697 
    698     if (haveWaiters) {
    699         // Wake up all the waiters.
    700         ReleaseSemaphore(condState->sema, condState->waitersCount, 0);
    701 
    702         LeaveCriticalSection(&condState->waitersCountLock);
    703 
    704         // Wait for all awakened threads to acquire the counting semaphore.
    705         // The last guy who was waiting sets this.
    706         WaitForSingleObject(condState->waitersDone, INFINITE);
    707 
    708         // Reset wasBroadcast.  (No crit section needed because nobody
    709         // else can wake up to poke at it.)
    710         condState->wasBroadcast = 0;
    711     } else {
    712         // nothing to do
    713         LeaveCriticalSection(&condState->waitersCountLock);
    714     }
    715 
    716     // Release internal mutex.
    717     ReleaseMutex(condState->internalMutex);
    718 }
    719 
    720 #else
    721 #error "condition variables not supported on this platform"
    722 #endif
    723 
    724 // ----------------------------------------------------------------------------
    725 
    726 /*
    727  * This is our thread object!
    728  */
    729 
    730 Thread::Thread(bool canCallJava)
    731     :   mCanCallJava(canCallJava),
    732         mThread(thread_id_t(-1)),
    733         mLock("Thread::mLock"),
    734         mStatus(NO_ERROR),
    735         mExitPending(false), mRunning(false)
    736 #ifdef HAVE_ANDROID_OS
    737         , mTid(-1)
    738 #endif
    739 {
    740 }
    741 
    742 Thread::~Thread()
    743 {
    744 }
    745 
    746 status_t Thread::readyToRun()
    747 {
    748     return NO_ERROR;
    749 }
    750 
    751 status_t Thread::run(const char* name, int32_t priority, size_t stack)
    752 {
    753     Mutex::Autolock _l(mLock);
    754 
    755     if (mRunning) {
    756         // thread already started
    757         return INVALID_OPERATION;
    758     }
    759 
    760     // reset status and exitPending to their default value, so we can
    761     // try again after an error happened (either below, or in readyToRun())
    762     mStatus = NO_ERROR;
    763     mExitPending = false;
    764     mThread = thread_id_t(-1);
    765 
    766     // hold a strong reference on ourself
    767     mHoldSelf = this;
    768 
    769     mRunning = true;
    770 
    771     bool res;
    772     if (mCanCallJava) {
    773         res = createThreadEtc(_threadLoop,
    774                 this, name, priority, stack, &mThread);
    775     } else {
    776         res = androidCreateRawThreadEtc(_threadLoop,
    777                 this, name, priority, stack, &mThread);
    778     }
    779 
    780     if (res == false) {
    781         mStatus = UNKNOWN_ERROR;   // something happened!
    782         mRunning = false;
    783         mThread = thread_id_t(-1);
    784         mHoldSelf.clear();  // "this" may have gone away after this.
    785 
    786         return UNKNOWN_ERROR;
    787     }
    788 
    789     // Do not refer to mStatus here: The thread is already running (may, in fact
    790     // already have exited with a valid mStatus result). The NO_ERROR indication
    791     // here merely indicates successfully starting the thread and does not
    792     // imply successful termination/execution.
    793     return NO_ERROR;
    794 
    795     // Exiting scope of mLock is a memory barrier and allows new thread to run
    796 }
    797 
    798 int Thread::_threadLoop(void* user)
    799 {
    800     Thread* const self = static_cast<Thread*>(user);
    801 
    802     sp<Thread> strong(self->mHoldSelf);
    803     wp<Thread> weak(strong);
    804     self->mHoldSelf.clear();
    805 
    806 #ifdef HAVE_ANDROID_OS
    807     // this is very useful for debugging with gdb
    808     self->mTid = gettid();
    809 #endif
    810 
    811     bool first = true;
    812 
    813     do {
    814         bool result;
    815         if (first) {
    816             first = false;
    817             self->mStatus = self->readyToRun();
    818             result = (self->mStatus == NO_ERROR);
    819 
    820             if (result && !self->exitPending()) {
    821                 // Binder threads (and maybe others) rely on threadLoop
    822                 // running at least once after a successful ::readyToRun()
    823                 // (unless, of course, the thread has already been asked to exit
    824                 // at that point).
    825                 // This is because threads are essentially used like this:
    826                 //   (new ThreadSubclass())->run();
    827                 // The caller therefore does not retain a strong reference to
    828                 // the thread and the thread would simply disappear after the
    829                 // successful ::readyToRun() call instead of entering the
    830                 // threadLoop at least once.
    831                 result = self->threadLoop();
    832             }
    833         } else {
    834             result = self->threadLoop();
    835         }
    836 
    837         // establish a scope for mLock
    838         {
    839         Mutex::Autolock _l(self->mLock);
    840         if (result == false || self->mExitPending) {
    841             self->mExitPending = true;
    842             self->mRunning = false;
    843             // clear thread ID so that requestExitAndWait() does not exit if
    844             // called by a new thread using the same thread ID as this one.
    845             self->mThread = thread_id_t(-1);
    846             // note that interested observers blocked in requestExitAndWait are
    847             // awoken by broadcast, but blocked on mLock until break exits scope
    848             self->mThreadExitedCondition.broadcast();
    849             break;
    850         }
    851         }
    852 
    853         // Release our strong reference, to let a chance to the thread
    854         // to die a peaceful death.
    855         strong.clear();
    856         // And immediately, re-acquire a strong reference for the next loop
    857         strong = weak.promote();
    858     } while(strong != 0);
    859 
    860     return 0;
    861 }
    862 
    863 void Thread::requestExit()
    864 {
    865     Mutex::Autolock _l(mLock);
    866     mExitPending = true;
    867 }
    868 
    869 status_t Thread::requestExitAndWait()
    870 {
    871     Mutex::Autolock _l(mLock);
    872     if (mThread == getThreadId()) {
    873         LOGW(
    874         "Thread (this=%p): don't call waitForExit() from this "
    875         "Thread object's thread. It's a guaranteed deadlock!",
    876         this);
    877 
    878         return WOULD_BLOCK;
    879     }
    880 
    881     mExitPending = true;
    882 
    883     while (mRunning == true) {
    884         mThreadExitedCondition.wait(mLock);
    885     }
    886     // This next line is probably not needed any more, but is being left for
    887     // historical reference. Note that each interested party will clear flag.
    888     mExitPending = false;
    889 
    890     return mStatus;
    891 }
    892 
    893 status_t Thread::join()
    894 {
    895     Mutex::Autolock _l(mLock);
    896     if (mThread == getThreadId()) {
    897         LOGW(
    898         "Thread (this=%p): don't call join() from this "
    899         "Thread object's thread. It's a guaranteed deadlock!",
    900         this);
    901 
    902         return WOULD_BLOCK;
    903     }
    904 
    905     while (mRunning == true) {
    906         mThreadExitedCondition.wait(mLock);
    907     }
    908 
    909     return mStatus;
    910 }
    911 
    912 bool Thread::exitPending() const
    913 {
    914     Mutex::Autolock _l(mLock);
    915     return mExitPending;
    916 }
    917 
    918 
    919 
    920 };  // namespace android
    921