84 lines
1.5 KiB
C++
84 lines
1.5 KiB
C++
// Copyright 2011-2020 Molecular Matters GmbH, all rights reserved.
|
|
|
|
#if LC_VERSION == 1
|
|
|
|
// BEGIN EPIC MOD
|
|
//#include PCH_INCLUDE
|
|
// END EPIC MOD
|
|
#include "LC_SchedulerQueue.h"
|
|
|
|
|
|
scheduler::TaskQueue::TaskQueue(void)
|
|
: m_tasks()
|
|
, m_readIndex(0u)
|
|
, m_writeIndex(0u)
|
|
, m_producerSema(TASK_COUNT, TASK_COUNT)
|
|
, m_consumerSema(0u, TASK_COUNT)
|
|
, m_cs()
|
|
{
|
|
}
|
|
|
|
|
|
void scheduler::TaskQueue::PushTask(TaskBase* task)
|
|
{
|
|
// wait until there is room for the task
|
|
m_producerSema.Wait();
|
|
|
|
{
|
|
CriticalSection::ScopedLock lock(&m_cs);
|
|
|
|
m_tasks[m_writeIndex & ACCESS_MASK] = task;
|
|
++m_writeIndex;
|
|
}
|
|
|
|
// tell the consumers that there is a new task available
|
|
m_consumerSema.Signal();
|
|
}
|
|
|
|
|
|
scheduler::TaskBase* scheduler::TaskQueue::PopTask(void)
|
|
{
|
|
// wait for a task to become available
|
|
m_consumerSema.Wait();
|
|
|
|
TaskBase* task = nullptr;
|
|
{
|
|
CriticalSection::ScopedLock lock(&m_cs);
|
|
|
|
task = m_tasks[m_readIndex & ACCESS_MASK];
|
|
++m_readIndex;
|
|
}
|
|
|
|
// tell the producers that there is room for a new task
|
|
m_producerSema.Signal();
|
|
|
|
return task;
|
|
}
|
|
|
|
|
|
scheduler::TaskBase* scheduler::TaskQueue::TryPopTask(void)
|
|
{
|
|
// check if a task is available
|
|
const bool isAvailable = m_consumerSema.TryWait();
|
|
if (!isAvailable)
|
|
{
|
|
// no task yet, bail out
|
|
return nullptr;
|
|
}
|
|
|
|
TaskBase* task = nullptr;
|
|
{
|
|
CriticalSection::ScopedLock lock(&m_cs);
|
|
|
|
task = m_tasks[m_readIndex & ACCESS_MASK];
|
|
++m_readIndex;
|
|
}
|
|
|
|
// tell the producers that there is room for a new task
|
|
m_producerSema.Signal();
|
|
|
|
return task;
|
|
}
|
|
|
|
|
|
#endif |