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. 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. 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: 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 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 268 inline Mutex::Mutex() { 269 pthread_mutex_init(&mMutex, NULL); 270 } 271 inline Mutex::Mutex(const char* name) { 272 pthread_mutex_init(&mMutex, NULL); 273 } 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 } 285 inline Mutex::~Mutex() { 286 pthread_mutex_destroy(&mMutex); 287 } 288 inline status_t Mutex::lock() { 289 return -pthread_mutex_lock(&mMutex); 290 } 291 inline void Mutex::unlock() { 292 pthread_mutex_unlock(&mMutex); 293 } 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: 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 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 360 inline RWLock::RWLock() { 361 pthread_rwlock_init(&mRWLock, NULL); 362 } 363 inline RWLock::RWLock(const char* name) { 364 pthread_rwlock_init(&mRWLock, NULL); 365 } 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 } 377 inline RWLock::~RWLock() { 378 pthread_rwlock_destroy(&mRWLock); 379 } 380 inline status_t RWLock::readLock() { 381 return -pthread_rwlock_rdlock(&mRWLock); 382 } 383 inline status_t RWLock::tryReadLock() { 384 return -pthread_rwlock_tryrdlock(&mRWLock); 385 } 386 inline status_t RWLock::writeLock() { 387 return -pthread_rwlock_wrlock(&mRWLock); 388 } 389 inline status_t RWLock::tryWriteLock() { 390 return -pthread_rwlock_trywrlock(&mRWLock); 391 } 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 437 inline Condition::Condition() { 438 pthread_cond_init(&mCond, NULL); 439 } 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 } 451 inline Condition::~Condition() { 452 pthread_cond_destroy(&mCond); 453 } 454 inline status_t Condition::wait(Mutex& mutex) { 455 return -pthread_cond_wait(&mCond, &mutex.mMutex); 456 } 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 } 483 inline void Condition::signal() { 484 pthread_cond_signal(&mCond); 485 } 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