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