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