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.
createThread(thread_func_t f,void * a)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.
getThreadId()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:
Autolock(Mutex & mutex)244 inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
Autolock(Mutex * mutex)245 inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
~Autolock()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
Mutex()268 inline Mutex::Mutex() {
269 pthread_mutex_init(&mMutex, NULL);
270 }
Mutex(const char * name)271 inline Mutex::Mutex(const char* name) {
272 pthread_mutex_init(&mMutex, NULL);
273 }
Mutex(int type,const char * name)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 }
~Mutex()285 inline Mutex::~Mutex() {
286 pthread_mutex_destroy(&mMutex);
287 }
lock()288 inline status_t Mutex::lock() {
289 return -pthread_mutex_lock(&mMutex);
290 }
unlock()291 inline void Mutex::unlock() {
292 pthread_mutex_unlock(&mMutex);
293 }
tryLock()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:
AutoRLock(RWLock & rwlock)338 inline AutoRLock(RWLock& rwlock) : mLock(rwlock) { mLock.readLock(); }
~AutoRLock()339 inline ~AutoRLock() { mLock.unlock(); }
340 private:
341 RWLock& mLock;
342 };
343
344 class AutoWLock {
345 public:
AutoWLock(RWLock & rwlock)346 inline AutoWLock(RWLock& rwlock) : mLock(rwlock) { mLock.writeLock(); }
~AutoWLock()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
RWLock()360 inline RWLock::RWLock() {
361 pthread_rwlock_init(&mRWLock, NULL);
362 }
RWLock(const char * name)363 inline RWLock::RWLock(const char* name) {
364 pthread_rwlock_init(&mRWLock, NULL);
365 }
RWLock(int type,const char * name)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 }
~RWLock()377 inline RWLock::~RWLock() {
378 pthread_rwlock_destroy(&mRWLock);
379 }
readLock()380 inline status_t RWLock::readLock() {
381 return -pthread_rwlock_rdlock(&mRWLock);
382 }
tryReadLock()383 inline status_t RWLock::tryReadLock() {
384 return -pthread_rwlock_tryrdlock(&mRWLock);
385 }
writeLock()386 inline status_t RWLock::writeLock() {
387 return -pthread_rwlock_wrlock(&mRWLock);
388 }
tryWriteLock()389 inline status_t RWLock::tryWriteLock() {
390 return -pthread_rwlock_trywrlock(&mRWLock);
391 }
unlock()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
Condition()437 inline Condition::Condition() {
438 pthread_cond_init(&mCond, NULL);
439 }
Condition(int type)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 }
~Condition()451 inline Condition::~Condition() {
452 pthread_cond_destroy(&mCond);
453 }
wait(Mutex & mutex)454 inline status_t Condition::wait(Mutex& mutex) {
455 return -pthread_cond_wait(&mCond, &mutex.mMutex);
456 }
waitRelative(Mutex & mutex,nsecs_t reltime)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 }
signal()483 inline void Condition::signal() {
484 pthread_cond_signal(&mCond);
485 }
broadcast()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