2018-01-16 13:05:00 -05:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Wait Handler
|
|
|
|
***********************************************************************************************************************************/
|
2018-05-18 11:57:32 -04:00
|
|
|
#include "common/debug.h"
|
2018-05-23 09:45:08 -04:00
|
|
|
#include "common/log.h"
|
2018-01-16 13:05:00 -05:00
|
|
|
#include "common/memContext.h"
|
|
|
|
#include "common/wait.h"
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Contains information about the wait handler
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
struct Wait
|
|
|
|
{
|
|
|
|
MemContext *memContext; // Context that contains the wait handler
|
2018-03-21 09:18:48 -04:00
|
|
|
TimeMSec waitTime; // Total time to wait (in usec)
|
|
|
|
TimeMSec sleepTime; // Next sleep time (in usec)
|
|
|
|
TimeMSec sleepPrevTime; // Previous time slept (in usec)
|
|
|
|
TimeMSec beginTime; // Time the wait began (in epoch usec)
|
2018-01-16 13:05:00 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
New wait handler
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
Wait *
|
2018-11-08 08:37:57 -05:00
|
|
|
waitNew(TimeMSec waitTime)
|
2018-01-16 13:05:00 -05:00
|
|
|
{
|
2019-01-21 17:41:59 +02:00
|
|
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
|
|
|
FUNCTION_LOG_PARAM(TIMEMSEC, waitTime);
|
|
|
|
FUNCTION_LOG_END();
|
2018-05-18 11:57:32 -04:00
|
|
|
|
2019-01-21 17:41:59 +02:00
|
|
|
ASSERT(waitTime >= 100 && waitTime <= 999999000);
|
2018-01-16 13:05:00 -05:00
|
|
|
|
|
|
|
// Allocate wait object
|
|
|
|
Wait *this = NULL;
|
|
|
|
|
|
|
|
MEM_CONTEXT_NEW_BEGIN("wait")
|
|
|
|
{
|
|
|
|
// Create object
|
|
|
|
this = memNew(sizeof(Wait));
|
|
|
|
this->memContext = MEM_CONTEXT_NEW();
|
|
|
|
|
|
|
|
// Store time
|
2018-11-08 08:37:57 -05:00
|
|
|
this->waitTime = waitTime;
|
2018-01-16 13:05:00 -05:00
|
|
|
|
|
|
|
// Calculate first sleep time -- start with 1/10th of a second for anything >= 1 second
|
2018-03-21 09:18:48 -04:00
|
|
|
if (this->waitTime >= MSEC_PER_SEC)
|
|
|
|
this->sleepTime = MSEC_PER_SEC / 10;
|
2018-01-16 13:05:00 -05:00
|
|
|
// Unless the wait time is really small -- in that case divide wait time by 10
|
|
|
|
else
|
|
|
|
this->sleepTime = this->waitTime / 10;
|
|
|
|
|
|
|
|
// Get beginning time
|
2018-03-21 09:18:48 -04:00
|
|
|
this->beginTime = timeMSec();
|
2018-01-16 13:05:00 -05:00
|
|
|
}
|
|
|
|
MEM_CONTEXT_NEW_END();
|
|
|
|
|
2019-01-21 17:41:59 +02:00
|
|
|
FUNCTION_LOG_RETURN(WAIT, this);
|
2018-01-16 13:05:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Wait and return whether the caller has more time left
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
bool
|
|
|
|
waitMore(Wait *this)
|
|
|
|
{
|
2019-01-21 17:41:59 +02:00
|
|
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
|
|
|
FUNCTION_LOG_PARAM(WAIT, this);
|
|
|
|
FUNCTION_LOG_END();
|
2018-05-18 11:57:32 -04:00
|
|
|
|
2019-01-21 17:41:59 +02:00
|
|
|
ASSERT(this != NULL);
|
2018-05-18 11:57:32 -04:00
|
|
|
|
2018-01-16 13:05:00 -05:00
|
|
|
bool result = false;
|
|
|
|
|
|
|
|
// If sleep is 0 then the wait time has already ended
|
|
|
|
if (this->sleepTime > 0)
|
|
|
|
{
|
|
|
|
// Sleep required amount
|
2018-03-21 09:18:48 -04:00
|
|
|
sleepMSec(this->sleepTime);
|
2018-01-16 13:05:00 -05:00
|
|
|
|
|
|
|
// Get the end time
|
2018-03-21 09:18:48 -04:00
|
|
|
TimeMSec elapsedTime = timeMSec() - this->beginTime;
|
2018-01-16 13:05:00 -05:00
|
|
|
|
|
|
|
// Is there more time to go?
|
|
|
|
if (elapsedTime < this->waitTime)
|
|
|
|
{
|
|
|
|
// Calculate sleep time as a sum of current and last (a Fibonacci-type sequence)
|
2018-03-21 09:18:48 -04:00
|
|
|
TimeMSec sleepNextTime = this->sleepTime + this->sleepPrevTime;
|
2018-01-16 13:05:00 -05:00
|
|
|
|
|
|
|
// Make sure sleep time does not go beyond end time (this won't be negative because of the if condition above)
|
|
|
|
if (sleepNextTime > this->waitTime - elapsedTime)
|
|
|
|
sleepNextTime = this->waitTime - elapsedTime;
|
|
|
|
|
|
|
|
// Store new sleep times
|
|
|
|
this->sleepPrevTime = this->sleepTime;
|
|
|
|
this->sleepTime = sleepNextTime;
|
|
|
|
}
|
|
|
|
// Else set sleep to zero so next call will return false
|
|
|
|
else
|
|
|
|
this->sleepTime = 0;
|
|
|
|
|
|
|
|
// Need to wait more
|
|
|
|
result = true;
|
|
|
|
}
|
|
|
|
|
2019-01-21 17:41:59 +02:00
|
|
|
FUNCTION_LOG_RETURN(BOOL, result);
|
2018-01-16 13:05:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Free the wait
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
void
|
|
|
|
waitFree(Wait *this)
|
|
|
|
{
|
2019-01-21 17:41:59 +02:00
|
|
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
|
|
|
FUNCTION_LOG_PARAM(WAIT, this);
|
|
|
|
FUNCTION_LOG_END();
|
2018-05-18 11:57:32 -04:00
|
|
|
|
2018-04-03 12:25:21 -04:00
|
|
|
if (this != NULL)
|
|
|
|
memContextFree(this->memContext);
|
2018-05-18 11:57:32 -04:00
|
|
|
|
2019-01-21 17:41:59 +02:00
|
|
|
FUNCTION_LOG_RETURN_VOID();
|
2018-01-16 13:05:00 -05:00
|
|
|
}
|