• 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 #ifdef __cplusplus
128 }
129 #endif
130 
131 // ------------------------------------------------------------------
132 // C++ API
133 
134 #ifdef __cplusplus
135 
136 #include <utils/Errors.h>
137 #include <utils/RefBase.h>
138 #include <utils/Timers.h>
139 
140 namespace android {
141 
142 typedef android_thread_id_t thread_id_t;
143 
144 typedef android_thread_func_t thread_func_t;
145 
146 enum {
147     PRIORITY_LOWEST         = ANDROID_PRIORITY_LOWEST,
148     PRIORITY_BACKGROUND     = ANDROID_PRIORITY_BACKGROUND,
149     PRIORITY_NORMAL         = ANDROID_PRIORITY_NORMAL,
150     PRIORITY_FOREGROUND     = ANDROID_PRIORITY_FOREGROUND,
151     PRIORITY_DISPLAY        = ANDROID_PRIORITY_DISPLAY,
152     PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY,
153     PRIORITY_AUDIO          = ANDROID_PRIORITY_AUDIO,
154     PRIORITY_URGENT_AUDIO   = ANDROID_PRIORITY_URGENT_AUDIO,
155     PRIORITY_HIGHEST        = ANDROID_PRIORITY_HIGHEST,
156     PRIORITY_DEFAULT        = ANDROID_PRIORITY_DEFAULT,
157     PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE,
158     PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE,
159 };
160 
161 // Create and run a new thread.
createThread(thread_func_t f,void * a)162 inline bool createThread(thread_func_t f, void *a) {
163     return androidCreateThread(f, a) ? true : false;
164 }
165 
166 // Create thread with lots of parameters
167 inline bool createThreadEtc(thread_func_t entryFunction,
168                             void *userData,
169                             const char* threadName = "android:unnamed_thread",
170                             int32_t threadPriority = PRIORITY_DEFAULT,
171                             size_t threadStackSize = 0,
172                             thread_id_t *threadId = 0)
173 {
174     return androidCreateThreadEtc(entryFunction, userData, threadName,
175         threadPriority, threadStackSize, threadId) ? true : false;
176 }
177 
178 // Get some sort of unique identifier for the current thread.
getThreadId()179 inline thread_id_t getThreadId() {
180     return androidGetThreadId();
181 }
182 
183 /*****************************************************************************/
184 
185 /*
186  * Simple mutex class.  The implementation is system-dependent.
187  *
188  * The mutex must be unlocked by the thread that locked it.  They are not
189  * recursive, i.e. the same thread can't lock it multiple times.
190  */
191 class Mutex {
192 public:
193     enum {
194         NORMAL = 0,
195         SHARED = 1
196     };
197 
198                 Mutex();
199                 Mutex(const char* name);
200                 Mutex(int type, const char* name = NULL);
201                 ~Mutex();
202 
203     // lock or unlock the mutex
204     status_t    lock();
205     void        unlock();
206 
207     // lock if possible; returns 0 on success, error otherwise
208     status_t    tryLock();
209 
210     // Manages the mutex automatically. It'll be locked when Autolock is
211     // constructed and released when Autolock goes out of scope.
212     class Autolock {
213     public:
Autolock(Mutex & mutex)214         inline Autolock(Mutex& mutex) : mLock(mutex)  { mLock.lock(); }
Autolock(Mutex * mutex)215         inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
~Autolock()216         inline ~Autolock() { mLock.unlock(); }
217     private:
218         Mutex& mLock;
219     };
220 
221 private:
222     friend class Condition;
223 
224     // A mutex cannot be copied
225                 Mutex(const Mutex&);
226     Mutex&      operator = (const Mutex&);
227 
228 #if defined(HAVE_PTHREADS)
229     pthread_mutex_t mMutex;
230 #else
231     void    _init();
232     void*   mState;
233 #endif
234 };
235 
236 #if defined(HAVE_PTHREADS)
237 
Mutex()238 inline Mutex::Mutex() {
239     pthread_mutex_init(&mMutex, NULL);
240 }
Mutex(const char * name)241 inline Mutex::Mutex(const char* name) {
242     pthread_mutex_init(&mMutex, NULL);
243 }
Mutex(int type,const char * name)244 inline Mutex::Mutex(int type, const char* name) {
245     if (type == SHARED) {
246         pthread_mutexattr_t attr;
247         pthread_mutexattr_init(&attr);
248         pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
249         pthread_mutex_init(&mMutex, &attr);
250         pthread_mutexattr_destroy(&attr);
251     } else {
252         pthread_mutex_init(&mMutex, NULL);
253     }
254 }
~Mutex()255 inline Mutex::~Mutex() {
256     pthread_mutex_destroy(&mMutex);
257 }
lock()258 inline status_t Mutex::lock() {
259     return -pthread_mutex_lock(&mMutex);
260 }
unlock()261 inline void Mutex::unlock() {
262     pthread_mutex_unlock(&mMutex);
263 }
tryLock()264 inline status_t Mutex::tryLock() {
265     return -pthread_mutex_trylock(&mMutex);
266 }
267 
268 #endif // HAVE_PTHREADS
269 
270 /*
271  * Automatic mutex.  Declare one of these at the top of a function.
272  * When the function returns, it will go out of scope, and release the
273  * mutex.
274  */
275 
276 typedef Mutex::Autolock AutoMutex;
277 
278 /*****************************************************************************/
279 
280 /*
281  * Condition variable class.  The implementation is system-dependent.
282  *
283  * Condition variables are paired up with mutexes.  Lock the mutex,
284  * call wait(), then either re-wait() if things aren't quite what you want,
285  * or unlock the mutex and continue.  All threads calling wait() must
286  * use the same mutex for a given Condition.
287  */
288 class Condition {
289 public:
290     Condition();
291     ~Condition();
292     // Wait on the condition variable.  Lock the mutex before calling.
293     status_t wait(Mutex& mutex);
294     // same with relative timeout
295     status_t waitRelative(Mutex& mutex, nsecs_t reltime);
296     // Signal the condition variable, allowing one thread to continue.
297     void signal();
298     // Signal the condition variable, allowing all threads to continue.
299     void broadcast();
300 
301 private:
302 #if defined(HAVE_PTHREADS)
303     pthread_cond_t mCond;
304 #else
305     void*   mState;
306 #endif
307 };
308 
309 #if defined(HAVE_PTHREADS)
310 
Condition()311 inline Condition::Condition() {
312     pthread_cond_init(&mCond, NULL);
313 }
~Condition()314 inline Condition::~Condition() {
315     pthread_cond_destroy(&mCond);
316 }
wait(Mutex & mutex)317 inline status_t Condition::wait(Mutex& mutex) {
318     return -pthread_cond_wait(&mCond, &mutex.mMutex);
319 }
waitRelative(Mutex & mutex,nsecs_t reltime)320 inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
321 #if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
322     struct timespec ts;
323     ts.tv_sec  = reltime/1000000000;
324     ts.tv_nsec = reltime%1000000000;
325     return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
326 #else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
327     struct timespec ts;
328 #if defined(HAVE_POSIX_CLOCKS)
329     clock_gettime(CLOCK_REALTIME, &ts);
330 #else // HAVE_POSIX_CLOCKS
331     // we don't support the clocks here.
332     struct timeval t;
333     gettimeofday(&t, NULL);
334     ts.tv_sec = t.tv_sec;
335     ts.tv_nsec= t.tv_usec*1000;
336 #endif // HAVE_POSIX_CLOCKS
337     ts.tv_sec += reltime/1000000000;
338     ts.tv_nsec+= reltime%1000000000;
339     if (ts.tv_nsec >= 1000000000) {
340         ts.tv_nsec -= 1000000000;
341         ts.tv_sec  += 1;
342     }
343     return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);
344 #endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
345 }
signal()346 inline void Condition::signal() {
347     pthread_cond_signal(&mCond);
348 }
broadcast()349 inline void Condition::broadcast() {
350     pthread_cond_broadcast(&mCond);
351 }
352 
353 #endif // HAVE_PTHREADS
354 
355 /*****************************************************************************/
356 
357 /*
358  * This is our spiffy thread object!
359  */
360 
361 class Thread : virtual public RefBase
362 {
363 public:
364     // Create a Thread object, but doesn't create or start the associated
365     // thread. See the run() method.
366                         Thread(bool canCallJava = true);
367     virtual             ~Thread();
368 
369     // Start the thread in threadLoop() which needs to be implemented.
370     virtual status_t    run(    const char* name = 0,
371                                 int32_t priority = PRIORITY_DEFAULT,
372                                 size_t stack = 0);
373 
374     // Ask this object's thread to exit. This function is asynchronous, when the
375     // function returns the thread might still be running. Of course, this
376     // function can be called from a different thread.
377     virtual void        requestExit();
378 
379     // Good place to do one-time initializations
380     virtual status_t    readyToRun();
381 
382     // Call requestExit() and wait until this object's thread exits.
383     // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
384     // this function from this object's thread. Will return WOULD_BLOCK in
385     // that case.
386             status_t    requestExitAndWait();
387 
388 protected:
389     // exitPending() returns true if requestExit() has been called.
390             bool        exitPending() const;
391 
392 private:
393     // Derived class must implement threadLoop(). The thread starts its life
394     // here. There are two ways of using the Thread object:
395     // 1) loop: if threadLoop() returns true, it will be called again if
396     //          requestExit() wasn't called.
397     // 2) once: if threadLoop() returns false, the thread will exit upon return.
398     virtual bool        threadLoop() = 0;
399 
400 private:
401     Thread& operator=(const Thread&);
402     static  int             _threadLoop(void* user);
403     const   bool            mCanCallJava;
404             thread_id_t     mThread;
405             Mutex           mLock;
406             Condition       mThreadExitedCondition;
407             status_t        mStatus;
408     volatile bool           mExitPending;
409     volatile bool           mRunning;
410             sp<Thread>      mHoldSelf;
411 #if HAVE_ANDROID_OS
412             int             mTid;
413 #endif
414 };
415 
416 
417 }; // namespace android
418 
419 #endif  // __cplusplus
420 
421 #endif // _LIBS_UTILS_THREADS_H
422