threads.h revision cbb1011c95e0c25c29e40e203a6a31bccd029da3
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// ------------------------------------------------------------------ 25// C API 26 27#ifdef __cplusplus 28extern "C" { 29#endif 30 31typedef void* android_thread_id_t; 32 33typedef int (*android_thread_func_t)(void*); 34 35enum { 36 /* 37 * *********************************************** 38 * ** Keep in sync with android.os.Process.java ** 39 * *********************************************** 40 * 41 * This maps directly to the "nice" priorites we use in Android. 42 * A thread priority should be chosen inverse-proportinally to 43 * the amount of work the thread is expected to do. The more work 44 * a thread will do, the less favorable priority it should get so that 45 * it doesn't starve the system. Threads not behaving properly might 46 * be "punished" by the kernel. 47 * Use the levels below when appropriate. Intermediate values are 48 * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below. 49 */ 50 ANDROID_PRIORITY_LOWEST = 19, 51 52 /* use for background tasks */ 53 ANDROID_PRIORITY_BACKGROUND = 10, 54 55 /* most threads run at normal priority */ 56 ANDROID_PRIORITY_NORMAL = 0, 57 58 /* threads currently running a UI that the user is interacting with */ 59 ANDROID_PRIORITY_FOREGROUND = -2, 60 61 /* the main UI thread has a slightly more favorable priority */ 62 ANDROID_PRIORITY_DISPLAY = -4, 63 64 /* ui service treads might want to run at a urgent display (uncommon) */ 65 ANDROID_PRIORITY_URGENT_DISPLAY = -8, 66 67 /* all normal audio threads */ 68 ANDROID_PRIORITY_AUDIO = -16, 69 70 /* service audio threads (uncommon) */ 71 ANDROID_PRIORITY_URGENT_AUDIO = -19, 72 73 /* should never be used in practice. regular process might not 74 * be allowed to use this level */ 75 ANDROID_PRIORITY_HIGHEST = -20, 76 77 ANDROID_PRIORITY_DEFAULT = ANDROID_PRIORITY_NORMAL, 78 ANDROID_PRIORITY_MORE_FAVORABLE = -1, 79 ANDROID_PRIORITY_LESS_FAVORABLE = +1, 80}; 81 82// Create and run a new thread. 83extern int androidCreateThread(android_thread_func_t, void *); 84 85// Create thread with lots of parameters 86extern int androidCreateThreadEtc(android_thread_func_t entryFunction, 87 void *userData, 88 const char* threadName, 89 int32_t threadPriority, 90 size_t threadStackSize, 91 android_thread_id_t *threadId); 92 93// Get some sort of unique identifier for the current thread. 94extern android_thread_id_t androidGetThreadId(); 95 96// Low-level thread creation -- never creates threads that can 97// interact with the Java VM. 98extern int androidCreateRawThreadEtc(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// Used by the Java Runtime to control how threads are created, so that 106// they can be proper and lovely Java threads. 107typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction, 108 void *userData, 109 const char* threadName, 110 int32_t threadPriority, 111 size_t threadStackSize, 112 android_thread_id_t *threadId); 113 114extern void androidSetCreateThreadFunc(android_create_thread_fn func); 115 116#ifdef __cplusplus 117} 118#endif 119 120// ------------------------------------------------------------------ 121// C++ API 122 123#ifdef __cplusplus 124 125#include <utils/Errors.h> 126#include <utils/RefBase.h> 127#include <utils/Timers.h> 128 129namespace android { 130 131typedef android_thread_id_t thread_id_t; 132 133typedef android_thread_func_t thread_func_t; 134 135enum { 136 PRIORITY_LOWEST = ANDROID_PRIORITY_LOWEST, 137 PRIORITY_BACKGROUND = ANDROID_PRIORITY_BACKGROUND, 138 PRIORITY_NORMAL = ANDROID_PRIORITY_NORMAL, 139 PRIORITY_FOREGROUND = ANDROID_PRIORITY_FOREGROUND, 140 PRIORITY_DISPLAY = ANDROID_PRIORITY_DISPLAY, 141 PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY, 142 PRIORITY_AUDIO = ANDROID_PRIORITY_AUDIO, 143 PRIORITY_URGENT_AUDIO = ANDROID_PRIORITY_URGENT_AUDIO, 144 PRIORITY_HIGHEST = ANDROID_PRIORITY_HIGHEST, 145 PRIORITY_DEFAULT = ANDROID_PRIORITY_DEFAULT, 146 PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE, 147 PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE, 148}; 149 150// Create and run a new thread. 151inline bool createThread(thread_func_t f, void *a) { 152 return androidCreateThread(f, a) ? true : false; 153} 154 155// Create thread with lots of parameters 156inline bool createThreadEtc(thread_func_t entryFunction, 157 void *userData, 158 const char* threadName = "android:unnamed_thread", 159 int32_t threadPriority = PRIORITY_DEFAULT, 160 size_t threadStackSize = 0, 161 thread_id_t *threadId = 0) 162{ 163 return androidCreateThreadEtc(entryFunction, userData, threadName, 164 threadPriority, threadStackSize, threadId) ? true : false; 165} 166 167// Get some sort of unique identifier for the current thread. 168inline thread_id_t getThreadId() { 169 return androidGetThreadId(); 170} 171 172/* 173 * Simple mutex class. The implementation is system-dependent. 174 * 175 * The mutex must be unlocked by the thread that locked it. They are not 176 * recursive, i.e. the same thread can't lock it multiple times. 177 */ 178class Mutex { 179public: 180 Mutex(); 181 Mutex(const char* name); 182 ~Mutex(); 183 184 // lock or unlock the mutex 185 status_t lock(); 186 void unlock(); 187 188 // lock if possible; returns 0 on success, error otherwise 189 status_t tryLock(); 190 191 // Manages the mutex automatically. It'll be locked when Autolock is 192 // constructed and released when Autolock goes out of scope. 193 class Autolock { 194 public: 195 inline Autolock(Mutex& mutex) : mpMutex(&mutex) { mutex.lock(); } 196 inline Autolock(Mutex* mutex) : mpMutex(mutex) { mutex->lock(); } 197 inline ~Autolock() { mpMutex->unlock(); } 198 private: 199 Mutex* mpMutex; 200 }; 201 202private: 203 friend class Condition; 204 205 // A mutex cannot be copied 206 Mutex(const Mutex&); 207 Mutex& operator = (const Mutex&); 208 void _init(); 209 210 void* mState; 211}; 212 213/* 214 * Automatic mutex. Declare one of these at the top of a function. 215 * When the function returns, it will go out of scope, and release the 216 * mutex. 217 */ 218 219typedef Mutex::Autolock AutoMutex; 220 221 222/* 223 * Condition variable class. The implementation is system-dependent. 224 * 225 * Condition variables are paired up with mutexes. Lock the mutex, 226 * call wait(), then either re-wait() if things aren't quite what you want, 227 * or unlock the mutex and continue. All threads calling wait() must 228 * use the same mutex for a given Condition. 229 */ 230class Condition { 231public: 232 Condition(); 233 ~Condition(); 234 // Wait on the condition variable. Lock the mutex before calling. 235 status_t wait(Mutex& mutex); 236 // Wait on the condition variable until the given time. Lock the mutex 237 // before calling. 238 status_t wait(Mutex& mutex, nsecs_t abstime); 239 // same with relative timeout 240 status_t waitRelative(Mutex& mutex, nsecs_t reltime); 241 // Signal the condition variable, allowing one thread to continue. 242 void signal(); 243 // Signal the condition variable, allowing all threads to continue. 244 void broadcast(); 245 246private: 247 void* mState; 248}; 249 250 251/* 252 * Read/write lock. The resource can have multiple readers or one writer, 253 * but can't be read and written at the same time. 254 * 255 * The same thread should not call a lock function while it already has 256 * a lock. (Should be okay for multiple readers.) 257 */ 258class ReadWriteLock { 259public: 260 ReadWriteLock() 261 : mNumReaders(0), mNumWriters(0) 262 {} 263 ~ReadWriteLock() {} 264 265 void lockForRead(); 266 bool tryLockForRead(); 267 void unlockForRead(); 268 269 void lockForWrite(); 270 bool tryLockForWrite(); 271 void unlockForWrite(); 272 273private: 274 int mNumReaders; 275 int mNumWriters; 276 277 Mutex mLock; 278 Condition mReadWaiter; 279 Condition mWriteWaiter; 280#if defined(PRINT_RENDER_TIMES) 281 DurationTimer mDebugTimer; 282#endif 283}; 284 285 286/* 287 * This is our spiffy thread object! 288 */ 289 290class Thread : virtual public RefBase 291{ 292public: 293 // Create a Thread object, but doesn't create or start the associated 294 // thread. See the run() method. 295 Thread(bool canCallJava = true); 296 virtual ~Thread(); 297 298 // Start the thread in threadLoop() which needs to be implemented. 299 virtual status_t run( const char* name = 0, 300 int32_t priority = PRIORITY_DEFAULT, 301 size_t stack = 0); 302 303 // Ask this object's thread to exit. This function is asynchronous, when the 304 // function returns the thread might still be running. Of course, this 305 // function can be called from a different thread. 306 virtual void requestExit(); 307 308 // Good place to do one-time initializations 309 virtual status_t readyToRun(); 310 311 // Call requestExit() and wait until this object's thread exits. 312 // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call 313 // this function from this object's thread. Will return WOULD_BLOCK in 314 // that case. 315 status_t requestExitAndWait(); 316 317protected: 318 // exitPending() returns true if requestExit() has been called. 319 bool exitPending() const; 320 321private: 322 // Derived class must implemtent threadLoop(). The thread starts its life 323 // here. There are two ways of using the Thread object: 324 // 1) loop: if threadLoop() returns true, it will be called again if 325 // requestExit() wasn't called. 326 // 2) once: if threadLoop() returns false, the thread will exit upon return. 327 virtual bool threadLoop() = 0; 328 329private: 330 Thread& operator=(const Thread&); 331 static int _threadLoop(void* user); 332 const bool mCanCallJava; 333 thread_id_t mThread; 334 Mutex mLock; 335 Condition mThreadExitedCondition; 336 status_t mStatus; 337 volatile bool mExitPending; 338 volatile bool mRunning; 339 sp<Thread> mHoldSelf; 340}; 341 342 343}; // namespace android 344 345#endif // __cplusplus 346 347#endif // _LIBS_UTILS_THREADS_H 348