1f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian/* 2f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * Copyright (C) 2007 The Android Open Source Project 3f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * 4f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * you may not use this file except in compliance with the License. 6f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * You may obtain a copy of the License at 7f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * 8f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * 10f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * Unless required by applicable law or agreed to in writing, software 11f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * See the License for the specific language governing permissions and 14f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * limitations under the License. 15f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian */ 16f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 17f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#ifndef _LIBS_UTILS_CONDITION_H 18f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#define _LIBS_UTILS_CONDITION_H 19f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 20f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <stdint.h> 21f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <sys/types.h> 22f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <time.h> 23f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 24f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#if defined(HAVE_PTHREADS) 25f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian# include <pthread.h> 26f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#endif 27f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 28f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <utils/Errors.h> 29f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <utils/Mutex.h> 30f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#include <utils/Timers.h> 31f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 32f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian// --------------------------------------------------------------------------- 33f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopiannamespace android { 34f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian// --------------------------------------------------------------------------- 35f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 36f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian/* 37f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * Condition variable class. The implementation is system-dependent. 38f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * 39f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * Condition variables are paired up with mutexes. Lock the mutex, 40f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * call wait(), then either re-wait() if things aren't quite what you want, 41f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * or unlock the mutex and continue. All threads calling wait() must 42f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian * use the same mutex for a given Condition. 43f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian */ 44f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianclass Condition { 45f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianpublic: 46f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian enum { 47f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian PRIVATE = 0, 48f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian SHARED = 1 49f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian }; 50f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 51f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian Condition(); 52f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian Condition(int type); 53f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian ~Condition(); 54f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // Wait on the condition variable. Lock the mutex before calling. 55f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian status_t wait(Mutex& mutex); 56f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // same with relative timeout 57f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian status_t waitRelative(Mutex& mutex, nsecs_t reltime); 58f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // Signal the condition variable, allowing one thread to continue. 59f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian void signal(); 60f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // Signal the condition variable, allowing all threads to continue. 61f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian void broadcast(); 62f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 63f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianprivate: 64f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#if defined(HAVE_PTHREADS) 65f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pthread_cond_t mCond; 66f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#else 67f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian void* mState; 68f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#endif 69f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian}; 70f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 71f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian// --------------------------------------------------------------------------- 72f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 73f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#if defined(HAVE_PTHREADS) 74f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 75f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianinline Condition::Condition() { 76f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pthread_cond_init(&mCond, NULL); 77f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian} 78f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianinline Condition::Condition(int type) { 79f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian if (type == SHARED) { 80f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pthread_condattr_t attr; 81f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pthread_condattr_init(&attr); 82f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 83f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pthread_cond_init(&mCond, &attr); 84f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pthread_condattr_destroy(&attr); 85f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian } else { 86f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pthread_cond_init(&mCond, NULL); 87f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian } 88f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian} 89f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianinline Condition::~Condition() { 90f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pthread_cond_destroy(&mCond); 91f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian} 92f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianinline status_t Condition::wait(Mutex& mutex) { 93f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian return -pthread_cond_wait(&mCond, &mutex.mMutex); 94f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian} 95f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianinline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) { 96f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE) 97f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian struct timespec ts; 98f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian ts.tv_sec = reltime/1000000000; 99f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian ts.tv_nsec = reltime%1000000000; 100f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts); 101f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE 102f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian struct timespec ts; 103f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#if defined(HAVE_POSIX_CLOCKS) 104f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian clock_gettime(CLOCK_REALTIME, &ts); 105f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#else // HAVE_POSIX_CLOCKS 106f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian // we don't support the clocks here. 107f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian struct timeval t; 108f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian gettimeofday(&t, NULL); 109f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian ts.tv_sec = t.tv_sec; 110f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian ts.tv_nsec= t.tv_usec*1000; 111f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#endif // HAVE_POSIX_CLOCKS 112f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian ts.tv_sec += reltime/1000000000; 113f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian ts.tv_nsec+= reltime%1000000000; 114f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian if (ts.tv_nsec >= 1000000000) { 115f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian ts.tv_nsec -= 1000000000; 116f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian ts.tv_sec += 1; 117f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian } 118f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts); 119f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE 120f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian} 121f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianinline void Condition::signal() { 122f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pthread_cond_signal(&mCond); 123f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian} 124f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopianinline void Condition::broadcast() { 125f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian pthread_cond_broadcast(&mCond); 126f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian} 127f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 128f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#endif // HAVE_PTHREADS 129f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 130f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian// --------------------------------------------------------------------------- 131f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian}; // namespace android 132f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian// --------------------------------------------------------------------------- 133f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian 134f91bb05132dccbb61a69351752d9ae47cc31f30dMathias Agopian#endif // _LIBS_UTILS_CONDITON_H 135