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 #ifndef _LIBS_UTILS_THREADS_H
     18 #define _LIBS_UTILS_THREADS_H
     19 
     20 #include <stdint.h>
     21 #include <sys/types.h>
     22 #include <time.h>
     23 #include <system/graphics.h>
     24 
     25 #if defined(HAVE_PTHREADS)
     26 # include <pthread.h>
     27 #endif
     28 
     29 // ------------------------------------------------------------------
     30 // C API
     31 
     32 #ifdef __cplusplus
     33 extern "C" {
     34 #endif
     35 
     36 typedef void* android_thread_id_t;
     37 
     38 typedef int (*android_thread_func_t)(void*);
     39 
     40 enum {
     41     /*
     42      * ***********************************************
     43      * ** Keep in sync with android.os.Process.java **
     44      * ***********************************************
     45      *
     46      * This maps directly to the "nice" priorities we use in Android.
     47      * A thread priority should be chosen inverse-proportionally to
     48      * the amount of work the thread is expected to do. The more work
     49      * a thread will do, the less favorable priority it should get so that
     50      * it doesn't starve the system. Threads not behaving properly might
     51      * be "punished" by the kernel.
     52      * Use the levels below when appropriate. Intermediate values are
     53      * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below.
     54      */
     55     ANDROID_PRIORITY_LOWEST         =  19,
     56 
     57     /* use for background tasks */
     58     ANDROID_PRIORITY_BACKGROUND     =  10,
     59 
     60     /* most threads run at normal priority */
     61     ANDROID_PRIORITY_NORMAL         =   0,
     62 
     63     /* threads currently running a UI that the user is interacting with */
     64     ANDROID_PRIORITY_FOREGROUND     =  -2,
     65 
     66     /* the main UI thread has a slightly more favorable priority */
     67     ANDROID_PRIORITY_DISPLAY        =  -4,
     68 
     69     /* ui service treads might want to run at a urgent display (uncommon) */
     70     ANDROID_PRIORITY_URGENT_DISPLAY =  HAL_PRIORITY_URGENT_DISPLAY,
     71 
     72     /* all normal audio threads */
     73     ANDROID_PRIORITY_AUDIO          = -16,
     74 
     75     /* service audio threads (uncommon) */
     76     ANDROID_PRIORITY_URGENT_AUDIO   = -19,
     77 
     78     /* should never be used in practice. regular process might not
     79      * be allowed to use this level */
     80     ANDROID_PRIORITY_HIGHEST        = -20,
     81 
     82     ANDROID_PRIORITY_DEFAULT        = ANDROID_PRIORITY_NORMAL,
     83     ANDROID_PRIORITY_MORE_FAVORABLE = -1,
     84     ANDROID_PRIORITY_LESS_FAVORABLE = +1,
     85 };
     86 
     87 enum {
     88     ANDROID_TGROUP_DEFAULT          = 0,
     89     ANDROID_TGROUP_BG_NONINTERACT   = 1,
     90     ANDROID_TGROUP_FG_BOOST         = 2,
     91     ANDROID_TGROUP_MAX              = ANDROID_TGROUP_FG_BOOST,
     92 };
     93 
     94 // Create and run a new thread.
     95 extern int androidCreateThread(android_thread_func_t, void *);
     96 
     97 // Create thread with lots of parameters
     98 extern int androidCreateThreadEtc(android_thread_func_t entryFunction,
     99                                   void *userData,
    100                                   const char* threadName,
    101                                   int32_t threadPriority,
    102                                   size_t threadStackSize,
    103                                   android_thread_id_t *threadId);
    104 
    105 // Get some sort of unique identifier for the current thread.
    106 extern android_thread_id_t androidGetThreadId();
    107 
    108 // Low-level thread creation -- never creates threads that can
    109 // interact with the Java VM.
    110 extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
    111                                      void *userData,
    112                                      const char* threadName,
    113                                      int32_t threadPriority,
    114                                      size_t threadStackSize,
    115                                      android_thread_id_t *threadId);
    116 
    117 // Used by the Java Runtime to control how threads are created, so that
    118 // they can be proper and lovely Java threads.
    119 typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
    120                                         void *userData,
    121                                         const char* threadName,
    122                                         int32_t threadPriority,
    123                                         size_t threadStackSize,
    124                                         android_thread_id_t *threadId);
    125 
    126 extern void androidSetCreateThreadFunc(android_create_thread_fn func);
    127 
    128 // ------------------------------------------------------------------
    129 // Extra functions working with raw pids.
    130 
    131 // Get pid for the current thread.
    132 extern pid_t androidGetTid();
    133 
    134 // Change the scheduling group of a particular thread.  The group
    135 // should be one of the ANDROID_TGROUP constants.  Returns BAD_VALUE if
    136 // grp is out of range, else another non-zero value with errno set if
    137 // the operation failed.  Thread ID zero means current thread.
    138 extern int androidSetThreadSchedulingGroup(pid_t tid, int grp);
    139 
    140 // Change the priority AND scheduling group of a particular thread.  The priority
    141 // should be one of the ANDROID_PRIORITY constants.  Returns INVALID_OPERATION
    142 // if the priority set failed, else another value if just the group set failed;
    143 // in either case errno is set.  Thread ID zero means current thread.
    144 extern int androidSetThreadPriority(pid_t tid, int prio);
    145 
    146 // Get the current priority of a particular thread. Returns one of the
    147 // ANDROID_PRIORITY constants or a negative result in case of error.
    148 extern int androidGetThreadPriority(pid_t tid);
    149 
    150 // Get the current scheduling group of a particular thread. Normally returns
    151 // one of the ANDROID_TGROUP constants other than ANDROID_TGROUP_DEFAULT.
    152 // Returns ANDROID_TGROUP_DEFAULT if no pthread support (e.g. on host) or if
    153 // scheduling groups are disabled.  Returns INVALID_OPERATION if unexpected error.
    154 // Thread ID zero means current thread.
    155 extern int androidGetThreadSchedulingGroup(pid_t tid);
    156 
    157 #ifdef __cplusplus
    158 }
    159 #endif
    160 
    161 // ------------------------------------------------------------------
    162 // C++ API
    163 
    164 #ifdef __cplusplus
    165 
    166 #include <utils/Errors.h>
    167 #include <utils/RefBase.h>
    168 #include <utils/Timers.h>
    169 
    170 namespace android {
    171 
    172 typedef android_thread_id_t thread_id_t;
    173 
    174 typedef android_thread_func_t thread_func_t;
    175 
    176 enum {
    177     PRIORITY_LOWEST         = ANDROID_PRIORITY_LOWEST,
    178     PRIORITY_BACKGROUND     = ANDROID_PRIORITY_BACKGROUND,
    179     PRIORITY_NORMAL         = ANDROID_PRIORITY_NORMAL,
    180     PRIORITY_FOREGROUND     = ANDROID_PRIORITY_FOREGROUND,
    181     PRIORITY_DISPLAY        = ANDROID_PRIORITY_DISPLAY,
    182     PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY,
    183     PRIORITY_AUDIO          = ANDROID_PRIORITY_AUDIO,
    184     PRIORITY_URGENT_AUDIO   = ANDROID_PRIORITY_URGENT_AUDIO,
    185     PRIORITY_HIGHEST        = ANDROID_PRIORITY_HIGHEST,
    186     PRIORITY_DEFAULT        = ANDROID_PRIORITY_DEFAULT,
    187     PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE,
    188     PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE,
    189 };
    190 
    191 // Create and run a new thread.
    192 inline bool createThread(thread_func_t f, void *a) {
    193     return androidCreateThread(f, a) ? true : false;
    194 }
    195 
    196 // Create thread with lots of parameters
    197 inline bool createThreadEtc(thread_func_t entryFunction,
    198                             void *userData,
    199                             const char* threadName = "android:unnamed_thread",
    200                             int32_t threadPriority = PRIORITY_DEFAULT,
    201                             size_t threadStackSize = 0,
    202                             thread_id_t *threadId = 0)
    203 {
    204     return androidCreateThreadEtc(entryFunction, userData, threadName,
    205         threadPriority, threadStackSize, threadId) ? true : false;
    206 }
    207 
    208 // Get some sort of unique identifier for the current thread.
    209 inline thread_id_t getThreadId() {
    210     return androidGetThreadId();
    211 }
    212 
    213 /*****************************************************************************/
    214 
    215 /*
    216  * Simple mutex class.  The implementation is system-dependent.
    217  *
    218  * The mutex must be unlocked by the thread that locked it.  They are not
    219  * recursive, i.e. the same thread can't lock it multiple times.
    220  */
    221 class Mutex {
    222 public:
    223     enum {
    224         PRIVATE = 0,
    225         SHARED = 1
    226     };
    227 
    228                 Mutex();
    229                 Mutex(const char* name);
    230                 Mutex(int type, const char* name = NULL);
    231                 ~Mutex();
    232 
    233     // lock or unlock the mutex
    234     status_t    lock();
    235     void        unlock();
    236 
    237     // lock if possible; returns 0 on success, error otherwise
    238     status_t    tryLock();
    239 
    240     // Manages the mutex automatically. It'll be locked when Autolock is
    241     // constructed and released when Autolock goes out of scope.
    242     class Autolock {
    243     public:
    244         inline Autolock(Mutex& mutex) : mLock(mutex)  { mLock.lock(); }
    245         inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
    246         inline ~Autolock() { mLock.unlock(); }
    247     private:
    248         Mutex& mLock;
    249     };
    250 
    251 private:
    252     friend class Condition;
    253 
    254     // A mutex cannot be copied
    255                 Mutex(const Mutex&);
    256     Mutex&      operator = (const Mutex&);
    257 
    258 #if defined(HAVE_PTHREADS)
    259     pthread_mutex_t mMutex;
    260 #else
    261     void    _init();
    262     void*   mState;
    263 #endif
    264 };
    265 
    266 #if defined(HAVE_PTHREADS)
    267 
    268 inline Mutex::Mutex() {
    269     pthread_mutex_init(&mMutex, NULL);
    270 }
    271 inline Mutex::Mutex(const char* name) {
    272     pthread_mutex_init(&mMutex, NULL);
    273 }
    274 inline Mutex::Mutex(int type, const char* name) {
    275     if (type == SHARED) {
    276         pthread_mutexattr_t attr;
    277         pthread_mutexattr_init(&attr);
    278         pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    279         pthread_mutex_init(&mMutex, &attr);
    280         pthread_mutexattr_destroy(&attr);
    281     } else {
    282         pthread_mutex_init(&mMutex, NULL);
    283     }
    284 }
    285 inline Mutex::~Mutex() {
    286     pthread_mutex_destroy(&mMutex);
    287 }
    288 inline status_t Mutex::lock() {
    289     return -pthread_mutex_lock(&mMutex);
    290 }
    291 inline void Mutex::unlock() {
    292     pthread_mutex_unlock(&mMutex);
    293 }
    294 inline status_t Mutex::tryLock() {
    295     return -pthread_mutex_trylock(&mMutex);
    296 }
    297 
    298 #endif // HAVE_PTHREADS
    299 
    300 /*
    301  * Automatic mutex.  Declare one of these at the top of a function.
    302  * When the function returns, it will go out of scope, and release the
    303  * mutex.
    304  */
    305 
    306 typedef Mutex::Autolock AutoMutex;
    307 
    308 /*****************************************************************************/
    309 
    310 #if defined(HAVE_PTHREADS)
    311 
    312 /*
    313  * Simple mutex class.  The implementation is system-dependent.
    314  *
    315  * The mutex must be unlocked by the thread that locked it.  They are not
    316  * recursive, i.e. the same thread can't lock it multiple times.
    317  */
    318 class RWLock {
    319 public:
    320     enum {
    321         PRIVATE = 0,
    322         SHARED = 1
    323     };
    324 
    325                 RWLock();
    326                 RWLock(const char* name);
    327                 RWLock(int type, const char* name = NULL);
    328                 ~RWLock();
    329 
    330     status_t    readLock();
    331     status_t    tryReadLock();
    332     status_t    writeLock();
    333     status_t    tryWriteLock();
    334     void        unlock();
    335 
    336     class AutoRLock {
    337     public:
    338         inline AutoRLock(RWLock& rwlock) : mLock(rwlock)  { mLock.readLock(); }
    339         inline ~AutoRLock() { mLock.unlock(); }
    340     private:
    341         RWLock& mLock;
    342     };
    343 
    344     class AutoWLock {
    345     public:
    346         inline AutoWLock(RWLock& rwlock) : mLock(rwlock)  { mLock.writeLock(); }
    347         inline ~AutoWLock() { mLock.unlock(); }
    348     private:
    349         RWLock& mLock;
    350     };
    351 
    352 private:
    353     // A RWLock cannot be copied
    354                 RWLock(const RWLock&);
    355    RWLock&      operator = (const RWLock&);
    356 
    357    pthread_rwlock_t mRWLock;
    358 };
    359 
    360 inline RWLock::RWLock() {
    361     pthread_rwlock_init(&mRWLock, NULL);
    362 }
    363 inline RWLock::RWLock(const char* name) {
    364     pthread_rwlock_init(&mRWLock, NULL);
    365 }
    366 inline RWLock::RWLock(int type, const char* name) {
    367     if (type == SHARED) {
    368         pthread_rwlockattr_t attr;
    369         pthread_rwlockattr_init(&attr);
    370         pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    371         pthread_rwlock_init(&mRWLock, &attr);
    372         pthread_rwlockattr_destroy(&attr);
    373     } else {
    374         pthread_rwlock_init(&mRWLock, NULL);
    375     }
    376 }
    377 inline RWLock::~RWLock() {
    378     pthread_rwlock_destroy(&mRWLock);
    379 }
    380 inline status_t RWLock::readLock() {
    381     return -pthread_rwlock_rdlock(&mRWLock);
    382 }
    383 inline status_t RWLock::tryReadLock() {
    384     return -pthread_rwlock_tryrdlock(&mRWLock);
    385 }
    386 inline status_t RWLock::writeLock() {
    387     return -pthread_rwlock_wrlock(&mRWLock);
    388 }
    389 inline status_t RWLock::tryWriteLock() {
    390     return -pthread_rwlock_trywrlock(&mRWLock);
    391 }
    392 inline void RWLock::unlock() {
    393     pthread_rwlock_unlock(&mRWLock);
    394 }
    395 
    396 #endif // HAVE_PTHREADS
    397 
    398 /*****************************************************************************/
    399 
    400 /*
    401  * Condition variable class.  The implementation is system-dependent.
    402  *
    403  * Condition variables are paired up with mutexes.  Lock the mutex,
    404  * call wait(), then either re-wait() if things aren't quite what you want,
    405  * or unlock the mutex and continue.  All threads calling wait() must
    406  * use the same mutex for a given Condition.
    407  */
    408 class Condition {
    409 public:
    410     enum {
    411         PRIVATE = 0,
    412         SHARED = 1
    413     };
    414 
    415     Condition();
    416     Condition(int type);
    417     ~Condition();
    418     // Wait on the condition variable.  Lock the mutex before calling.
    419     status_t wait(Mutex& mutex);
    420     // same with relative timeout
    421     status_t waitRelative(Mutex& mutex, nsecs_t reltime);
    422     // Signal the condition variable, allowing one thread to continue.
    423     void signal();
    424     // Signal the condition variable, allowing all threads to continue.
    425     void broadcast();
    426 
    427 private:
    428 #if defined(HAVE_PTHREADS)
    429     pthread_cond_t mCond;
    430 #else
    431     void*   mState;
    432 #endif
    433 };
    434 
    435 #if defined(HAVE_PTHREADS)
    436 
    437 inline Condition::Condition() {
    438     pthread_cond_init(&mCond, NULL);
    439 }
    440 inline Condition::Condition(int type) {
    441     if (type == SHARED) {
    442         pthread_condattr_t attr;
    443         pthread_condattr_init(&attr);
    444         pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    445         pthread_cond_init(&mCond, &attr);
    446         pthread_condattr_destroy(&attr);
    447     } else {
    448         pthread_cond_init(&mCond, NULL);
    449     }
    450 }
    451 inline Condition::~Condition() {
    452     pthread_cond_destroy(&mCond);
    453 }
    454 inline status_t Condition::wait(Mutex& mutex) {
    455     return -pthread_cond_wait(&mCond, &mutex.mMutex);
    456 }
    457 inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
    458 #if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
    459     struct timespec ts;
    460     ts.tv_sec  = reltime/1000000000;
    461     ts.tv_nsec = reltime%1000000000;
    462     return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
    463 #else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
    464     struct timespec ts;
    465 #if defined(HAVE_POSIX_CLOCKS)
    466     clock_gettime(CLOCK_REALTIME, &ts);
    467 #else // HAVE_POSIX_CLOCKS
    468     // we don't support the clocks here.
    469     struct timeval t;
    470     gettimeofday(&t, NULL);
    471     ts.tv_sec = t.tv_sec;
    472     ts.tv_nsec= t.tv_usec*1000;
    473 #endif // HAVE_POSIX_CLOCKS
    474     ts.tv_sec += reltime/1000000000;
    475     ts.tv_nsec+= reltime%1000000000;
    476     if (ts.tv_nsec >= 1000000000) {
    477         ts.tv_nsec -= 1000000000;
    478         ts.tv_sec  += 1;
    479     }
    480     return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);
    481 #endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
    482 }
    483 inline void Condition::signal() {
    484     pthread_cond_signal(&mCond);
    485 }
    486 inline void Condition::broadcast() {
    487     pthread_cond_broadcast(&mCond);
    488 }
    489 
    490 #endif // HAVE_PTHREADS
    491 
    492 /*****************************************************************************/
    493 
    494 /*
    495  * This is our spiffy thread object!
    496  */
    497 
    498 class Thread : virtual public RefBase
    499 {
    500 public:
    501     // Create a Thread object, but doesn't create or start the associated
    502     // thread. See the run() method.
    503                         Thread(bool canCallJava = true);
    504     virtual             ~Thread();
    505 
    506     // Start the thread in threadLoop() which needs to be implemented.
    507     virtual status_t    run(    const char* name = 0,
    508                                 int32_t priority = PRIORITY_DEFAULT,
    509                                 size_t stack = 0);
    510 
    511     // Ask this object's thread to exit. This function is asynchronous, when the
    512     // function returns the thread might still be running. Of course, this
    513     // function can be called from a different thread.
    514     virtual void        requestExit();
    515 
    516     // Good place to do one-time initializations
    517     virtual status_t    readyToRun();
    518 
    519     // Call requestExit() and wait until this object's thread exits.
    520     // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
    521     // this function from this object's thread. Will return WOULD_BLOCK in
    522     // that case.
    523             status_t    requestExitAndWait();
    524 
    525     // Wait until this object's thread exits. Returns immediately if not yet running.
    526     // Do not call from this object's thread; will return WOULD_BLOCK in that case.
    527             status_t    join();
    528 
    529 protected:
    530     // exitPending() returns true if requestExit() has been called.
    531             bool        exitPending() const;
    532 
    533 private:
    534     // Derived class must implement threadLoop(). The thread starts its life
    535     // here. There are two ways of using the Thread object:
    536     // 1) loop: if threadLoop() returns true, it will be called again if
    537     //          requestExit() wasn't called.
    538     // 2) once: if threadLoop() returns false, the thread will exit upon return.
    539     virtual bool        threadLoop() = 0;
    540 
    541 private:
    542     Thread& operator=(const Thread&);
    543     static  int             _threadLoop(void* user);
    544     const   bool            mCanCallJava;
    545     // always hold mLock when reading or writing
    546             thread_id_t     mThread;
    547     mutable Mutex           mLock;
    548             Condition       mThreadExitedCondition;
    549             status_t        mStatus;
    550     // note that all accesses of mExitPending and mRunning need to hold mLock
    551     volatile bool           mExitPending;
    552     volatile bool           mRunning;
    553             sp<Thread>      mHoldSelf;
    554 #if HAVE_ANDROID_OS
    555             int             mTid;
    556 #endif
    557 };
    558 
    559 
    560 }; // namespace android
    561 
    562 #endif  // __cplusplus
    563 
    564 #endif // _LIBS_UTILS_THREADS_H
    565