in IORequestGenerator/IORequestGenerator.cpp [596:719]
static bool issueNextIO(ThreadParameters *p, IORequest *pIORequest, DWORD *pdwBytesTransferred, bool useCompletionRoutines)
{
OVERLAPPED *pOverlapped = pIORequest->GetOverlapped();
Target *pTarget = pIORequest->GetCurrentTarget();
size_t iTarget = pTarget - &p->vTargets[0];
UINT32 iRequest = pIORequest->GetRequestIndex();
LARGE_INTEGER li;
BOOL rslt = true;
//
// Compute next IO
//
p->vTargetStates[iTarget].NextIORequest(*pIORequest);
li.LowPart = pIORequest->GetOverlapped()->Offset;
li.HighPart = pIORequest->GetOverlapped()->OffsetHigh;
if (TraceLoggingProviderEnabled(g_hEtwProvider,
TRACE_LEVEL_VERBOSE,
DISKSPD_TRACE_IO))
{
GUID ActivityId = p->NextActivityId();
pIORequest->SetActivityId(ActivityId);
TraceLoggingWriteActivity(g_hEtwProvider,
"DiskSpd IO",
&ActivityId,
NULL,
TraceLoggingKeyword(DISKSPD_TRACE_IO),
TraceLoggingOpcode(EVENT_TRACE_TYPE_START),
TraceLoggingLevel(TRACE_LEVEL_VERBOSE),
TraceLoggingUInt32(p->ulThreadNo, "Thread"),
TraceLoggingString(pIORequest->GetIoType() == IOOperation::ReadIO ? "Read" : "Write", "IO Type"),
TraceLoggingUInt64(iTarget, "Target"),
TraceLoggingInt32(pTarget->GetBlockSizeInBytes(), "Block Size"),
TraceLoggingInt64(li.QuadPart, "Offset"));
}
#if 0
PrintError("t[%u:%u] issuing %u %s @ %I64u)\n", p->ulThreadNo, iTarget,
pTarget->GetBlockSizeInBytes(),
(pIORequest->GetIoType() == IOOperation::ReadIO ? "read" : "write"),
li.QuadPart);
#endif
if (p->pTimeSpan->GetMeasureLatency())
{
pIORequest->SetStartTime(PerfTimer::GetTime());
}
if (pIORequest->GetIoType() == IOOperation::ReadIO)
{
if (pTarget->GetMemoryMappedIoMode() == MemoryMappedIoMode::On)
{
if (pTarget->GetWriteThroughMode() == WriteThroughMode::On )
{
g_pfnRtlCopyMemoryNonTemporal(p->GetReadBuffer(iTarget, iRequest), pTarget->GetMappedView() + li.QuadPart, pTarget->GetBlockSizeInBytes());
}
else
{
memcpy(p->GetReadBuffer(iTarget, iRequest), pTarget->GetMappedView() + li.QuadPart, pTarget->GetBlockSizeInBytes());
}
*pdwBytesTransferred = pTarget->GetBlockSizeInBytes();
}
else
{
if (useCompletionRoutines)
{
rslt = ReadFileEx(p->vhTargets[iTarget], p->GetReadBuffer(iTarget, iRequest), pTarget->GetBlockSizeInBytes(), pOverlapped, fileIOCompletionRoutine);
}
else
{
rslt = ReadFile(p->vhTargets[iTarget], p->GetReadBuffer(iTarget, iRequest), pTarget->GetBlockSizeInBytes(), pdwBytesTransferred, pOverlapped);
}
}
}
else
{
if (pTarget->GetMemoryMappedIoMode() == MemoryMappedIoMode::On)
{
if (pTarget->GetWriteThroughMode() == WriteThroughMode::On)
{
g_pfnRtlCopyMemoryNonTemporal(pTarget->GetMappedView() + li.QuadPart, p->GetWriteBuffer(iTarget, iRequest), pTarget->GetBlockSizeInBytes());
}
else
{
memcpy(pTarget->GetMappedView() + li.QuadPart, p->GetWriteBuffer(iTarget, iRequest), pTarget->GetBlockSizeInBytes());
switch (pTarget->GetMemoryMappedIoFlushMode())
{
case MemoryMappedIoFlushMode::ViewOfFile:
FlushViewOfFile(pTarget->GetMappedView() + li.QuadPart, pTarget->GetBlockSizeInBytes());
break;
case MemoryMappedIoFlushMode::NonVolatileMemory:
g_pfnRtlFlushNonVolatileMemory(pTarget->GetMemoryMappedIoNvToken(), pTarget->GetMappedView() + li.QuadPart, pTarget->GetBlockSizeInBytes(), 0);
break;
case MemoryMappedIoFlushMode::NonVolatileMemoryNoDrain:
g_pfnRtlFlushNonVolatileMemory(pTarget->GetMemoryMappedIoNvToken(), pTarget->GetMappedView() + li.QuadPart, pTarget->GetBlockSizeInBytes(), FLUSH_NV_MEMORY_IN_FLAG_NO_DRAIN);
break;
}
}
*pdwBytesTransferred = pTarget->GetBlockSizeInBytes();
}
else
{
if (useCompletionRoutines)
{
rslt = WriteFileEx(p->vhTargets[iTarget], p->GetWriteBuffer(iTarget, iRequest), pTarget->GetBlockSizeInBytes(), pOverlapped, fileIOCompletionRoutine);
}
else
{
rslt = WriteFile(p->vhTargets[iTarget], p->GetWriteBuffer(iTarget, iRequest), pTarget->GetBlockSizeInBytes(), pdwBytesTransferred, pOverlapped);
}
}
}
if (p->vThroughputMeters.size() != 0 && p->vThroughputMeters[iTarget].IsRunning())
{
p->vThroughputMeters[iTarget].Adjust(pTarget->GetBlockSizeInBytes());
}
return (rslt) ? true : false;
}