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