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