Condition.h revision 31ba37f1c80801ee128749d4772c47f23323a3be
12bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian/* 22bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Copyright (C) 2007 The Android Open Source Project 32bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * 42bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 52bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * you may not use this file except in compliance with the License. 62bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * You may obtain a copy of the License at 72bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * 82bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 92bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * 102bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Unless required by applicable law or agreed to in writing, software 112bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 122bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * See the License for the specific language governing permissions and 142bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * limitations under the License. 152bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian */ 162bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 172bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#ifndef _LIBS_UTILS_CONDITION_H 182bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#define _LIBS_UTILS_CONDITION_H 192bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 202bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <stdint.h> 212bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <sys/types.h> 222bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <time.h> 232bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 242bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREADS) 252bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian# include <pthread.h> 262bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif 272bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 282bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <utils/Errors.h> 292bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <utils/Mutex.h> 302bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#include <utils/Timers.h> 312bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 322bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 332bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopiannamespace android { 342bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 352bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 362bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian/* 372bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Condition variable class. The implementation is system-dependent. 382bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * 392bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * Condition variables are paired up with mutexes. Lock the mutex, 402bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * call wait(), then either re-wait() if things aren't quite what you want, 412bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * or unlock the mutex and continue. All threads calling wait() must 422bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian * use the same mutex for a given Condition. 432bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian */ 442bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianclass Condition { 452bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianpublic: 462bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian enum { 472bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian PRIVATE = 0, 482bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian SHARED = 1 492bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian }; 502bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 5131ba37f1c80801ee128749d4772c47f23323a3beRomain Guy enum WakeUpType { 5231ba37f1c80801ee128749d4772c47f23323a3beRomain Guy WAKE_UP_ONE = 0, 5331ba37f1c80801ee128749d4772c47f23323a3beRomain Guy WAKE_UP_ALL = 1 5431ba37f1c80801ee128749d4772c47f23323a3beRomain Guy }; 5531ba37f1c80801ee128749d4772c47f23323a3beRomain Guy 562bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Condition(); 572bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Condition(int type); 582bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ~Condition(); 592bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Wait on the condition variable. Lock the mutex before calling. 602bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian status_t wait(Mutex& mutex); 612bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // same with relative timeout 622bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian status_t waitRelative(Mutex& mutex, nsecs_t reltime); 632bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Signal the condition variable, allowing one thread to continue. 642bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian void signal(); 6531ba37f1c80801ee128749d4772c47f23323a3beRomain Guy // Signal the condition variable, allowing one or all threads to continue. 6631ba37f1c80801ee128749d4772c47f23323a3beRomain Guy void signal(WakeUpType type) { 6731ba37f1c80801ee128749d4772c47f23323a3beRomain Guy if (type == WAKE_UP_ONE) { 6831ba37f1c80801ee128749d4772c47f23323a3beRomain Guy signal(); 6931ba37f1c80801ee128749d4772c47f23323a3beRomain Guy } else { 7031ba37f1c80801ee128749d4772c47f23323a3beRomain Guy broadcast(); 7131ba37f1c80801ee128749d4772c47f23323a3beRomain Guy } 7231ba37f1c80801ee128749d4772c47f23323a3beRomain Guy } 732bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Signal the condition variable, allowing all threads to continue. 742bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian void broadcast(); 752bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 762bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianprivate: 772bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREADS) 782bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_t mCond; 792bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#else 802bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian void* mState; 812bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif 822bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}; 832bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 842bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 852bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 862bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREADS) 872bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 882bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline Condition::Condition() { 892bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_init(&mCond, NULL); 902bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 912bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline Condition::Condition(int type) { 922bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian if (type == SHARED) { 932bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_condattr_t attr; 942bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_condattr_init(&attr); 952bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 962bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_init(&mCond, &attr); 972bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_condattr_destroy(&attr); 982bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian } else { 992bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_init(&mCond, NULL); 1002bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian } 1012bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1022bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline Condition::~Condition() { 1032bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_destroy(&mCond); 1042bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1052bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline status_t Condition::wait(Mutex& mutex) { 1062bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian return -pthread_cond_wait(&mCond, &mutex.mMutex); 1072bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1082bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) { 1092bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE) 1102bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian struct timespec ts; 1112bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_sec = reltime/1000000000; 1122bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_nsec = reltime%1000000000; 1132bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts); 1142bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE 1152bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian struct timespec ts; 1162bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_POSIX_CLOCKS) 1172bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian clock_gettime(CLOCK_REALTIME, &ts); 1182bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#else // HAVE_POSIX_CLOCKS 1192bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // we don't support the clocks here. 1202bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian struct timeval t; 1212bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian gettimeofday(&t, NULL); 1222bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_sec = t.tv_sec; 1232bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_nsec= t.tv_usec*1000; 1242bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // HAVE_POSIX_CLOCKS 1252bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_sec += reltime/1000000000; 1262bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_nsec+= reltime%1000000000; 1272bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian if (ts.tv_nsec >= 1000000000) { 1282bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_nsec -= 1000000000; 1292bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_sec += 1; 1302bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian } 1312bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts); 1322bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE 1332bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1342bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline void Condition::signal() { 1352bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_signal(&mCond); 1362bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1372bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline void Condition::broadcast() { 1382bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_broadcast(&mCond); 1392bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1402bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1412bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // HAVE_PTHREADS 1422bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1432bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 1442bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}; // namespace android 1452bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 1462bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1472bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // _LIBS_UTILS_CONDITON_H 148