/*
 * (c) 2005 Research Group Dr. Fuhrmann, University of Karlsruhe, Germany
 * All rights reserved.
 *
 * Author:
 *         Stefan Denk <denk@ira.uka.de>
 *
 * $Id: watchdog.cc,v 1.3 2005/12/27 12:12:33 kutzner Exp $
 *
 */

// libc
#include <unistd.h>

// vidtrans
#include "watchdog.h"

watchdog::watchdog(int speedlimit) : bpsused(0), _speedlimit(speedlimit)
{
}

/**
 * upstream speed control
 * returns the amount of microseconds a subserverthread is supposed to sleep after having transmitted bytessent bytes.
 */
unsigned long watchdog::getsleeptime(ssize_t bytessent)
{
	//dsyslog("%s: begin", __PRETTY_FUNCTION__);
	unsigned long sleeptime = 0;
	ssize_t newbpsused;
	
	newbpsused = incrementbpsused(bytessent);
	sleeptime = (newbpsused * 1024) / _speedlimit;
	sleeptime = sleeptime / 1024;
	sleeptime += 1;
	return sleeptime;
}

ssize_t watchdog::incrementbpsused(ssize_t byvalue)
{
	mutex.Lock();
	bpsused += byvalue;
	mutex.Unlock();
	return bpsused;
}

ssize_t watchdog::decrementbpsused(ssize_t byvalue)
{
	mutex.Lock();
	bpsused -= byvalue;
	mutex.Unlock();
	return bpsused;
}

ssize_t watchdog::getbpsused(void)
{
	return bpsused;
}

void watchdog::Action()
{
	while(true)
	{
		sleep(1);
		if ( getbpsused() > _speedlimit ) 
		{
			decrementbpsused(_speedlimit);
		}
		else if ( (getbpsused() > 0) && (getbpsused() < _speedlimit) ) 
		{
			decrementbpsused(getbpsused());
		}
		// if (getbpsused() != 0) dsyslog("%s: upstream state: %ld bytes in queue (speedlimit %d bytes/s)", __PRETTY_FUNCTION__, long(getbpsused()), _speedlimit);
	}
}

