#include <stdlib.h>
#include "csemq.hpp"
/* Constructor */
Csemq::Csemq()
{
sem = 0L;
priority = CSC_NO_THREAD;
}
/* Another Constructor */
Csemq::Csemq(long lValue)
{
sem = 1Value;
priority = CSC_NO_THREAD;
}
/* Used to return a thread for execution based on a
round-robin-like scheduling algorithm */
int Csemq::Dequeue()
{
int nTask = CSC_NO_THREAD;
long task;
long tmp;
int i;
if (sem < 0)
{
//this implements a somewhat round-robin scheduling algorithm
task = _lrotl(1, priority + 1);
tmp = sem & ~CSC_IDLE;
/* scan the semaphore queue structure bit-by-bit */
for (i = 0; i < CSC_NO_THREAD + 1; i++)
{
if (task & tmp)
break;
else
task = _lrotl(task, 1);
}
sem &= ~task;
if (sem == CSC_IDLE)
sem = 0;
if (i <= CSC_NO_THREAD)
nTask = long (i + priority + 1) % 32L;
}
priority = nTask;
return (nTask);
}
/* Used to put a thread in the semaphore queue */
void Csemq::Enqueue(int nThread)
{
if ((nThread <= CSC_NO_THREAD) || (sem <= 0))
{
sem |= (1L << nThread) | CSC_IDLE ;
}
}
/* Used to update the semaphore count by the specified
amount */
void Csemq::UpdateCount(long lValue)
{
long lTmp;
if (sem >= 0)
{
lTmp = sem + lValue;
if (lTmp >= 0)
sem = lTmp;
}
}
/* Used to return an indicator to the caller telling
it if the semaphore structure is a counter or a queue */
csemq_type Csemq::GetType()
{
csemq_type nType = CST_COUNT;
if (sem < 0)
nType = CST_QUEUE;
return (nType);
}
/* Used to get the count of a semaphore */
long Csemq::GetCount()
{
return (sem);
}
// End of File