threads.h revision 83c0446f27b9542d6c2e724817b2b2d8d1f55085
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 82enum { 83 ANDROID_TGROUP_DEFAULT = 0, 84 ANDROID_TGROUP_BG_NONINTERACT = 1, 85 ANDROID_TGROUP_FG_BOOST = 2, 86 ANDROID_TGROUP_MAX = ANDROID_TGROUP_FG_BOOST, 87}; 88 89// Create and run a new thread. 90extern int androidCreateThread(android_thread_func_t, void *); 91 92// Create thread with lots of parameters 93extern int androidCreateThreadEtc(android_thread_func_t entryFunction, 94 void *userData, 95 const char* threadName, 96 int32_t threadPriority, 97 size_t threadStackSize, 98 android_thread_id_t *threadId); 99 100// Get some sort of unique identifier for the current thread. 101extern android_thread_id_t androidGetThreadId(); 102 103// Low-level thread creation -- never creates threads that can 104// interact with the Java VM. 105extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction, 106 void *userData, 107 const char* threadName, 108 int32_t threadPriority, 109 size_t threadStackSize, 110 android_thread_id_t *threadId); 111 112// Used by the Java Runtime to control how threads are created, so that 113// they can be proper and lovely Java threads. 114typedef int (*android_create_thread_fn)(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 121extern void androidSetCreateThreadFunc(android_create_thread_fn func); 122 123#ifdef __cplusplus 124} 125#endif 126 127// ------------------------------------------------------------------ 128// C++ API 129 130#ifdef __cplusplus 131 132#include <utils/Errors.h> 133#include <utils/RefBase.h> 134#include <utils/Timers.h> 135 136namespace android { 137 138typedef android_thread_id_t thread_id_t; 139 140typedef android_thread_func_t thread_func_t; 141 142enum { 143 PRIORITY_LOWEST = ANDROID_PRIORITY_LOWEST, 144 PRIORITY_BACKGROUND = ANDROID_PRIORITY_BACKGROUND, 145 PRIORITY_NORMAL = ANDROID_PRIORITY_NORMAL, 146 PRIORITY_FOREGROUND = ANDROID_PRIORITY_FOREGROUND, 147 PRIORITY_DISPLAY = ANDROID_PRIORITY_DISPLAY, 148 PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY, 149 PRIORITY_AUDIO = ANDROID_PRIORITY_AUDIO, 150 PRIORITY_URGENT_AUDIO = ANDROID_PRIORITY_URGENT_AUDIO, 151 PRIORITY_HIGHEST = ANDROID_PRIORITY_HIGHEST, 152 PRIORITY_DEFAULT = ANDROID_PRIORITY_DEFAULT, 153 PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE, 154 PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE, 155}; 156 157// Create and run a new thread. 158inline bool createThread(thread_func_t f, void *a) { 159 return androidCreateThread(f, a) ? true : false; 160} 161 162// Create thread with lots of parameters 163inline bool createThreadEtc(thread_func_t entryFunction, 164 void *userData, 165 const char* threadName = "android:unnamed_thread", 166 int32_t threadPriority = PRIORITY_DEFAULT, 167 size_t threadStackSize = 0, 168 thread_id_t *threadId = 0) 169{ 170 return androidCreateThreadEtc(entryFunction, userData, threadName, 171 threadPriority, threadStackSize, threadId) ? true : false; 172} 173 174// Get some sort of unique identifier for the current thread. 175inline thread_id_t getThreadId() { 176 return androidGetThreadId(); 177} 178 179/* 180 * Simple mutex class. The implementation is system-dependent. 181 * 182 * The mutex must be unlocked by the thread that locked it. They are not 183 * recursive, i.e. the same thread can't lock it multiple times. 184 */ 185class Mutex { 186public: 187 Mutex(); 188 Mutex(const char* name); 189 ~Mutex(); 190 191 // lock or unlock the mutex 192 status_t lock(); 193 void unlock(); 194 195 // lock if possible; returns 0 on success, error otherwise 196 status_t tryLock(); 197 198 // Manages the mutex automatically. It'll be locked when Autolock is 199 // constructed and released when Autolock goes out of scope. 200 class Autolock { 201 public: 202 inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } 203 inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } 204 inline ~Autolock() { mLock.unlock(); } 205 private: 206 Mutex& mLock; 207 }; 208 209private: 210 friend class Condition; 211 212 // A mutex cannot be copied 213 Mutex(const Mutex&); 214 Mutex& operator = (const Mutex&); 215 void _init(); 216 217 void* mState; 218}; 219 220/* 221 * Automatic mutex. Declare one of these at the top of a function. 222 * When the function returns, it will go out of scope, and release the 223 * mutex. 224 */ 225 226typedef Mutex::Autolock AutoMutex; 227 228 229/* 230 * Condition variable class. The implementation is system-dependent. 231 * 232 * Condition variables are paired up with mutexes. Lock the mutex, 233 * call wait(), then either re-wait() if things aren't quite what you want, 234 * or unlock the mutex and continue. All threads calling wait() must 235 * use the same mutex for a given Condition. 236 */ 237class Condition { 238public: 239 Condition(); 240 ~Condition(); 241 // Wait on the condition variable. Lock the mutex before calling. 242 status_t wait(Mutex& mutex); 243 // Wait on the condition variable until the given time. Lock the mutex 244 // before calling. 245 status_t wait(Mutex& mutex, nsecs_t abstime); 246 // same with relative timeout 247 status_t waitRelative(Mutex& mutex, nsecs_t reltime); 248 // Signal the condition variable, allowing one thread to continue. 249 void signal(); 250 // Signal the condition variable, allowing all threads to continue. 251 void broadcast(); 252 253private: 254 void* mState; 255}; 256 257 258/* 259 * This is our spiffy thread object! 260 */ 261 262class Thread : virtual public RefBase 263{ 264public: 265 // Create a Thread object, but doesn't create or start the associated 266 // thread. See the run() method. 267 Thread(bool canCallJava = true); 268 virtual ~Thread(); 269 270 // Start the thread in threadLoop() which needs to be implemented. 271 virtual status_t run( const char* name = 0, 272 int32_t priority = PRIORITY_DEFAULT, 273 size_t stack = 0); 274 275 // Ask this object's thread to exit. This function is asynchronous, when the 276 // function returns the thread might still be running. Of course, this 277 // function can be called from a different thread. 278 virtual void requestExit(); 279 280 // Good place to do one-time initializations 281 virtual status_t readyToRun(); 282 283 // Call requestExit() and wait until this object's thread exits. 284 // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call 285 // this function from this object's thread. Will return WOULD_BLOCK in 286 // that case. 287 status_t requestExitAndWait(); 288 289protected: 290 // exitPending() returns true if requestExit() has been called. 291 bool exitPending() const; 292 293private: 294 // Derived class must implement threadLoop(). The thread starts its life 295 // here. There are two ways of using the Thread object: 296 // 1) loop: if threadLoop() returns true, it will be called again if 297 // requestExit() wasn't called. 298 // 2) once: if threadLoop() returns false, the thread will exit upon return. 299 virtual bool threadLoop() = 0; 300 301private: 302 Thread& operator=(const Thread&); 303 static int _threadLoop(void* user); 304 const bool mCanCallJava; 305 thread_id_t mThread; 306 Mutex mLock; 307 Condition mThreadExitedCondition; 308 status_t mStatus; 309 volatile bool mExitPending; 310 volatile bool mRunning; 311 sp<Thread> mHoldSelf; 312}; 313 314 315}; // namespace android 316 317#endif // __cplusplus 318 319#endif // _LIBS_UTILS_THREADS_H 320