/******************************************************************************* * BCondInt.cc BCondBool Classes * T.Barnaby, BEAM Ltd, 10/12/02 ******************************************************************************* */ #include <BCondInt.h> #include <sys/time.h> #include <stdio.h> #include <errno.h> BCondValue::BCondValue(){ pthread_mutex_init(&omutex, 0); pthread_cond_init(&ocond, 0); ovalue = 0; } BCondValue::~BCondValue(){ pthread_cond_destroy(&ocond); pthread_mutex_destroy(&omutex); } void BCondValue::setValue(int value){ pthread_mutex_lock(&omutex); ovalue = value; pthread_cond_broadcast(&ocond); pthread_mutex_unlock(&omutex); } int BCondValue::value(){ return ovalue; } int BCondValue::increment(int v){ int ret; pthread_mutex_lock(&omutex); ovalue += v; ret = ovalue; pthread_cond_broadcast(&ocond); pthread_mutex_unlock(&omutex); return ret; } int BCondValue::decrement(int v){ int ret; pthread_mutex_lock(&omutex); ovalue -= v; ret = ovalue; pthread_cond_broadcast(&ocond); pthread_mutex_unlock(&omutex); return ret; } int BCondValue::waitMoreThanOrEqual(int v, int decrement, int timeOutUs){ int ret = 0; struct timeval tv; struct timespec ts; pthread_mutex_lock(&omutex); if(timeOutUs){ gettimeofday(&tv, 0); ts.tv_sec = tv.tv_sec + (tv.tv_usec + timeOutUs) / 1000000; ts.tv_nsec = ((tv.tv_usec + timeOutUs) % 1000000) * 1000; while(!ret && (ovalue < v)) ret = pthread_cond_timedwait(&ocond, &omutex, &ts); } else { while(ovalue < v) pthread_cond_wait(&ocond, &omutex); } if(ret == 0) ovalue -= decrement; pthread_mutex_unlock(&omutex); return ret; } int BCondValue::waitLessThanOrEqual(int v, int increment, int timeOutUs){ int ret = 0; struct timeval tv; struct timespec ts; pthread_mutex_lock(&omutex); if(timeOutUs){ gettimeofday(&tv, 0); ts.tv_sec = tv.tv_sec + (tv.tv_usec + timeOutUs) / 1000000; ts.tv_nsec = ((tv.tv_usec + timeOutUs) % 1000000) * 1000; while(!ret && (ovalue > v)) ret = pthread_cond_timedwait(&ocond, &omutex, &ts); } else { while(ovalue > v) pthread_cond_wait(&ocond, &omutex); } if(ret == 0) ovalue += increment; pthread_mutex_unlock(&omutex); return ret; } int BCondValue::waitLessThan(int v, int timeOutUs){ int ret = 0; struct timeval tv; struct timespec ts; pthread_mutex_lock(&omutex); if(timeOutUs){ gettimeofday(&tv, 0); ts.tv_sec = tv.tv_sec + (tv.tv_usec + timeOutUs) / 1000000; ts.tv_nsec = ((tv.tv_usec + timeOutUs) % 1000000) * 1000; while(!ret && (ovalue >= v)) ret = pthread_cond_timedwait(&ocond, &omutex, &ts); } else { while(ovalue >= v) pthread_cond_wait(&ocond, &omutex); } pthread_mutex_unlock(&omutex); return ret; } BCondInt::BCondInt(){ pthread_mutex_init(&omutex, 0); pthread_cond_init(&ocond, 0); ovalue = 0; } BCondInt::~BCondInt(){ pthread_cond_destroy(&ocond); pthread_mutex_destroy(&omutex); } void BCondInt::setValue(int value){ pthread_mutex_lock(&omutex); ovalue = value; pthread_cond_broadcast(&ocond); pthread_mutex_unlock(&omutex); } int BCondInt::increment(){ int ret; pthread_mutex_lock(&omutex); ret = ++ovalue; pthread_cond_broadcast(&ocond); pthread_mutex_unlock(&omutex); return ret; } int BCondInt::decrement(){ int ret; pthread_mutex_lock(&omutex); ret = --ovalue; if(ovalue <= 0) pthread_cond_broadcast(&ocond); pthread_mutex_unlock(&omutex); return ret; } int BCondInt::value(){ return ovalue; } int BCondInt::wait(){ int ret = 0; pthread_mutex_lock(&omutex); while(ovalue > 0) ret = pthread_cond_wait(&ocond, &omutex); pthread_mutex_unlock(&omutex); return ret; } int BCondInt::waitIncrement(int timeOutUs){ int ret = 0; struct timeval tv; struct timespec ts; pthread_mutex_lock(&omutex); if(timeOutUs){ gettimeofday(&tv, 0); ts.tv_sec = tv.tv_sec + (tv.tv_usec + timeOutUs) / 1000000; ts.tv_nsec = ((tv.tv_usec + timeOutUs) % 1000000) * 1000; while(!ret && (ovalue > 0)) ret = pthread_cond_timedwait(&ocond, &omutex, &ts); if(!ret) ovalue++; } else { while(ovalue > 0) pthread_cond_wait(&ocond, &omutex); ovalue++; } pthread_mutex_unlock(&omutex); return ret; } int BCondInt::waitNotZero(){ int ret = 0; pthread_mutex_lock(&omutex); while(ovalue <= 0) ret = pthread_cond_wait(&ocond, &omutex); pthread_mutex_unlock(&omutex); return ret; } int BCondInt::waitNotZeroDecrement(){ int ret = 0; pthread_mutex_lock(&omutex); while(ovalue <= 0) ret = pthread_cond_wait(&ocond, &omutex); ovalue--; pthread_mutex_unlock(&omutex); return ret; } int BCondInt::tryNotZeroDecrement(){ int ret = 1; pthread_mutex_lock(&omutex); if(ovalue > 0){ ret = 0; ovalue--; } pthread_mutex_unlock(&omutex); return ret; } int BCondInt::timedWait(int timeOutUs){ int ret = 0; struct timeval tv; struct timespec ts; gettimeofday(&tv, 0); ts.tv_sec = tv.tv_sec + (tv.tv_usec + timeOutUs) / 1000000; ts.tv_nsec = ((tv.tv_usec + timeOutUs) % 1000000) * 1000; pthread_mutex_lock(&omutex); while(ovalue > 0){ ret = pthread_cond_timedwait(&ocond, &omutex, &ts); if(ret == ETIMEDOUT) break; } pthread_mutex_unlock(&omutex); return ret; } BCondBool::BCondBool(){ pthread_mutex_init(&omutex, 0); pthread_cond_init(&ocond, 0); ovalue = 0; } BCondBool::~BCondBool(){ pthread_cond_destroy(&ocond); pthread_mutex_destroy(&omutex); } int BCondBool::set(){ int ret; pthread_mutex_lock(&omutex); ret = ovalue = 1; pthread_cond_broadcast(&ocond); pthread_mutex_unlock(&omutex); return ret; } int BCondBool::clear(){ int ret; pthread_mutex_lock(&omutex); ret = ovalue = 0; pthread_mutex_unlock(&omutex); return ret; } int BCondBool::value(){ return ovalue; } int BCondBool::wait(){ int ret = 0; pthread_mutex_lock(&omutex); while(ovalue != 1) ret = pthread_cond_wait(&ocond, &omutex); pthread_mutex_unlock(&omutex); return ret; } int BCondBool::timedWait(int timeOutUs){ int ret = 0; struct timeval tv; struct timespec ts; gettimeofday(&tv, 0); ts.tv_sec = tv.tv_sec + timeOutUs / 1000000; ts.tv_nsec = (tv.tv_usec + timeOutUs % 1000000) * 1000; ts.tv_sec += (ts.tv_nsec / 1000000000); ts.tv_nsec %= 1000000000; pthread_mutex_lock(&omutex); while(ovalue != 1){ ret = pthread_cond_timedwait(&ocond, &omutex, &ts); if(ret == ETIMEDOUT) break; } pthread_mutex_unlock(&omutex); return ret; } BCondWrap::BCondWrap(){ pthread_mutex_init(&omutex, 0); pthread_cond_init(&ocond, 0); ovalue = 0; } BCondWrap::~BCondWrap(){ pthread_cond_destroy(&ocond); pthread_mutex_destroy(&omutex); } void BCondWrap::setValue(uint32_t value){ pthread_mutex_lock(&omutex); ovalue = value; pthread_cond_broadcast(&ocond); pthread_mutex_unlock(&omutex); } uint32_t BCondWrap::value(){ return ovalue; } uint32_t BCondWrap::increment(uint32_t v){ int ret; pthread_mutex_lock(&omutex); ovalue += v; ret = ovalue; pthread_cond_broadcast(&ocond); pthread_mutex_unlock(&omutex); return ret; } uint32_t BCondWrap::decrement(uint32_t v){ int ret; pthread_mutex_lock(&omutex); ovalue -= v; ret = ovalue; pthread_cond_broadcast(&ocond); pthread_mutex_unlock(&omutex); return ret; } int BCondWrap::waitMoreThanOrEqual(uint32_t v, uint32_t decrement, uint32_t timeOutUs){ int ret = 0; struct timeval tv; struct timespec ts; pthread_mutex_lock(&omutex); if(timeOutUs){ gettimeofday(&tv, 0); ts.tv_sec = tv.tv_sec + (tv.tv_usec + timeOutUs) / 1000000; ts.tv_nsec = ((tv.tv_usec + timeOutUs) % 1000000) * 1000; while(!ret && (diff(v) < 0)) ret = pthread_cond_timedwait(&ocond, &omutex, &ts); } else { while(diff(v) < 0) pthread_cond_wait(&ocond, &omutex); } if(ret == 0) ovalue -= decrement; pthread_mutex_unlock(&omutex); return ret; } int BCondWrap::waitLessThanOrEqual(uint32_t v, uint32_t increment, uint32_t timeOutUs){ int ret = 0; struct timeval tv; struct timespec ts; pthread_mutex_lock(&omutex); if(timeOutUs){ gettimeofday(&tv, 0); ts.tv_sec = tv.tv_sec + (tv.tv_usec + timeOutUs) / 1000000; ts.tv_nsec = ((tv.tv_usec + timeOutUs) % 1000000) * 1000; while(!ret && (diff(v) > 0)) ret = pthread_cond_timedwait(&ocond, &omutex, &ts); } else { while(diff(v) > 0) pthread_cond_wait(&ocond, &omutex); } if(ret == 0) ovalue += increment; pthread_mutex_unlock(&omutex); return ret; } int BCondWrap::waitLessThan(uint32_t v, uint32_t timeOutUs){ int ret = 0; struct timeval tv; struct timespec ts; pthread_mutex_lock(&omutex); if(timeOutUs){ gettimeofday(&tv, 0); ts.tv_sec = tv.tv_sec + (tv.tv_usec + timeOutUs) / 1000000; ts.tv_nsec = ((tv.tv_usec + timeOutUs) % 1000000) * 1000; while(!ret && (diff(v) >= 0)) ret = pthread_cond_timedwait(&ocond, &omutex, &ts); } else { while(diff(v) >= 0) pthread_cond_wait(&ocond, &omutex); } pthread_mutex_unlock(&omutex); return ret; } int BCondWrap::diff(uint32_t v){ return (ovalue - v); }