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