private static SubmissionQueue MapSq(int ringFd, size_t sqSize, io_uring_params *p, out UnmapHandle sqHandle, out UnmapHandle sqeHandle) { var ptr = mmap(NULL, sqSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, ringFd, (long)IORING_OFF_SQ_RING); if (ptr == MAP_FAILED) { ThrowErrnoException(); } sqHandle = new UnmapHandle(ptr, sqSize); size_t sqeSize = SqeSize(p); var sqePtr = mmap(NULL, sqeSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, ringFd, (long)IORING_OFF_SQES); if (sqePtr == MAP_FAILED) { ThrowErrnoException(); } sqeHandle = new UnmapHandle(sqePtr, sqeSize); return(SubmissionQueue.CreateSubmissionQueue(ptr, &p->sq_off, (io_uring_sqe *)sqePtr)); }
Ring(int entries, object?hack, RingOptions? ringOptions = default) #endif { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || !KernelVersion.Supports.IoUring) { ThrowPlatformNotSupportedException(); } if (entries < 1) { ThrowArgumentOutOfRangeException(ExceptionArgument.entries); } io_uring_params p = default; int fd = Setup((uint)entries, &p, ringOptions); _ringFd = new CloseHandle(); _ringFd.SetHandle(fd); _flags = p.flags; _features = p.features; var(sqSize, cqSize) = GetSize(&p); try { _sq = MapSq(fd, sqSize, &p, SubmissionPollingEnabled, IoPollingEnabled, out _sqHandle, out _sqeHandle); _cq = MapCq(fd, cqSize, &p, _sqHandle, IoPollingEnabled, out _cqHandle); _supportedOperations = FetchSupportedOperations(fd); } catch (ErrnoException) { // Ensure we don't leak file handles on error Dispose(); throw; } }
public override IORequest GetNextIORequest(HostInterface hostInterface, bool foldAddress, bool ignoreUnallocatedReads) { IORequest request = null; if (NextInputLine != null) { #region GenerateRequest ulong lsn = AddressOffset + ulong.Parse(NextInputLine[HostInterface.ASCIITraceAddressColumn]); uint size = uint.Parse(NextInputLine[HostInterface.ASCIITraceSizeColumn]); if (hostInterface.FTL.AddressMapper.CheckRequestAddress(_id, lsn, size, foldAddress)) { if (foldAddress) { lsn = lsn % hostInterface.FTL.AddressMapper.AddressMappingDomains[_id].LargestLSN; } if (NextInputLine[HostInterface.ASCIITraceTypeColumn] == HostInterface.ASCIITraceWriteCode)//write request in ascii traces { request = new IORequest(_id, TimeOffset + ulong.Parse(NextInputLine[HostInterface.ASCIITraceTimeColumn]), lsn, size, IORequestType.Write); ReceivedWriteRequestCount++; ReceivedRequestCount++; request.RelatedNodeInList = SubmissionQueue.AddLast(request); if (HeadRequest == null) { HeadRequest = request.RelatedNodeInList; } } else//read request in ascii traces { bool goodRead = true; if (ignoreUnallocatedReads) { if (!hostInterface.FTL.AddressMapper.CheckReadRequest(_id, lsn, size)) { goodRead = false; IgnoredRequestsCount++; } } request = new IORequest(_id, TimeOffset + ulong.Parse(NextInputLine[HostInterface.ASCIITraceTimeColumn]), lsn, size, IORequestType.Read); ReceivedReadRequestCount++; ReceivedRequestCount++; if (goodRead) { request.RelatedNodeInList = SubmissionQueue.AddLast(request); if (HeadRequest == null) { HeadRequest = request.RelatedNodeInList; } } else { request.ToBeIgnored = true; } } } #endregion #region PrepareNextRequest if (_inputFile.Peek() >= 0) { if (ReceivedRequestCount < NumberOfRequestsToGenerate) { NextInputLine = _inputFile.ReadLine().Split(HostInterface.Separator); ulong eventTime = TimeOffset + ulong.Parse(NextInputLine[HostInterface.ASCIITraceTimeColumn]); XEngineFactory.XEngine.EventList.InsertXEvent(new XEvent(eventTime, hostInterface, _id, 0)); } } else { NextInputLine = null; if (XEngineFactory.XEngine.Time < SimulationStopTime) { _inputFile.Close(); _inputFile = new StreamReader(_traceFilePath); if (_inputFile.Peek() >= 0) { NextInputLine = _inputFile.ReadLine().Split(HostInterface.Separator); thisRoundHandledRequestsCount = 0; thisRoundSumResponseTime = 0; thisRoundHandledReadRequestsCount = 0; thisRoundSumResponseTimeR = 0; thisRoundHandledWriteRequestsCount = 0; thisRoundSumResponseTimeW = 0; } CurrentReplayRound++; TimeOffset = XEngineFactory.XEngine.Time; ulong eventTime = TimeOffset + ulong.Parse(NextInputLine[HostInterface.ASCIITraceTimeColumn]); XEngineFactory.XEngine.EventList.InsertXEvent(new XEvent(eventTime, hostInterface, _id, 0)); AddressOffset = ReplayAddressOffset[CurrentReplayRound - 1]; Console.WriteLine("\n\n******************************************"); Console.WriteLine("* Round {0} of {1} execution started *", CurrentReplayRound, FlowName); Console.WriteLine("******************************************\n"); } } #endregion } return(request); }
public override IORequest GetNextIORequest(HostInterface hostInterface, bool foldAddress, bool ignoreUnallocatedReads) { ReceivedRequestCount++; IORequestType reqType = IORequestType.Write; if (randomRequestTypeGenerator.Uniform(0, 1) < readRatio) { reqType = IORequestType.Read; ReceivedReadRequestCount++; } else { ReceivedWriteRequestCount++; } ulong lsn = 0; switch (addressDistributionType) { case DistributionType.Uniform: lsn = randomAddressGenerator1.UniformULong((ulong)(_addressDistributionParam1 * AddressMappingDomain.LargestLSN) , ((ulong)_addressDistributionParam2 * AddressMappingDomain.LargestLSN)); break; case DistributionType.Normal: double templsn = randomAddressGenerator1.Normal(_addressDistributionParam1, _addressDistributionParam2); lsn = (uint)templsn; if (templsn < 0) { lsn = 0; } else if (templsn > AddressMappingDomain.LargestLSN) { lsn = AddressMappingDomain.LargestLSN; } break; case DistributionType.HotCold: if (randomHotColdRatioGenerator.Uniform(0, 1) < hotTrafficRate) { lsn = _addressDistributionParam1 + randomHotAddressGenerator.UniformULong(0, hotAddressRange); } else { lsn = randomAddressGenerator1.UniformULong(0, AddressMappingDomain.LargestLSN - hotAddressRange); if (lsn > _addressDistributionParam1) { lsn += hotAddressRange; } } break; case DistributionType.Fixed: default: throw new Exception("Unknown distribution type for address."); } uint reqSize = 0; switch (requestSizeDistributionType) { case DistributionType.Uniform: double tempReqSize = randomRequestSizeGenerator.Uniform(_requestSizeDistributionParam1Sector, _requestSizeDistributionParam2Sector); reqSize = (uint)(Math.Ceiling(tempReqSize)); if (reqSize == 0) { reqSize = 1; } break; case DistributionType.Normal: tempReqSize = randomRequestSizeGenerator.Normal(_requestSizeDistributionParam1Sector, _requestSizeDistributionParam2Sector); reqSize = (uint)(Math.Ceiling(tempReqSize)); if (tempReqSize < 0) { reqSize = 1; } break; case DistributionType.Fixed: reqSize = _requestSizeDistributionParam1Sector; break; default: throw new Exception("Uknown distribution type for requset size."); } IORequest request = new IORequest(XEngineFactory.XEngine.Time, lsn, reqSize, reqType); request.RelatedNodeInList = SubmissionQueue.AddLast(request); if (HeadRequest == null) { HeadRequest = request.RelatedNodeInList; } if (ReceivedRequestCount < NumberOfRequestsToGenerate) { nextRequetArrivalTime = XEngineFactory.XEngine.Time + (ulong)(randomTimeIntervalGenerator.Exponential(averageRequestInterArrivalTime)); if (nextRequetArrivalTime <= SimulationStopTime) { XEngineFactory.XEngine.EventList.InsertXEvent(new XEvent(nextRequetArrivalTime, hostInterface, _id, 0)); } } return(request); }