/*******************************************************************************
* 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);
}