threads.h revision 9410f98e78622d962b3fb1c520af53d5351a65c5
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
24#if defined(HAVE_PTHREADS)
25# include <pthread.h>
26#endif
27
28// ------------------------------------------------------------------
29// C API
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35typedef void* android_thread_id_t;
36
37typedef int (*android_thread_func_t)(void*);
38
39enum {
40    /*
41     * ***********************************************
42     * ** Keep in sync with android.os.Process.java **
43     * ***********************************************
44     *
45     * This maps directly to the "nice" priorites we use in Android.
46     * A thread priority should be chosen inverse-proportinally to
47     * the amount of work the thread is expected to do. The more work
48     * a thread will do, the less favorable priority it should get so that
49     * it doesn't starve the system. Threads not behaving properly might
50     * be "punished" by the kernel.
51     * Use the levels below when appropriate. Intermediate values are
52     * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below.
53     */
54    ANDROID_PRIORITY_LOWEST         =  19,
55
56    /* use for background tasks */
57    ANDROID_PRIORITY_BACKGROUND     =  10,
58
59    /* most threads run at normal priority */
60    ANDROID_PRIORITY_NORMAL         =   0,
61
62    /* threads currently running a UI that the user is interacting with */
63    ANDROID_PRIORITY_FOREGROUND     =  -2,
64
65    /* the main UI thread has a slightly more favorable priority */
66    ANDROID_PRIORITY_DISPLAY        =  -4,
67
68    /* ui service treads might want to run at a urgent display (uncommon) */
69    ANDROID_PRIORITY_URGENT_DISPLAY =  -8,
70
71    /* all normal audio threads */
72    ANDROID_PRIORITY_AUDIO          = -16,
73
74    /* service audio threads (uncommon) */
75    ANDROID_PRIORITY_URGENT_AUDIO   = -19,
76
77    /* should never be used in practice. regular process might not
78     * be allowed to use this level */
79    ANDROID_PRIORITY_HIGHEST        = -20,
80
81    ANDROID_PRIORITY_DEFAULT        = ANDROID_PRIORITY_NORMAL,
82    ANDROID_PRIORITY_MORE_FAVORABLE = -1,
83    ANDROID_PRIORITY_LESS_FAVORABLE = +1,
84};
85
86enum {
87    ANDROID_TGROUP_DEFAULT          = 0,
88    ANDROID_TGROUP_BG_NONINTERACT   = 1,
89    ANDROID_TGROUP_FG_BOOST         = 2,
90    ANDROID_TGROUP_MAX              = ANDROID_TGROUP_FG_BOOST,
91};
92
93typedef enum {
94    SP_BACKGROUND = 0,
95    SP_FOREGROUND = 1,
96} SchedPolicy;
97
98// Create and run a new thread.
99extern int androidCreateThread(android_thread_func_t, void *);
100
101// Create thread with lots of parameters
102extern int androidCreateThreadEtc(android_thread_func_t entryFunction,
103                                  void *userData,
104                                  const char* threadName,
105                                  int32_t threadPriority,
106                                  size_t threadStackSize,
107                                  android_thread_id_t *threadId);
108
109// Get some sort of unique identifier for the current thread.
110extern android_thread_id_t androidGetThreadId();
111
112// Low-level thread creation -- never creates threads that can
113// interact with the Java VM.
114extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
115                                     void *userData,
116                                     const char* threadName,
117                                     int32_t threadPriority,
118                                     size_t threadStackSize,
119                                     android_thread_id_t *threadId);
120
121// Used by the Java Runtime to control how threads are created, so that
122// they can be proper and lovely Java threads.
123typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
124                                        void *userData,
125                                        const char* threadName,
126                                        int32_t threadPriority,
127                                        size_t threadStackSize,
128                                        android_thread_id_t *threadId);
129
130extern void androidSetCreateThreadFunc(android_create_thread_fn func);
131
132#ifdef __cplusplus
133}
134#endif
135
136// ------------------------------------------------------------------
137// C++ API
138
139#ifdef __cplusplus
140
141#include <utils/Errors.h>
142#include <utils/RefBase.h>
143#include <utils/Timers.h>
144
145namespace android {
146
147typedef android_thread_id_t thread_id_t;
148
149typedef android_thread_func_t thread_func_t;
150
151enum {
152    PRIORITY_LOWEST         = ANDROID_PRIORITY_LOWEST,
153    PRIORITY_BACKGROUND     = ANDROID_PRIORITY_BACKGROUND,
154    PRIORITY_NORMAL         = ANDROID_PRIORITY_NORMAL,
155    PRIORITY_FOREGROUND     = ANDROID_PRIORITY_FOREGROUND,
156    PRIORITY_DISPLAY        = ANDROID_PRIORITY_DISPLAY,
157    PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY,
158    PRIORITY_AUDIO          = ANDROID_PRIORITY_AUDIO,
159    PRIORITY_URGENT_AUDIO   = ANDROID_PRIORITY_URGENT_AUDIO,
160    PRIORITY_HIGHEST        = ANDROID_PRIORITY_HIGHEST,
161    PRIORITY_DEFAULT        = ANDROID_PRIORITY_DEFAULT,
162    PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE,
163    PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE,
164};
165
166// Create and run a new thread.
167inline bool createThread(thread_func_t f, void *a) {
168    return androidCreateThread(f, a) ? true : false;
169}
170
171// Create thread with lots of parameters
172inline bool createThreadEtc(thread_func_t entryFunction,
173                            void *userData,
174                            const char* threadName = "android:unnamed_thread",
175                            int32_t threadPriority = PRIORITY_DEFAULT,
176                            size_t threadStackSize = 0,
177                            thread_id_t *threadId = 0)
178{
179    return androidCreateThreadEtc(entryFunction, userData, threadName,
180        threadPriority, threadStackSize, threadId) ? true : false;
181}
182
183// Get some sort of unique identifier for the current thread.
184inline thread_id_t getThreadId() {
185    return androidGetThreadId();
186}
187
188/*****************************************************************************/
189
190/*
191 * Simple mutex class.  The implementation is system-dependent.
192 *
193 * The mutex must be unlocked by the thread that locked it.  They are not
194 * recursive, i.e. the same thread can't lock it multiple times.
195 */
196class Mutex {
197public:
198    enum {
199        NORMAL = 0,
200        SHARED = 1
201    };
202
203                Mutex();
204                Mutex(const char* name);
205                Mutex(int type, const char* name = NULL);
206                ~Mutex();
207
208    // lock or unlock the mutex
209    status_t    lock();
210    void        unlock();
211
212    // lock if possible; returns 0 on success, error otherwise
213    status_t    tryLock();
214
215    // Manages the mutex automatically. It'll be locked when Autolock is
216    // constructed and released when Autolock goes out of scope.
217    class Autolock {
218    public:
219        inline Autolock(Mutex& mutex) : mLock(mutex)  { mLock.lock(); }
220        inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
221        inline ~Autolock() { mLock.unlock(); }
222    private:
223        Mutex& mLock;
224    };
225
226private:
227    friend class Condition;
228
229    // A mutex cannot be copied
230                Mutex(const Mutex&);
231    Mutex&      operator = (const Mutex&);
232
233#if defined(HAVE_PTHREADS)
234    pthread_mutex_t mMutex;
235#else
236    void    _init();
237    void*   mState;
238#endif
239};
240
241#if defined(HAVE_PTHREADS)
242
243inline Mutex::Mutex() {
244    pthread_mutex_init(&mMutex, NULL);
245}
246inline Mutex::Mutex(const char* name) {
247    pthread_mutex_init(&mMutex, NULL);
248}
249inline Mutex::Mutex(int type, const char* name) {
250    if (type == SHARED) {
251        pthread_mutexattr_t attr;
252        pthread_mutexattr_init(&attr);
253        pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
254        pthread_mutex_init(&mMutex, &attr);
255        pthread_mutexattr_destroy(&attr);
256    } else {
257        pthread_mutex_init(&mMutex, NULL);
258    }
259}
260inline Mutex::~Mutex() {
261    pthread_mutex_destroy(&mMutex);
262}
263inline status_t Mutex::lock() {
264    return -pthread_mutex_lock(&mMutex);
265}
266inline void Mutex::unlock() {
267    pthread_mutex_unlock(&mMutex);
268}
269inline status_t Mutex::tryLock() {
270    return -pthread_mutex_trylock(&mMutex);
271}
272
273#endif // HAVE_PTHREADS
274
275/*
276 * Automatic mutex.  Declare one of these at the top of a function.
277 * When the function returns, it will go out of scope, and release the
278 * mutex.
279 */
280
281typedef Mutex::Autolock AutoMutex;
282
283/*****************************************************************************/
284
285/*
286 * Condition variable class.  The implementation is system-dependent.
287 *
288 * Condition variables are paired up with mutexes.  Lock the mutex,
289 * call wait(), then either re-wait() if things aren't quite what you want,
290 * or unlock the mutex and continue.  All threads calling wait() must
291 * use the same mutex for a given Condition.
292 */
293class Condition {
294public:
295    Condition();
296    ~Condition();
297    // Wait on the condition variable.  Lock the mutex before calling.
298    status_t wait(Mutex& mutex);
299    // same with relative timeout
300    status_t waitRelative(Mutex& mutex, nsecs_t reltime);
301    // Signal the condition variable, allowing one thread to continue.
302    void signal();
303    // Signal the condition variable, allowing all threads to continue.
304    void broadcast();
305
306private:
307#if defined(HAVE_PTHREADS)
308    pthread_cond_t mCond;
309#else
310    void*   mState;
311#endif
312};
313
314#if defined(HAVE_PTHREADS)
315
316inline Condition::Condition() {
317    pthread_cond_init(&mCond, NULL);
318}
319inline Condition::~Condition() {
320    pthread_cond_destroy(&mCond);
321}
322inline status_t Condition::wait(Mutex& mutex) {
323    return -pthread_cond_wait(&mCond, &mutex.mMutex);
324}
325inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
326#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
327    struct timespec ts;
328    ts.tv_sec  = reltime/1000000000;
329    ts.tv_nsec = reltime%1000000000;
330    return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
331#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
332    struct timespec ts;
333#if defined(HAVE_POSIX_CLOCKS)
334    clock_gettime(CLOCK_REALTIME, &ts);
335#else // HAVE_POSIX_CLOCKS
336    // we don't support the clocks here.
337    struct timeval t;
338    gettimeofday(&t, NULL);
339    ts.tv_sec = t.tv_sec;
340    ts.tv_nsec= t.tv_usec*1000;
341#endif // HAVE_POSIX_CLOCKS
342    ts.tv_sec += reltime/1000000000;
343    ts.tv_nsec+= reltime%1000000000;
344    if (ts.tv_nsec >= 1000000000) {
345        ts.tv_nsec -= 1000000000;
346        ts.tv_sec  += 1;
347    }
348    return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);
349#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
350}
351inline void Condition::signal() {
352    pthread_cond_signal(&mCond);
353}
354inline void Condition::broadcast() {
355    pthread_cond_broadcast(&mCond);
356}
357
358#endif // HAVE_PTHREADS
359
360/*****************************************************************************/
361
362/*
363 * This is our spiffy thread object!
364 */
365
366class Thread : virtual public RefBase
367{
368public:
369    // Create a Thread object, but doesn't create or start the associated
370    // thread. See the run() method.
371                        Thread(bool canCallJava = true);
372    virtual             ~Thread();
373
374    // Start the thread in threadLoop() which needs to be implemented.
375    virtual status_t    run(    const char* name = 0,
376                                int32_t priority = PRIORITY_DEFAULT,
377                                size_t stack = 0);
378
379    // Ask this object's thread to exit. This function is asynchronous, when the
380    // function returns the thread might still be running. Of course, this
381    // function can be called from a different thread.
382    virtual void        requestExit();
383
384    // Good place to do one-time initializations
385    virtual status_t    readyToRun();
386
387    // Call requestExit() and wait until this object's thread exits.
388    // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
389    // this function from this object's thread. Will return WOULD_BLOCK in
390    // that case.
391            status_t    requestExitAndWait();
392
393protected:
394    // exitPending() returns true if requestExit() has been called.
395            bool        exitPending() const;
396
397private:
398    // Derived class must implement threadLoop(). The thread starts its life
399    // here. There are two ways of using the Thread object:
400    // 1) loop: if threadLoop() returns true, it will be called again if
401    //          requestExit() wasn't called.
402    // 2) once: if threadLoop() returns false, the thread will exit upon return.
403    virtual bool        threadLoop() = 0;
404
405private:
406    Thread& operator=(const Thread&);
407    static  int             _threadLoop(void* user);
408    const   bool            mCanCallJava;
409            thread_id_t     mThread;
410            Mutex           mLock;
411            Condition       mThreadExitedCondition;
412            status_t        mStatus;
413    volatile bool           mExitPending;
414    volatile bool           mRunning;
415            sp<Thread>      mHoldSelf;
416#if HAVE_ANDROID_OS
417            int             mTid;
418#endif
419};
420
421
422}; // namespace android
423
424#endif  // __cplusplus
425
426#endif // _LIBS_UTILS_THREADS_H
427