diff options
Diffstat (limited to 'media/omx-plugin/include/ics/utils/threads.h')
-rw-r--r-- | media/omx-plugin/include/ics/utils/threads.h | 564 |
1 files changed, 0 insertions, 564 deletions
diff --git a/media/omx-plugin/include/ics/utils/threads.h b/media/omx-plugin/include/ics/utils/threads.h deleted file mode 100644 index ab3e8cdb6..000000000 --- a/media/omx-plugin/include/ics/utils/threads.h +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _LIBS_UTILS_THREADS_H -#define _LIBS_UTILS_THREADS_H - -#include <stdint.h> -#include <sys/types.h> -#include <time.h> -#include <system/graphics.h> - -#if defined(HAVE_PTHREADS) -# include <pthread.h> -#endif - -// ------------------------------------------------------------------ -// C API - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void* android_thread_id_t; - -typedef int (*android_thread_func_t)(void*); - -enum { - /* - * *********************************************** - * ** Keep in sync with android.os.Process.java ** - * *********************************************** - * - * This maps directly to the "nice" priorities we use in Android. - * A thread priority should be chosen inverse-proportionally to - * the amount of work the thread is expected to do. The more work - * a thread will do, the less favorable priority it should get so that - * it doesn't starve the system. Threads not behaving properly might - * be "punished" by the kernel. - * Use the levels below when appropriate. Intermediate values are - * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below. - */ - ANDROID_PRIORITY_LOWEST = 19, - - /* use for background tasks */ - ANDROID_PRIORITY_BACKGROUND = 10, - - /* most threads run at normal priority */ - ANDROID_PRIORITY_NORMAL = 0, - - /* threads currently running a UI that the user is interacting with */ - ANDROID_PRIORITY_FOREGROUND = -2, - - /* the main UI thread has a slightly more favorable priority */ - ANDROID_PRIORITY_DISPLAY = -4, - - /* ui service treads might want to run at a urgent display (uncommon) */ - ANDROID_PRIORITY_URGENT_DISPLAY = HAL_PRIORITY_URGENT_DISPLAY, - - /* all normal audio threads */ - ANDROID_PRIORITY_AUDIO = -16, - - /* service audio threads (uncommon) */ - ANDROID_PRIORITY_URGENT_AUDIO = -19, - - /* should never be used in practice. regular process might not - * be allowed to use this level */ - ANDROID_PRIORITY_HIGHEST = -20, - - ANDROID_PRIORITY_DEFAULT = ANDROID_PRIORITY_NORMAL, - ANDROID_PRIORITY_MORE_FAVORABLE = -1, - ANDROID_PRIORITY_LESS_FAVORABLE = +1, -}; - -enum { - ANDROID_TGROUP_DEFAULT = 0, - ANDROID_TGROUP_BG_NONINTERACT = 1, - ANDROID_TGROUP_FG_BOOST = 2, - ANDROID_TGROUP_MAX = ANDROID_TGROUP_FG_BOOST, -}; - -// Create and run a new thread. -extern int androidCreateThread(android_thread_func_t, void *); - -// Create thread with lots of parameters -extern int androidCreateThreadEtc(android_thread_func_t entryFunction, - void *userData, - const char* threadName, - int32_t threadPriority, - size_t threadStackSize, - android_thread_id_t *threadId); - -// Get some sort of unique identifier for the current thread. -extern android_thread_id_t androidGetThreadId(); - -// Low-level thread creation -- never creates threads that can -// interact with the Java VM. -extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction, - void *userData, - const char* threadName, - int32_t threadPriority, - size_t threadStackSize, - android_thread_id_t *threadId); - -// Used by the Java Runtime to control how threads are created, so that -// they can be proper and lovely Java threads. -typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction, - void *userData, - const char* threadName, - int32_t threadPriority, - size_t threadStackSize, - android_thread_id_t *threadId); - -extern void androidSetCreateThreadFunc(android_create_thread_fn func); - -// ------------------------------------------------------------------ -// Extra functions working with raw pids. - -// Get pid for the current thread. -extern pid_t androidGetTid(); - -// Change the scheduling group of a particular thread. The group -// should be one of the ANDROID_TGROUP constants. Returns BAD_VALUE if -// grp is out of range, else another non-zero value with errno set if -// the operation failed. Thread ID zero means current thread. -extern int androidSetThreadSchedulingGroup(pid_t tid, int grp); - -// Change the priority AND scheduling group of a particular thread. The priority -// should be one of the ANDROID_PRIORITY constants. Returns INVALID_OPERATION -// if the priority set failed, else another value if just the group set failed; -// in either case errno is set. Thread ID zero means current thread. -extern int androidSetThreadPriority(pid_t tid, int prio); - -// Get the current priority of a particular thread. Returns one of the -// ANDROID_PRIORITY constants or a negative result in case of error. -extern int androidGetThreadPriority(pid_t tid); - -// Get the current scheduling group of a particular thread. Normally returns -// one of the ANDROID_TGROUP constants other than ANDROID_TGROUP_DEFAULT. -// Returns ANDROID_TGROUP_DEFAULT if no pthread support (e.g. on host) or if -// scheduling groups are disabled. Returns INVALID_OPERATION if unexpected error. -// Thread ID zero means current thread. -extern int androidGetThreadSchedulingGroup(pid_t tid); - -#ifdef __cplusplus -} -#endif - -// ------------------------------------------------------------------ -// C++ API - -#ifdef __cplusplus - -#include <utils/Errors.h> -#include <utils/RefBase.h> -#include <utils/Timers.h> - -namespace android { - -typedef android_thread_id_t thread_id_t; - -typedef android_thread_func_t thread_func_t; - -enum { - PRIORITY_LOWEST = ANDROID_PRIORITY_LOWEST, - PRIORITY_BACKGROUND = ANDROID_PRIORITY_BACKGROUND, - PRIORITY_NORMAL = ANDROID_PRIORITY_NORMAL, - PRIORITY_FOREGROUND = ANDROID_PRIORITY_FOREGROUND, - PRIORITY_DISPLAY = ANDROID_PRIORITY_DISPLAY, - PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY, - PRIORITY_AUDIO = ANDROID_PRIORITY_AUDIO, - PRIORITY_URGENT_AUDIO = ANDROID_PRIORITY_URGENT_AUDIO, - PRIORITY_HIGHEST = ANDROID_PRIORITY_HIGHEST, - PRIORITY_DEFAULT = ANDROID_PRIORITY_DEFAULT, - PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE, - PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE, -}; - -// Create and run a new thread. -inline bool createThread(thread_func_t f, void *a) { - return androidCreateThread(f, a) ? true : false; -} - -// Create thread with lots of parameters -inline bool createThreadEtc(thread_func_t entryFunction, - void *userData, - const char* threadName = "android:unnamed_thread", - int32_t threadPriority = PRIORITY_DEFAULT, - size_t threadStackSize = 0, - thread_id_t *threadId = 0) -{ - return androidCreateThreadEtc(entryFunction, userData, threadName, - threadPriority, threadStackSize, threadId) ? true : false; -} - -// Get some sort of unique identifier for the current thread. -inline thread_id_t getThreadId() { - return androidGetThreadId(); -} - -/*****************************************************************************/ - -/* - * Simple mutex class. The implementation is system-dependent. - * - * The mutex must be unlocked by the thread that locked it. They are not - * recursive, i.e. the same thread can't lock it multiple times. - */ -class Mutex { -public: - enum { - PRIVATE = 0, - SHARED = 1 - }; - - Mutex(); - Mutex(const char* name); - Mutex(int type, const char* name = NULL); - ~Mutex(); - - // lock or unlock the mutex - status_t lock(); - void unlock(); - - // lock if possible; returns 0 on success, error otherwise - status_t tryLock(); - - // Manages the mutex automatically. It'll be locked when Autolock is - // constructed and released when Autolock goes out of scope. - class Autolock { - public: - inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } - inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } - inline ~Autolock() { mLock.unlock(); } - private: - Mutex& mLock; - }; - -private: - friend class Condition; - - // A mutex cannot be copied - Mutex(const Mutex&); - Mutex& operator = (const Mutex&); - -#if defined(HAVE_PTHREADS) - pthread_mutex_t mMutex; -#else - void _init(); - void* mState; -#endif -}; - -#if defined(HAVE_PTHREADS) - -inline Mutex::Mutex() { - pthread_mutex_init(&mMutex, NULL); -} -inline Mutex::Mutex(const char* name) { - pthread_mutex_init(&mMutex, NULL); -} -inline Mutex::Mutex(int type, const char* name) { - if (type == SHARED) { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - pthread_mutex_init(&mMutex, &attr); - pthread_mutexattr_destroy(&attr); - } else { - pthread_mutex_init(&mMutex, NULL); - } -} -inline Mutex::~Mutex() { - pthread_mutex_destroy(&mMutex); -} -inline status_t Mutex::lock() { - return -pthread_mutex_lock(&mMutex); -} -inline void Mutex::unlock() { - pthread_mutex_unlock(&mMutex); -} -inline status_t Mutex::tryLock() { - return -pthread_mutex_trylock(&mMutex); -} - -#endif // HAVE_PTHREADS - -/* - * Automatic mutex. Declare one of these at the top of a function. - * When the function returns, it will go out of scope, and release the - * mutex. - */ - -typedef Mutex::Autolock AutoMutex; - -/*****************************************************************************/ - -#if defined(HAVE_PTHREADS) - -/* - * Simple mutex class. The implementation is system-dependent. - * - * The mutex must be unlocked by the thread that locked it. They are not - * recursive, i.e. the same thread can't lock it multiple times. - */ -class RWLock { -public: - enum { - PRIVATE = 0, - SHARED = 1 - }; - - RWLock(); - RWLock(const char* name); - RWLock(int type, const char* name = NULL); - ~RWLock(); - - status_t readLock(); - status_t tryReadLock(); - status_t writeLock(); - status_t tryWriteLock(); - void unlock(); - - class AutoRLock { - public: - inline AutoRLock(RWLock& rwlock) : mLock(rwlock) { mLock.readLock(); } - inline ~AutoRLock() { mLock.unlock(); } - private: - RWLock& mLock; - }; - - class AutoWLock { - public: - inline AutoWLock(RWLock& rwlock) : mLock(rwlock) { mLock.writeLock(); } - inline ~AutoWLock() { mLock.unlock(); } - private: - RWLock& mLock; - }; - -private: - // A RWLock cannot be copied - RWLock(const RWLock&); - RWLock& operator = (const RWLock&); - - pthread_rwlock_t mRWLock; -}; - -inline RWLock::RWLock() { - pthread_rwlock_init(&mRWLock, NULL); -} -inline RWLock::RWLock(const char* name) { - pthread_rwlock_init(&mRWLock, NULL); -} -inline RWLock::RWLock(int type, const char* name) { - if (type == SHARED) { - pthread_rwlockattr_t attr; - pthread_rwlockattr_init(&attr); - pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - pthread_rwlock_init(&mRWLock, &attr); - pthread_rwlockattr_destroy(&attr); - } else { - pthread_rwlock_init(&mRWLock, NULL); - } -} -inline RWLock::~RWLock() { - pthread_rwlock_destroy(&mRWLock); -} -inline status_t RWLock::readLock() { - return -pthread_rwlock_rdlock(&mRWLock); -} -inline status_t RWLock::tryReadLock() { - return -pthread_rwlock_tryrdlock(&mRWLock); -} -inline status_t RWLock::writeLock() { - return -pthread_rwlock_wrlock(&mRWLock); -} -inline status_t RWLock::tryWriteLock() { - return -pthread_rwlock_trywrlock(&mRWLock); -} -inline void RWLock::unlock() { - pthread_rwlock_unlock(&mRWLock); -} - -#endif // HAVE_PTHREADS - -/*****************************************************************************/ - -/* - * Condition variable class. The implementation is system-dependent. - * - * Condition variables are paired up with mutexes. Lock the mutex, - * call wait(), then either re-wait() if things aren't quite what you want, - * or unlock the mutex and continue. All threads calling wait() must - * use the same mutex for a given Condition. - */ -class Condition { -public: - enum { - PRIVATE = 0, - SHARED = 1 - }; - - Condition(); - Condition(int type); - ~Condition(); - // Wait on the condition variable. Lock the mutex before calling. - status_t wait(Mutex& mutex); - // same with relative timeout - status_t waitRelative(Mutex& mutex, nsecs_t reltime); - // Signal the condition variable, allowing one thread to continue. - void signal(); - // Signal the condition variable, allowing all threads to continue. - void broadcast(); - -private: -#if defined(HAVE_PTHREADS) - pthread_cond_t mCond; -#else - void* mState; -#endif -}; - -#if defined(HAVE_PTHREADS) - -inline Condition::Condition() { - pthread_cond_init(&mCond, NULL); -} -inline Condition::Condition(int type) { - if (type == SHARED) { - pthread_condattr_t attr; - pthread_condattr_init(&attr); - pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - pthread_cond_init(&mCond, &attr); - pthread_condattr_destroy(&attr); - } else { - pthread_cond_init(&mCond, NULL); - } -} -inline Condition::~Condition() { - pthread_cond_destroy(&mCond); -} -inline status_t Condition::wait(Mutex& mutex) { - return -pthread_cond_wait(&mCond, &mutex.mMutex); -} -inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) { -#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE) - struct timespec ts; - ts.tv_sec = reltime/1000000000; - ts.tv_nsec = reltime%1000000000; - return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts); -#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE - struct timespec ts; -#if defined(HAVE_POSIX_CLOCKS) - clock_gettime(CLOCK_REALTIME, &ts); -#else // HAVE_POSIX_CLOCKS - // we don't support the clocks here. - struct timeval t; - gettimeofday(&t, NULL); - ts.tv_sec = t.tv_sec; - ts.tv_nsec= t.tv_usec*1000; -#endif // HAVE_POSIX_CLOCKS - ts.tv_sec += reltime/1000000000; - ts.tv_nsec+= reltime%1000000000; - if (ts.tv_nsec >= 1000000000) { - ts.tv_nsec -= 1000000000; - ts.tv_sec += 1; - } - return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts); -#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE -} -inline void Condition::signal() { - pthread_cond_signal(&mCond); -} -inline void Condition::broadcast() { - pthread_cond_broadcast(&mCond); -} - -#endif // HAVE_PTHREADS - -/*****************************************************************************/ - -/* - * This is our spiffy thread object! - */ - -class Thread : virtual public RefBase -{ -public: - // Create a Thread object, but doesn't create or start the associated - // thread. See the run() method. - Thread(bool canCallJava = true); - virtual ~Thread(); - - // Start the thread in threadLoop() which needs to be implemented. - virtual status_t run( const char* name = 0, - int32_t priority = PRIORITY_DEFAULT, - size_t stack = 0); - - // Ask this object's thread to exit. This function is asynchronous, when the - // function returns the thread might still be running. Of course, this - // function can be called from a different thread. - virtual void requestExit(); - - // Good place to do one-time initializations - virtual status_t readyToRun(); - - // Call requestExit() and wait until this object's thread exits. - // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call - // this function from this object's thread. Will return WOULD_BLOCK in - // that case. - status_t requestExitAndWait(); - - // Wait until this object's thread exits. Returns immediately if not yet running. - // Do not call from this object's thread; will return WOULD_BLOCK in that case. - status_t join(); - -protected: - // exitPending() returns true if requestExit() has been called. - bool exitPending() const; - -private: - // Derived class must implement threadLoop(). The thread starts its life - // here. There are two ways of using the Thread object: - // 1) loop: if threadLoop() returns true, it will be called again if - // requestExit() wasn't called. - // 2) once: if threadLoop() returns false, the thread will exit upon return. - virtual bool threadLoop() = 0; - -private: - Thread& operator=(const Thread&); - static int _threadLoop(void* user); - const bool mCanCallJava; - // always hold mLock when reading or writing - thread_id_t mThread; - mutable Mutex mLock; - Condition mThreadExitedCondition; - status_t mStatus; - // note that all accesses of mExitPending and mRunning need to hold mLock - volatile bool mExitPending; - volatile bool mRunning; - sp<Thread> mHoldSelf; -#if HAVE_ANDROID_OS - int mTid; -#endif -}; - - -}; // namespace android - -#endif // __cplusplus - -#endif // _LIBS_UTILS_THREADS_H |