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