RSS Git Download  Clone
Raw Blame History
/*******************************************************************************
 *	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);
}