Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 */
17 #ifndef _LIBS_UTILS_THREADS_H
18 #define _LIBS_UTILS_THREADS_H
20 #include <stdint.h>
21 #include <sys/types.h>
22 #include <time.h>
24 #if defined(HAVE_PTHREADS)
25 # include <pthread.h>
26 #endif
28 // ------------------------------------------------------------------
29 // C API
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
35 typedef void* android_thread_id_t;
37 typedef int (*android_thread_func_t)(void*);
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,
56 /* use for background tasks */
57 ANDROID_PRIORITY_BACKGROUND = 10,
59 /* most threads run at normal priority */
60 ANDROID_PRIORITY_NORMAL = 0,
62 /* threads currently running a UI that the user is interacting with */
63 ANDROID_PRIORITY_FOREGROUND = -2,
65 /* the main UI thread has a slightly more favorable priority */
66 ANDROID_PRIORITY_DISPLAY = -4,
68 /* ui service treads might want to run at a urgent display (uncommon) */
69 ANDROID_PRIORITY_URGENT_DISPLAY = -8,
71 /* all normal audio threads */
72 ANDROID_PRIORITY_AUDIO = -16,
74 /* service audio threads (uncommon) */
75 ANDROID_PRIORITY_URGENT_AUDIO = -19,
77 /* should never be used in practice. regular process might not
78 * be allowed to use this level */
79 ANDROID_PRIORITY_HIGHEST = -20,
81 ANDROID_PRIORITY_DEFAULT = ANDROID_PRIORITY_NORMAL,
82 ANDROID_PRIORITY_MORE_FAVORABLE = -1,
83 ANDROID_PRIORITY_LESS_FAVORABLE = +1,
84 };
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 };
93 // Create and run a new thread.
94 extern int androidCreateThread(android_thread_func_t, void *);
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);
104 // Get some sort of unique identifier for the current thread.
105 extern android_thread_id_t androidGetThreadId();
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);
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);
125 extern void androidSetCreateThreadFunc(android_create_thread_fn func);
127 // ------------------------------------------------------------------
128 // Extra functions working with raw pids.
130 // Get pid for the current thread.
131 extern pid_t androidGetTid();
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);
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);
145 #ifdef __cplusplus
146 }
147 #endif
149 // ------------------------------------------------------------------
150 // C++ API
152 #ifdef __cplusplus
154 #include <utils/Errors.h>
155 #include <utils/RefBase.h>
156 #include <utils/Timers.h>
158 namespace android {
160 typedef android_thread_id_t thread_id_t;
162 typedef android_thread_func_t thread_func_t;
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 };
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 }
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 }
196 // Get some sort of unique identifier for the current thread.
197 inline thread_id_t getThreadId() {
198 return androidGetThreadId();
199 }
201 /*****************************************************************************/
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 };
216 Mutex();
217 Mutex(const char* name);
218 Mutex(int type, const char* name = NULL);
219 ~Mutex();
221 // lock or unlock the mutex
222 status_t lock();
223 void unlock();
225 // lock if possible; returns 0 on success, error otherwise
226 status_t tryLock();
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 };
239 private:
240 friend class Condition;
242 // A mutex cannot be copied
243 Mutex(const Mutex&);
244 Mutex& operator = (const Mutex&);
246 #if defined(HAVE_PTHREADS)
247 pthread_mutex_t mMutex;
248 #else
249 void _init();
250 void* mState;
251 #endif
252 };
254 #if defined(HAVE_PTHREADS)
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 }
286 #endif // HAVE_PTHREADS
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 */
294 typedef Mutex::Autolock AutoMutex;
296 /*****************************************************************************/
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 };
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();
325 private:
326 #if defined(HAVE_PTHREADS)
327 pthread_cond_t mCond;
328 #else
329 void* mState;
330 #endif
331 };
333 #if defined(HAVE_PTHREADS)
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 }
388 #endif // HAVE_PTHREADS
390 /*****************************************************************************/
392 /*
393 * This is our spiffy thread object!
394 */
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();
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);
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();
414 // Good place to do one-time initializations
415 virtual status_t readyToRun();
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();
423 protected:
424 // exitPending() returns true if requestExit() has been called.
425 bool exitPending() const;
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;
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 };
452 }; // namespace android
454 #endif // __cplusplus
456 #endif // _LIBS_UTILS_THREADS_H