threads.h revision d731f07cc9ca7e8fc327c7910de7bea7e22c2fd3
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
33extern "C" {
34#endif
35
36typedef void* android_thread_id_t;
37
38typedef int (*android_thread_func_t)(void*);
39
40enum {
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
87enum {
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.
95extern int androidCreateThread(android_thread_func_t, void *);
96
97// Create thread with lots of parameters
98extern 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.
106extern android_thread_id_t androidGetThreadId();
107
108// Low-level thread creation -- never creates threads that can
109// interact with the Java VM.
110extern 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.
119typedef 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
126extern void androidSetCreateThreadFunc(android_create_thread_fn func);
127
128// ------------------------------------------------------------------
129// Extra functions working with raw pids.
130
131// Get pid for the current thread.
132extern 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.
138extern 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.
144extern 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.
148extern 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.
155extern 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
170namespace android {
171
172typedef android_thread_id_t thread_id_t;
173
174typedef android_thread_func_t thread_func_t;
175
176enum {
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.
192inline bool createThread(thread_func_t f, void *a) {
193    return androidCreateThread(f, a) ? true : false;
194}
195
196// Create thread with lots of parameters
197inline 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.
209inline 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 */
221class Mutex {
222public:
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
251private:
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
268inline Mutex::Mutex() {
269    pthread_mutex_init(&mMutex, NULL);
270}
271inline Mutex::Mutex(const char* name) {
272    pthread_mutex_init(&mMutex, NULL);
273}
274inline 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}
285inline Mutex::~Mutex() {
286    pthread_mutex_destroy(&mMutex);
287}
288inline status_t Mutex::lock() {
289    return -pthread_mutex_lock(&mMutex);
290}
291inline void Mutex::unlock() {
292    pthread_mutex_unlock(&mMutex);
293}
294inline 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
306typedef 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 */
318class RWLock {
319public:
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
352private:
353    // A RWLock cannot be copied
354                RWLock(const RWLock&);
355   RWLock&      operator = (const RWLock&);
356
357   pthread_rwlock_t mRWLock;
358};
359
360inline RWLock::RWLock() {
361    pthread_rwlock_init(&mRWLock, NULL);
362}
363inline RWLock::RWLock(const char* name) {
364    pthread_rwlock_init(&mRWLock, NULL);
365}
366inline 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}
377inline RWLock::~RWLock() {
378    pthread_rwlock_destroy(&mRWLock);
379}
380inline status_t RWLock::readLock() {
381    return -pthread_rwlock_rdlock(&mRWLock);
382}
383inline status_t RWLock::tryReadLock() {
384    return -pthread_rwlock_tryrdlock(&mRWLock);
385}
386inline status_t RWLock::writeLock() {
387    return -pthread_rwlock_wrlock(&mRWLock);
388}
389inline status_t RWLock::tryWriteLock() {
390    return -pthread_rwlock_trywrlock(&mRWLock);
391}
392inline 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 */
408class Condition {
409public:
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
427private:
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
437inline Condition::Condition() {
438    pthread_cond_init(&mCond, NULL);
439}
440inline 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}
451inline Condition::~Condition() {
452    pthread_cond_destroy(&mCond);
453}
454inline status_t Condition::wait(Mutex& mutex) {
455    return -pthread_cond_wait(&mCond, &mutex.mMutex);
456}
457inline 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}
483inline void Condition::signal() {
484    pthread_cond_signal(&mCond);
485}
486inline 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
498class Thread : virtual public RefBase
499{
500public:
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#ifdef HAVE_ANDROID_OS
530    // Return the thread's kernel ID, same as the thread itself calling gettid() or
531    // androidGetTid(), or -1 if the thread is not running.
532            pid_t       getTid() const;
533#endif
534
535protected:
536    // exitPending() returns true if requestExit() has been called.
537            bool        exitPending() const;
538
539private:
540    // Derived class must implement threadLoop(). The thread starts its life
541    // here. There are two ways of using the Thread object:
542    // 1) loop: if threadLoop() returns true, it will be called again if
543    //          requestExit() wasn't called.
544    // 2) once: if threadLoop() returns false, the thread will exit upon return.
545    virtual bool        threadLoop() = 0;
546
547private:
548    Thread& operator=(const Thread&);
549    static  int             _threadLoop(void* user);
550    const   bool            mCanCallJava;
551    // always hold mLock when reading or writing
552            thread_id_t     mThread;
553    mutable Mutex           mLock;
554            Condition       mThreadExitedCondition;
555            status_t        mStatus;
556    // note that all accesses of mExitPending and mRunning need to hold mLock
557    volatile bool           mExitPending;
558    volatile bool           mRunning;
559            sp<Thread>      mHoldSelf;
560#ifdef HAVE_ANDROID_OS
561    // legacy for debugging, not used by getTid() as it is set by the child thread
562    // and so is not initialized until the child reaches that point
563            pid_t           mTid;
564#endif
565};
566
567
568}; // namespace android
569
570#endif  // __cplusplus
571
572#endif // _LIBS_UTILS_THREADS_H
573