blob: e7549b840e76ac6f55ca9648590e60524c9ffd68 [file] [log] [blame]
#include "ConcQueue.h"
#include <ctime>
#define BILLION 1E9
class QueueLock
{
ConcQueue<int> lock_queue;
int lock_taken;
int number_of_elements;
float timeout_period;
public:
QueueLock():lock_taken(0),number_of_elements(0),timeout_period(3.0)
{
}
int GetLock(char *name1)
{
struct timespec requestStart, requestEnd;
if(lock_taken != 0)
{
const QueueElement<int> *p_add = lock_queue.AddElement(0);
++number_of_elements;
const volatile int *p_spin = p_add->GetPointerToData();
clock_gettime(CLOCK_REALTIME, &requestStart);
while(*(p_spin) != 1)
{
//Spinning waiting for lock
clock_gettime(CLOCK_REALTIME, &requestEnd);
double accum = ( requestEnd.tv_sec - requestStart.tv_sec )
+ ( requestEnd.tv_nsec - requestStart.tv_nsec )
/ BILLION;
if(accum >= timeout_period)
{
break;
return (0);
}
}
}
lock_taken = 1;
return (1);
}
void ReleaseLock(char *name1)
{
QueueElement<int> *p_release = lock_queue.GetElement();
if(p_release == NULL)
{
lock_taken = 0;
}
else
{
--number_of_elements;
p_release->SetData(1);
}
}
int ForceLock(char *name1) //Use with EXTREME caution.
{
const QueueElement<int> *p_add = lock_queue.AddElementInFront(0);
const int *p_spin = p_add->GetPointerToData();
struct timespec requestStart, requestEnd;
if(lock_taken != 0)
{
clock_gettime(CLOCK_REALTIME, &requestStart);
while(*(p_spin) != 1)
{
//Spinning waiting for lock
clock_gettime(CLOCK_REALTIME, &requestEnd);
double accum = ( requestEnd.tv_sec - requestStart.tv_sec )
+ ( requestEnd.tv_nsec - requestStart.tv_nsec )
/ BILLION;
if(accum >= timeout_period)
{
break;
return (0);
}
}
}
lock_taken = 1;
return (1);
}
int CheckLockIsAcquired()
{
return (lock_taken);
}
const int* GetPointerToFlag() const
{
return (&lock_taken);
}
void SetTimeOutPeriod(float timeout_period_val)
{
timeout_period = timeout_period_val;
}
};