Condition.h revision 2bd99599bb9eef197e6d1ccacb9f808ebfbcc598
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 512bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Condition(); 522bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian Condition(int type); 532bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ~Condition(); 542bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Wait on the condition variable. Lock the mutex before calling. 552bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian status_t wait(Mutex& mutex); 562bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // same with relative timeout 572bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian status_t waitRelative(Mutex& mutex, nsecs_t reltime); 582bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Signal the condition variable, allowing one thread to continue. 592bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian void signal(); 602bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // Signal the condition variable, allowing all threads to continue. 612bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian void broadcast(); 622bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 632bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianprivate: 642bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREADS) 652bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_t mCond; 662bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#else 672bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian void* mState; 682bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif 692bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}; 702bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 712bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 722bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 732bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREADS) 742bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 752bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline Condition::Condition() { 762bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_init(&mCond, NULL); 772bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 782bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline Condition::Condition(int type) { 792bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian if (type == SHARED) { 802bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_condattr_t attr; 812bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_condattr_init(&attr); 822bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 832bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_init(&mCond, &attr); 842bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_condattr_destroy(&attr); 852bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian } else { 862bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_init(&mCond, NULL); 872bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian } 882bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 892bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline Condition::~Condition() { 902bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_destroy(&mCond); 912bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 922bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline status_t Condition::wait(Mutex& mutex) { 932bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian return -pthread_cond_wait(&mCond, &mutex.mMutex); 942bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 952bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) { 962bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE) 972bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian struct timespec ts; 982bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_sec = reltime/1000000000; 992bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_nsec = reltime%1000000000; 1002bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts); 1012bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE 1022bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian struct timespec ts; 1032bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#if defined(HAVE_POSIX_CLOCKS) 1042bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian clock_gettime(CLOCK_REALTIME, &ts); 1052bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#else // HAVE_POSIX_CLOCKS 1062bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian // we don't support the clocks here. 1072bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian struct timeval t; 1082bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian gettimeofday(&t, NULL); 1092bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_sec = t.tv_sec; 1102bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_nsec= t.tv_usec*1000; 1112bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // HAVE_POSIX_CLOCKS 1122bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_sec += reltime/1000000000; 1132bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_nsec+= reltime%1000000000; 1142bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian if (ts.tv_nsec >= 1000000000) { 1152bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_nsec -= 1000000000; 1162bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian ts.tv_sec += 1; 1172bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian } 1182bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts); 1192bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE 1202bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1212bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline void Condition::signal() { 1222bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_signal(&mCond); 1232bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1242bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopianinline void Condition::broadcast() { 1252bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian pthread_cond_broadcast(&mCond); 1262bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian} 1272bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1282bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // HAVE_PTHREADS 1292bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1302bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 1312bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian}; // namespace android 1322bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian// --------------------------------------------------------------------------- 1332bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian 1342bd99599bb9eef197e6d1ccacb9f808ebfbcc598Mathias Agopian#endif // _LIBS_UTILS_CONDITON_H 135