Dateien
rocm-systems/rocclr/runtime/device/gpu/gslbe/src/rt/EventQueue.cpp
T
2014-07-04 16:17:05 -04:00

203 Zeilen
4.4 KiB
C++

#include "EventQueue.h"
#include "query/QueryObject.h"
#include "gsl_ctx.h"
EventQueue::EventQueue()
{
m_cs = NULL;
m_queueSize = c_staticQueueSize;
memset(m_queries,0,sizeof(m_queries));
memset(m_flushed,0,sizeof(m_flushed));
m_latestRetired = 0;
m_headId = m_queueSize - 1 ;
m_tail = 0;
}
EventQueue::~EventQueue()
{
for (unsigned int i = 0; i < c_staticQueueSize; i++)
{
assert(m_queries[i] == 0);
}
}
bool
EventQueue::open(gsCtx* cs, gslQueryTarget target, EQManagerConfig config, uint32 engineMask)
{
assert((config == EQManager_HIGH) || (config == EQManager_LOW));
setSlotCount((int) config);
assert((GpuEvent::InvalidID+1) % m_queueSize == 0);
m_cs = cs;
m_headId = m_queueSize - 1 ;
m_tail = 0;
m_latestRetired = 0;
m_target = target;
m_engineMask = engineMask;
for (unsigned int i = 0; i < m_queueSize; i++)
{
m_queries[i] = cs->createQuery(target);
}
return true;
}
void
EventQueue::close()
{
if (!m_cs) // the queue is unintialized.
{
return;
}
for (unsigned int i = 0; i < m_queueSize; i++)
{
m_cs->destroyQuery(m_queries[i]);
}
memset(m_queries, 0, sizeof(m_queries));
memset(m_flushed, 0, sizeof(m_flushed));
m_latestRetired = 0;
m_headId = m_queueSize - 1 ;
m_tail = 0;
m_cs = NULL;
}
void
EventQueue::begin()
{
const CALuint slot = m_headId % m_queueSize;
gslErrorCode ec = m_queries[slot]->BeginQuery(m_cs, m_target, 0, m_engineMask);
assert(ec == GSL_NO_ERROR);
m_flushed[slot] = false; // we've started a query, but it hasn't been checked yet...
}
uint32
EventQueue::end()
{
uint32 ret = m_headId;
const uint32 slot = m_headId % m_queueSize;
m_queries[slot]->EndQuery(m_cs, 0);
m_headId++;
m_tail++;
if (GpuEvent::InvalidID == m_headId)
{
// Flush on an event ID wrap around or when the Queue is going to wrap in
flush();
//roll numbers back to the beginning
m_latestRetired = 0;
m_headId = m_headId % m_queueSize;
m_tail = m_tail % m_queueSize;
}
return ret;
}
bool
EventQueue::isDone(uint32 event)
{
assert((event < GpuEvent::InvalidID) && "illegal event handle");
// if the event is older the the last known retired event we
// do not need to process it.
if (event <= m_latestRetired)
{
return true;
}
// if the event is older than the oldest event handle we have
// we synchronize with the oldest event.
if (event < m_tail)
{
return waitForEvent(m_tail, CAL_WAIT_LOW_CPU_UTILIZATION);
}
//
// If we've never called flush on the query object, go ahead flush the first time to ensure
// we never infinite loop
//
const uint32 slot = event % m_queueSize;
if (!m_flushed[slot])
{
flush();
}
//
// Since we're in between, we actually have to check to see if things are truely done
//
bool retVal = m_queries[slot]->IsResultAvailable(m_cs);
// cache the most recently retired event
if (retVal && (event < m_headId) && (event > m_latestRetired))
{
m_latestRetired = event;
}
return retVal;
}
bool
EventQueue::waitForEvent(uint32 event, uint32 waitType)
{
// if we already retired a younger event we don't to process current events
if (event <= m_latestRetired)
{
return true;
}
// if the event is older than the oldest event handle we have
// we synchronize with the oldest event
if (event < m_tail)
{
event = m_tail;
}
//
// If we've never called flush on the query object, go ahead flush the first time to ensure
// we never infinite loop
//
const uint32 slot = event % m_queueSize;
if (!m_flushed[slot])
{
flush();
}
uint64 param;
m_queries[slot]->GetResult(m_cs, &param, waitType);
// cache the most recently retired event
if ((event < m_headId) && (event > m_latestRetired))
{
m_latestRetired = event;
}
return (param != 0);
}
bool
EventQueue::flush()
{
m_cs->Flush(false, m_engineMask);
memset(m_flushed, 1, sizeof(m_flushed));
return true;
}
void
EventQueue::setSlotCount(uint32 slotCount)
{
if (slotCount < c_staticQueueSize)
{
m_queueSize = slotCount;
}
else
{
m_queueSize = c_staticQueueSize;
}
}