19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef _LIBS_UTILS_THREADS_H 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define _LIBS_UTILS_THREADS_H 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdint.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <time.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#if defined(HAVE_PTHREADS) 25b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian# include <pthread.h> 26b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#endif 27b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ------------------------------------------------------------------ 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// C API 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef __cplusplus 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern "C" { 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef void* android_thread_id_t; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef int (*android_thread_func_t)(void*); 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectenum { 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * *********************************************** 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ** Keep in sync with android.os.Process.java ** 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * *********************************************** 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This maps directly to the "nice" priorites we use in Android. 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A thread priority should be chosen inverse-proportinally to 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the amount of work the thread is expected to do. The more work 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a thread will do, the less favorable priority it should get so that 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it doesn't starve the system. Threads not behaving properly might 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be "punished" by the kernel. 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Use the levels below when appropriate. Intermediate values are 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below. 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANDROID_PRIORITY_LOWEST = 19, 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* use for background tasks */ 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANDROID_PRIORITY_BACKGROUND = 10, 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* most threads run at normal priority */ 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANDROID_PRIORITY_NORMAL = 0, 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* threads currently running a UI that the user is interacting with */ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANDROID_PRIORITY_FOREGROUND = -2, 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* the main UI thread has a slightly more favorable priority */ 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANDROID_PRIORITY_DISPLAY = -4, 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* ui service treads might want to run at a urgent display (uncommon) */ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANDROID_PRIORITY_URGENT_DISPLAY = -8, 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* all normal audio threads */ 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANDROID_PRIORITY_AUDIO = -16, 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* service audio threads (uncommon) */ 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANDROID_PRIORITY_URGENT_AUDIO = -19, 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* should never be used in practice. regular process might not 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be allowed to use this level */ 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANDROID_PRIORITY_HIGHEST = -20, 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANDROID_PRIORITY_DEFAULT = ANDROID_PRIORITY_NORMAL, 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANDROID_PRIORITY_MORE_FAVORABLE = -1, 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ANDROID_PRIORITY_LESS_FAVORABLE = +1, 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 86e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatenum { 87e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat ANDROID_TGROUP_DEFAULT = 0, 88e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat ANDROID_TGROUP_BG_NONINTERACT = 1, 89e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat ANDROID_TGROUP_FG_BOOST = 2, 90e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat ANDROID_TGROUP_MAX = ANDROID_TGROUP_FG_BOOST, 91e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat}; 92e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Create and run a new thread. 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern int androidCreateThread(android_thread_func_t, void *); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Create thread with lots of parameters 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern int androidCreateThreadEtc(android_thread_func_t entryFunction, 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void *userData, 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* threadName, 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t threadPriority, 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t threadStackSize, 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_thread_id_t *threadId); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Get some sort of unique identifier for the current thread. 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern android_thread_id_t androidGetThreadId(); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Low-level thread creation -- never creates threads that can 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// interact with the Java VM. 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern int androidCreateRawThreadEtc(android_thread_func_t entryFunction, 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void *userData, 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* threadName, 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t threadPriority, 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t threadStackSize, 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_thread_id_t *threadId); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Used by the Java Runtime to control how threads are created, so that 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// they can be proper and lovely Java threads. 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef int (*android_create_thread_fn)(android_thread_func_t entryFunction, 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void *userData, 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* threadName, 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t threadPriority, 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t threadStackSize, 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_thread_id_t *threadId); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern void androidSetCreateThreadFunc(android_create_thread_fn func); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 127887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn// ------------------------------------------------------------------ 128887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn// Extra functions working with raw pids. 129887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn 130887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn// Get pid for the current thread. 131887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackbornextern pid_t androidGetTid(); 132887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn 133887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn// Change the scheduling group of a particular thread. The group 134887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn// should be one of the ANDROID_TGROUP constants. Returns BAD_VALUE if 135887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn// grp is out of range, else another non-zero value with errno set if 136887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn// the operation failed. 137887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackbornextern int androidSetThreadSchedulingGroup(pid_t tid, int grp); 138887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn 139887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn// Change the priority AND scheduling group of a particular thread. The priority 140887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn// should be one of the ANDROID_PRIORITY constants. Returns INVALID_OPERATION 141887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn// if the priority set failed, else another value if just the group set failed; 142887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn// in either case errno is set. 143887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackbornextern int androidSetThreadPriority(pid_t tid, int prio); 144887f355f99ff83d568ef2885a4fdcaae475583dfDianne Hackborn 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef __cplusplus 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ------------------------------------------------------------------ 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// C++ API 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef __cplusplus 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Errors.h> 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/RefBase.h> 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Timers.h> 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef android_thread_id_t thread_id_t; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef android_thread_func_t thread_func_t; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectenum { 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PRIORITY_LOWEST = ANDROID_PRIORITY_LOWEST, 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PRIORITY_BACKGROUND = ANDROID_PRIORITY_BACKGROUND, 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PRIORITY_NORMAL = ANDROID_PRIORITY_NORMAL, 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PRIORITY_FOREGROUND = ANDROID_PRIORITY_FOREGROUND, 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PRIORITY_DISPLAY = ANDROID_PRIORITY_DISPLAY, 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY, 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PRIORITY_AUDIO = ANDROID_PRIORITY_AUDIO, 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PRIORITY_URGENT_AUDIO = ANDROID_PRIORITY_URGENT_AUDIO, 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PRIORITY_HIGHEST = ANDROID_PRIORITY_HIGHEST, 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PRIORITY_DEFAULT = ANDROID_PRIORITY_DEFAULT, 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE, 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE, 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Create and run a new thread. 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline bool createThread(thread_func_t f, void *a) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return androidCreateThread(f, a) ? true : false; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Create thread with lots of parameters 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline bool createThreadEtc(thread_func_t entryFunction, 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void *userData, 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* threadName = "android:unnamed_thread", 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t threadPriority = PRIORITY_DEFAULT, 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t threadStackSize = 0, 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thread_id_t *threadId = 0) 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return androidCreateThreadEtc(entryFunction, userData, threadName, 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project threadPriority, threadStackSize, threadId) ? true : false; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Get some sort of unique identifier for the current thread. 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline thread_id_t getThreadId() { 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return androidGetThreadId(); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 201b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian/*****************************************************************************/ 202b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Simple mutex class. The implementation is system-dependent. 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The mutex must be unlocked by the thread that locked it. They are not 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * recursive, i.e. the same thread can't lock it multiple times. 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass Mutex { 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 211fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian enum { 212a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian PRIVATE = 0, 213fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian SHARED = 1 214fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian }; 215fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex(); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex(const char* name); 218fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian Mutex(int type, const char* name = NULL); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~Mutex(); 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // lock or unlock the mutex 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t lock(); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void unlock(); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // lock if possible; returns 0 on success, error otherwise 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t tryLock(); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Manages the mutex automatically. It'll be locked when Autolock is 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // constructed and released when Autolock goes out of scope. 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class Autolock { 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public: 232aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } 233aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } 234aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian inline ~Autolock() { mLock.unlock(); } 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private: 236aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian Mutex& mLock; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project friend class Condition; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // A mutex cannot be copied 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex(const Mutex&); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex& operator = (const Mutex&); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 246b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#if defined(HAVE_PTHREADS) 247b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian pthread_mutex_t mMutex; 248b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#else 249b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian void _init(); 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* mState; 251b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#endif 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 254b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#if defined(HAVE_PTHREADS) 255b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian 256b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopianinline Mutex::Mutex() { 257b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian pthread_mutex_init(&mMutex, NULL); 258b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian} 259b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopianinline Mutex::Mutex(const char* name) { 260b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian pthread_mutex_init(&mMutex, NULL); 261b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian} 262fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopianinline Mutex::Mutex(int type, const char* name) { 263fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian if (type == SHARED) { 264fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian pthread_mutexattr_t attr; 265fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian pthread_mutexattr_init(&attr); 266fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 267fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian pthread_mutex_init(&mMutex, &attr); 268fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian pthread_mutexattr_destroy(&attr); 269fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian } else { 270fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian pthread_mutex_init(&mMutex, NULL); 271fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian } 272fb4f266a1b9f6a20e256d192a940ae4ccc510fadMathias Agopian} 273b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopianinline Mutex::~Mutex() { 274b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian pthread_mutex_destroy(&mMutex); 275b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian} 276b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopianinline status_t Mutex::lock() { 277b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian return -pthread_mutex_lock(&mMutex); 278b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian} 279b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopianinline void Mutex::unlock() { 280b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian pthread_mutex_unlock(&mMutex); 281b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian} 282b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopianinline status_t Mutex::tryLock() { 283b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian return -pthread_mutex_trylock(&mMutex); 284b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian} 285b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian 286b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#endif // HAVE_PTHREADS 287b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Automatic mutex. Declare one of these at the top of a function. 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * When the function returns, it will go out of scope, and release the 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * mutex. 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef Mutex::Autolock AutoMutex; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 296b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian/*****************************************************************************/ 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29866c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian#if defined(HAVE_PTHREADS) 29966c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian 30066c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian/* 30166c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian * Simple mutex class. The implementation is system-dependent. 30266c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian * 30366c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian * The mutex must be unlocked by the thread that locked it. They are not 30466c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian * recursive, i.e. the same thread can't lock it multiple times. 30566c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian */ 30666c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopianclass RWLock { 30766c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopianpublic: 30866c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian enum { 30966c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian PRIVATE = 0, 31066c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian SHARED = 1 31166c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian }; 31266c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian 31366c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian RWLock(); 31466c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian RWLock(const char* name); 31566c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian RWLock(int type, const char* name = NULL); 31666c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian ~RWLock(); 31766c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian 31866c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian status_t readLock(); 31966c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian status_t tryReadLock(); 32066c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian status_t writeLock(); 32166c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian status_t tryWriteLock(); 32266c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian void unlock(); 32366c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian 32466c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian class AutoRLock { 32566c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian public: 32666c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian inline AutoRLock(RWLock& rwlock) : mLock(rwlock) { mLock.readLock(); } 32766c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian inline ~AutoRLock() { mLock.unlock(); } 32866c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian private: 32966c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian RWLock& mLock; 33066c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian }; 33166c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian 33266c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian class AutoWLock { 33366c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian public: 33466c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian inline AutoWLock(RWLock& rwlock) : mLock(rwlock) { mLock.writeLock(); } 33566c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian inline ~AutoWLock() { mLock.unlock(); } 33666c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian private: 33766c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian RWLock& mLock; 33866c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian }; 33966c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian 34066c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopianprivate: 34166c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian // A RWLock cannot be copied 34266c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian RWLock(const RWLock&); 34366c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian RWLock& operator = (const RWLock&); 34466c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian 34566c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian pthread_rwlock_t mRWLock; 34666c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian}; 34766c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian 34866c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopianinline RWLock::RWLock() { 34966c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian pthread_rwlock_init(&mRWLock, NULL); 35066c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian} 35166c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopianinline RWLock::RWLock(const char* name) { 35266c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian pthread_rwlock_init(&mRWLock, NULL); 35366c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian} 35466c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopianinline RWLock::RWLock(int type, const char* name) { 35566c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian if (type == SHARED) { 35666c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian pthread_rwlockattr_t attr; 35766c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian pthread_rwlockattr_init(&attr); 35866c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 35966c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian pthread_rwlock_init(&mRWLock, &attr); 36066c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian pthread_rwlockattr_destroy(&attr); 36166c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian } else { 36266c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian pthread_rwlock_init(&mRWLock, NULL); 36366c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian } 36466c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian} 36566c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopianinline RWLock::~RWLock() { 36666c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian pthread_rwlock_destroy(&mRWLock); 36766c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian} 36866c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopianinline status_t RWLock::readLock() { 36966c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian return -pthread_rwlock_rdlock(&mRWLock); 37066c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian} 37166c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopianinline status_t RWLock::tryReadLock() { 37266c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian return -pthread_rwlock_tryrdlock(&mRWLock); 37366c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian} 37466c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopianinline status_t RWLock::writeLock() { 37566c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian return -pthread_rwlock_wrlock(&mRWLock); 37666c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian} 37766c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopianinline status_t RWLock::tryWriteLock() { 37866c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian return -pthread_rwlock_trywrlock(&mRWLock); 37966c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian} 38066c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopianinline void RWLock::unlock() { 38166c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian pthread_rwlock_unlock(&mRWLock); 38266c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian} 38366c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian 38466c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian#endif // HAVE_PTHREADS 38566c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian 38666c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian/*****************************************************************************/ 38766c46a6bd15422fe898d533d1350d6df748dd95bMathias Agopian 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Condition variable class. The implementation is system-dependent. 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Condition variables are paired up with mutexes. Lock the mutex, 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * call wait(), then either re-wait() if things aren't quite what you want, 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or unlock the mutex and continue. All threads calling wait() must 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * use the same mutex for a given Condition. 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass Condition { 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 398a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian enum { 399a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian PRIVATE = 0, 400a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian SHARED = 1 401a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian }; 402a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Condition(); 404a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian Condition(int type); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~Condition(); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Wait on the condition variable. Lock the mutex before calling. 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t wait(Mutex& mutex); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // same with relative timeout 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t waitRelative(Mutex& mutex, nsecs_t reltime); 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Signal the condition variable, allowing one thread to continue. 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void signal(); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Signal the condition variable, allowing all threads to continue. 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void broadcast(); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 416b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#if defined(HAVE_PTHREADS) 417b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian pthread_cond_t mCond; 418b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#else 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* mState; 420b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#endif 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 423b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#if defined(HAVE_PTHREADS) 424b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian 425b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopianinline Condition::Condition() { 426b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian pthread_cond_init(&mCond, NULL); 427b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian} 428a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopianinline Condition::Condition(int type) { 429a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian if (type == SHARED) { 430a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian pthread_condattr_t attr; 431a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian pthread_condattr_init(&attr); 432a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 433a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian pthread_cond_init(&mCond, &attr); 434a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian pthread_condattr_destroy(&attr); 435a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian } else { 436a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian pthread_cond_init(&mCond, NULL); 437a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian } 438a729f97e8bfba67a94b1cde26d0d78d84528de85Mathias Agopian} 439b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopianinline Condition::~Condition() { 440b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian pthread_cond_destroy(&mCond); 441b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian} 442b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopianinline status_t Condition::wait(Mutex& mutex) { 443b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian return -pthread_cond_wait(&mCond, &mutex.mMutex); 444b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian} 445b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopianinline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) { 446b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE) 447b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian struct timespec ts; 448b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian ts.tv_sec = reltime/1000000000; 449b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian ts.tv_nsec = reltime%1000000000; 450b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts); 451b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE 452b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian struct timespec ts; 453b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#if defined(HAVE_POSIX_CLOCKS) 454b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian clock_gettime(CLOCK_REALTIME, &ts); 455b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#else // HAVE_POSIX_CLOCKS 456b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian // we don't support the clocks here. 457b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian struct timeval t; 458b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian gettimeofday(&t, NULL); 459b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian ts.tv_sec = t.tv_sec; 460b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian ts.tv_nsec= t.tv_usec*1000; 461b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#endif // HAVE_POSIX_CLOCKS 462b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian ts.tv_sec += reltime/1000000000; 463b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian ts.tv_nsec+= reltime%1000000000; 464b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian if (ts.tv_nsec >= 1000000000) { 465b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian ts.tv_nsec -= 1000000000; 466b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian ts.tv_sec += 1; 467b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian } 468b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts); 469b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE 470b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian} 471b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopianinline void Condition::signal() { 472b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian pthread_cond_signal(&mCond); 473b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian} 474b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopianinline void Condition::broadcast() { 475b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian pthread_cond_broadcast(&mCond); 476b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian} 477b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian 478b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian#endif // HAVE_PTHREADS 479b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian 480b1c4ca5ad21ae63cd5af2cfc1be82ba176d25195Mathias Agopian/*****************************************************************************/ 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is our spiffy thread object! 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass Thread : virtual public RefBase 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Create a Thread object, but doesn't create or start the associated 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // thread. See the run() method. 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Thread(bool canCallJava = true); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual ~Thread(); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Start the thread in threadLoop() which needs to be implemented. 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual status_t run( const char* name = 0, 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t priority = PRIORITY_DEFAULT, 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t stack = 0); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Ask this object's thread to exit. This function is asynchronous, when the 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // function returns the thread might still be running. Of course, this 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // function can be called from a different thread. 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual void requestExit(); 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Good place to do one-time initializations 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual status_t readyToRun(); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Call requestExit() and wait until this object's thread exits. 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this function from this object's thread. Will return WOULD_BLOCK in 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // that case. 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t requestExitAndWait(); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprotected: 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // exitPending() returns true if requestExit() has been called. 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool exitPending() const; 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 518aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian // Derived class must implement threadLoop(). The thread starts its life 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // here. There are two ways of using the Thread object: 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 1) loop: if threadLoop() returns true, it will be called again if 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // requestExit() wasn't called. 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 2) once: if threadLoop() returns false, the thread will exit upon return. 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual bool threadLoop() = 0; 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Thread& operator=(const Thread&); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int _threadLoop(void* user); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const bool mCanCallJava; 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thread_id_t mThread; 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex mLock; 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Condition mThreadExitedCondition; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t mStatus; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile bool mExitPending; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile bool mRunning; 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<Thread> mHoldSelf; 536d42bd87f23974164d2539ea85c7b5e6329faf2c2Mathias Agopian#if HAVE_ANDROID_OS 537d42bd87f23974164d2539ea85c7b5e6329faf2c2Mathias Agopian int mTid; 538d42bd87f23974164d2539ea85c7b5e6329faf2c2Mathias Agopian#endif 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif // __cplusplus 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif // _LIBS_UTILS_THREADS_H 547