Example #1
0
        public override void ProcessXEvent(XEvent e)
        {
            switch ((HostInterfaceEventType)e.Type)
            {
            case HostInterfaceEventType.GenerateNextIORequest:
                if (XEngineFactory.XEngine.Time >= SimulationStopTime)
                {
                    Finished = true;
                }
                uint      streamID = (uint)e.Parameters;
                IORequest request  = _inputStreams[streamID].GetNextIORequest(this, foldAddress, ignoreUnallocatedReads);
                ReceivedRequestCount++;
                if (request.Type == IORequestType.Write)    //write request in ascii traces
                {
                    ReceivedWriteRequestCount++;
                }
                else    //read request in ascii traces
                {
                    ReceivedReadRequestCount++;
                }
                if (request.ToBeIgnored)
                {
                    ignoredRequestsCount++;
                }
                else
                {
                    OnIORequestArrived(streamID);
                }
                break;

            case HostInterfaceEventType.RequestCompletedByDRAM:
                IORequest targetRequest = e.Parameters as IORequest;
                SendEarlyResponseToHost(targetRequest);
                break;

            default:
                throw new Exception("Unhandled XEvent type");
            }
        }
Example #2
0
        private void SegmentIORequestNoCache(IORequest currentRequest)
        {
            ulong lsn     = currentRequest.LSN;
            uint  reqSize = currentRequest.SizeInSubpages;

            uint subState = 0;
            uint handledSize = 0, subSize = 0;

            while (handledSize < reqSize)
            {
                lsn     = lsn % myFTL.AddressMapper.LargestLSN;
                subSize = myFTL.SubpageNoPerPage - (uint)(lsn % myFTL.SubpageNoPerPage);
                if (handledSize + subSize >= reqSize)
                {
                    subSize      = reqSize - handledSize;
                    handledSize += subSize;
                }
                ulong lpn = lsn / myFTL.SubpageNoPerPage;
                subState = myFTL.SetEntryState(lsn, subSize);
                createFlashOperationRequest(lpn, subSize, subState, currentRequest);
                lsn          = lsn + subSize;
                handledSize += subSize;
            }

            if (currentRequest.InternalRequestList.Count == 0)
            {
                myHI.SendEarlyResponseToHost(currentRequest);
            }

            /*try to estimate the execution time of each flash transaction separately*/
            foreach (InternalRequest ir in currentRequest.InternalRequestList)
            {
                uint queueID = ir.TargetPageAddress.ChannelID;
                if (queueID == uint.MaxValue)
                {
                    throw new Exception("Current implementation does not support dynamic channel allocation!");
                }
            }
        }
        public override IORequest SaturatedMode_GetNextRequest()
        {
            if (ReceivedRequestCount == numberOfRequestsToBeSeen)
            {
                return(null);
            }

            ulong lsn = 0;

            switch (addressDistributionType)
            {
            case InputStreamSynthetic.DistributionType.Uniform:
                lsn = randomAddressGenerator1.UniformULong(addressDistributionParam1, addressDistributionParam2);
                break;

            case InputStreamSynthetic.DistributionType.Normal:
                double templsn = randomAddressGenerator1.Normal(addressDistributionParam1, addressDistributionParam2);
                lsn = (uint)templsn;
                if (templsn < 0)
                {
                    lsn = 0;
                }
                else if (templsn > this.FTL.AddressMapper.LargestLSN)
                {
                    lsn = this.FTL.AddressMapper.LargestLSN;
                }
                break;

            case InputStreamSynthetic.DistributionType.Fixed:
                lsn = addressDistributionParam1;
                break;

            case InputStreamSynthetic.DistributionType.HotCold:
                if (randomHotColdRatioGenerator.Uniform(0, 1) < hotTrafficRate)
                {
                    lsn = addressDistributionParam1 + randomHotAddressGenerator.UniformULong(0, hotAddressRange);
                }
                else
                {
                    lsn = randomAddressGenerator1.UniformULong(0, this.FTL.AddressMapper.LargestLSN - hotAddressRange);
                    if (lsn > addressDistributionParam1)
                    {
                        lsn += hotAddressRange;
                    }
                }
                break;

            default:
                throw new Exception("Unknown distribution type for address.");
            }

            uint reqSize = 0;

            switch (requestSizeDistributionType)
            {
            case InputStreamSynthetic.DistributionType.Uniform:
                double tempReqSize = randomRequestSizeGenerator.Uniform(requestSizeDistributionParam1B, requestSizeDistributionParam2B);
                reqSize = (uint)(Math.Ceiling(tempReqSize / (double)FTL.SubPageCapacity));
                if (reqSize == 0)
                {
                    reqSize = 1;
                }
                break;

            case InputStreamSynthetic.DistributionType.Normal:
                tempReqSize = randomRequestSizeGenerator.Normal(requestSizeDistributionParam1B, requestSizeDistributionParam2B);
                reqSize     = (uint)(Math.Ceiling(tempReqSize / (double)FTL.SubPageCapacity));
                if (tempReqSize < 0)
                {
                    reqSize = 1;
                }
                break;

            case InputStreamSynthetic.DistributionType.Fixed:
                reqSize = (uint)(Math.Ceiling(requestSizeDistributionParam1B / (double)FTL.SubPageCapacity));
                break;

            default:
                throw new Exception("Uknown distribution type for requset size.");
            }
            IORequest request = null;

            if (randomRequestTypeGenerator.Uniform(0, 1) < readRatio)
            {
                request = new IORequest(XEngineFactory.XEngine.Time, lsn, reqSize, IORequestType.Read);
                ReceivedReadRequestCount++;
            }
            else
            {
                request = new IORequest(XEngineFactory.XEngine.Time, lsn, reqSize, IORequestType.Write);
                ReceivedWriteRequestCount++;
            }

            ReceivedRequestCount++;
            if (ReceivedRequestCount == numberOfRequestsToBeSeen)
            {
                reqExists = false;
            }

            request.RelatedNodeInList = NCQ.AddLast(request);

            return(request);
        }
        public override void ProcessXEvent(XEvent e)
        {
            switch ((HostInterfaceEventType)e.Type)
            {
            case HostInterfaceEventType.GenerateNextIORequest:
                IORequest request = null;

                IORequestType reqType = IORequestType.Write;
                if (randomRequestTypeGenerator.Uniform(0, 1) < readRatio)
                {
                    reqType = IORequestType.Read;
                    ReceivedReadRequestCount++;
                }
                else
                {
                    ReceivedWriteRequestCount++;
                }


                ulong lsn = 0;
                switch (addressDistributionType)
                {
                case InputStreamSynthetic.DistributionType.Uniform:
                    lsn = randomAddressGenerator1.UniformULong(addressDistributionParam1, addressDistributionParam2);
                    break;

                case InputStreamSynthetic.DistributionType.Normal:
                    double templsn = randomAddressGenerator1.Normal(addressDistributionParam1, addressDistributionParam2);
                    lsn = (uint)templsn;
                    if (templsn < 0)
                    {
                        lsn = 0;
                    }
                    else if (templsn > this.FTL.AddressMapper.LargestLSN)
                    {
                        lsn = this.FTL.AddressMapper.LargestLSN;
                    }
                    break;

                case InputStreamSynthetic.DistributionType.Fixed:
                    lsn = addressDistributionParam1;
                    break;

                case InputStreamSynthetic.DistributionType.HotCold:
                    if (randomHotColdRatioGenerator.Uniform(0, 1) < hotTrafficRate)
                    {
                        lsn = addressDistributionParam1 + randomHotAddressGenerator.UniformULong(0, hotAddressRange);
                    }
                    else
                    {
                        lsn = randomAddressGenerator1.UniformULong(0, this.FTL.AddressMapper.LargestLSN - hotAddressRange);
                        if (lsn > addressDistributionParam1)
                        {
                            lsn += hotAddressRange;
                        }
                    }
                    break;

                default:
                    throw new Exception("Unknown distribution type for address.");
                }

                uint reqSize = 0;
                switch (requestSizeDistributionType)
                {
                case InputStreamSynthetic.DistributionType.Uniform:
                    double tempReqSize = randomRequestSizeGenerator.Uniform(requestSizeDistributionParam1B, requestSizeDistributionParam2B);
                    reqSize = (uint)(Math.Ceiling(tempReqSize / (double)FTL.SubPageCapacity));
                    if (reqSize == 0)
                    {
                        reqSize = 1;
                    }
                    break;

                case InputStreamSynthetic.DistributionType.Normal:
                    tempReqSize = randomRequestSizeGenerator.Normal(requestSizeDistributionParam1B, requestSizeDistributionParam2B);
                    reqSize     = (uint)(Math.Ceiling(tempReqSize / (double)FTL.SubPageCapacity));
                    if (tempReqSize < 0)
                    {
                        reqSize = 1;
                    }
                    break;

                case InputStreamSynthetic.DistributionType.Fixed:
                    reqSize = (uint)(Math.Ceiling(requestSizeDistributionParam1B / (double)FTL.SubPageCapacity));
                    break;

                default:
                    throw new Exception("Uknown distribution type for requset size.");
                }

                request = new IORequest(XEngineFactory.XEngine.Time, lsn, reqSize, reqType);

                ReceivedRequestCount++;
                if (NCQ.Count < NCQSize)
                {
                    request.RelatedNodeInList = NCQ.AddLast(request);
                    SegmentIORequestNoCache_Sprinkler(request);
                    FTL.IOScheduler.Schedule((uint)StreamPriorityClass.Urgent, AddressMappingModule.DefaultStreamID);
                    //FTL.ServiceIORequest();
                }
                else
                {
                    HostQueue.AddLast(request);
                }

                if (ReceivedRequestCount < numberOfRequestsToBeSeen)
                {
                    nextRequetArrivalTime = XEngineFactory.XEngine.Time + (ulong)(randomTimeIntervalGenerator.Exponential(averageRequestInterArrivalTime));
                    XEngineFactory.XEngine.EventList.InsertXEvent(new XEvent(nextRequetArrivalTime, this, null, 0));
                }
                break;

            case HostInterfaceEventType.RequestCompletedByDRAM:
                IORequest targetRequest = e.Parameters as IORequest;
                SendEarlyResponseToHost(targetRequest);
                break;

            default:
                throw new Exception("Unhandled XEvent type");
            }
        }
Example #5
0
        private void createFlashOperationRequest(ulong lpn, uint sizeInSubpages, uint state, IORequest currentIORequest)
        {
            if (currentIORequest.Type == IORequestType.Read)
            {
                InternalReadRequest subRequest = new InternalReadRequest();
                myFTL.TotalPageReads++;
                myFTL.PageReadsForWorkload++;
                if (myFTL.AddressMapper.AddressMappingDomains[currentIORequest.StreamID].MappingTable.State[lpn] == 0)
                {
                    for (var LPN = myFTL.currentActiveWriteLPNs[currentIORequest.StreamID].First; LPN != null; LPN = LPN.Next)
                    {
                        if (LPN.Value == lpn)
                        {
                            return;
                        }
                    }
                    throw new Exception("Accessing an unwritten logical address for read!");
                }

                myFTL.AddressMapper.ConvertPPNToPageAddress(myFTL.AddressMapper.AddressMappingDomains[currentIORequest.StreamID].MappingTable.PPN[lpn], subRequest.TargetPageAddress);
                subRequest.TargetFlashChip    = myFTL.FlashChips[subRequest.TargetPageAddress.OverallFlashChipID];
                subRequest.LPN                = lpn;
                subRequest.PPN                = myFTL.AddressMapper.AddressMappingDomains[currentIORequest.StreamID].MappingTable.PPN[lpn];
                subRequest.SizeInSubpages     = sizeInSubpages;
                subRequest.SizeInByte         = sizeInSubpages * FTL.SubPageCapacity;
                subRequest.BodyTransferCycles = subRequest.SizeInByte / FTL.ChannelWidthInByte;

                subRequest.State            = (myFTL.AddressMapper.AddressMappingDomains[currentIORequest.StreamID].MappingTable.State[lpn] & 0x7fffffff);
                subRequest.Type             = InternalRequestType.Read;
                subRequest.RelatedIORequest = currentIORequest;

                //Arash: I have omitted a section of original code to ignore simultaneous read of same memory location

                currentIORequest.InternalRequestList.AddLast(subRequest);
            }
            else //currentRequest.Type == IORequestType.Write
            {
                InternalWriteRequest subRequest = new InternalWriteRequest();
                myFTL.currentActiveWriteLPNs[currentIORequest.StreamID].AddLast(lpn);
                myFTL.TotalPageProgams++;
                myFTL.PageProgramsForWorkload++;
                subRequest.LPN                = lpn;
                subRequest.PPN                = 0;
                subRequest.SizeInSubpages     = sizeInSubpages;
                subRequest.SizeInByte         = sizeInSubpages * FTL.SubPageCapacity;
                subRequest.BodyTransferCycles = subRequest.SizeInByte / FTL.ChannelWidthInByte;
                subRequest.State              = state;
                subRequest.Type               = InternalRequestType.Write;
                subRequest.RelatedIORequest   = currentIORequest;
                //The above line should be positioned before AllocateLocation.
                AllocatePlaneToWriteTransaction(subRequest);
                currentIORequest.InternalRequestList.AddLast(subRequest);
            }
        }
Example #6
0
        public void Segment(uint streamID)
        {
            if (Locked)
            {
                return;
            }

            Locked = true;
            while (myHandler.Flows[streamID].DeviceInternalQueue.Count > 0)
            {
                IORequest currentRequest = myHandler.Flows[streamID].DeviceInternalQueue.First.Value;
                myHandler.Flows[streamID].DeviceInternalQueue.RemoveFirst();
                SegmentIORequestNoCache(currentRequest);
                IntegerPageAddress addr = null;
                foreach (InternalRequest ir in currentRequest.InternalRequestList)
                {
                    addr = ir.TargetPageAddress;
                    if (ir.Type == InternalRequestType.Read)
                    {
                        if (!myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests.ContainsKey(currentRequest))
                        {
                            myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests.Add(currentRequest, 1);
                        }
                        else
                        {
                            myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests[currentRequest] = ((int)myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests[currentRequest]) + 1;
                        }
                        if (!myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests.ContainsKey(currentRequest))
                        {
                            myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests.Add(currentRequest, 1);
                        }
                        else
                        {
                            myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests[currentRequest]
                                = ((int)myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests[currentRequest]) + 1;
                        }
                        if (!myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests.ContainsKey(currentRequest))
                        {
                            myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests.Add(currentRequest, 1);
                        }
                        else
                        {
                            myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests[currentRequest]
                                = ((int)myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests[currentRequest]) + 1;
                        }

                        myHandler.Flows[streamID].ReadQueue.AddLast(ir as InternalReadRequest);
                        myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadCount++;
                        myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadCount++;
                        myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadCount++;
                    }
                    else
                    {
                        if (!myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingWriteRequests.ContainsKey(currentRequest))
                        {
                            myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingWriteRequests.Add(currentRequest, 1);
                        }
                        else
                        {
                            myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingWriteRequests[currentRequest] = ((int)myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingWriteRequests[currentRequest]) + 1;
                        }
                        if (!myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingWriteRequests.ContainsKey(currentRequest))
                        {
                            myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingWriteRequests.Add(currentRequest, 1);
                        }
                        else
                        {
                            myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingWriteRequests[currentRequest]
                                = ((int)myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingWriteRequests[currentRequest]) + 1;
                        }
                        if (!myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingWriteRequests.ContainsKey(currentRequest))
                        {
                            myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingWriteRequests.Add(currentRequest, 1);
                        }
                        else
                        {
                            myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingWriteRequests[currentRequest]
                                = ((int)myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingWriteRequests[currentRequest]) + 1;
                        }

                        myHandler.Flows[streamID].WriteQueue.AddLast(ir as InternalWriteRequest);
                        myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingWriteCount++;
                        myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingWriteCount++;
                        myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingWriteCount++;
                        if ((ir as InternalWriteRequest).UpdateRead != null)
                        {
                            addr = (ir as InternalWriteRequest).UpdateRead.TargetPageAddress;
                            if (!myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests.ContainsKey(currentRequest))
                            {
                                myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests.Add(currentRequest, 1);
                            }
                            else
                            {
                                myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests[currentRequest] = ((int)myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadRequests[currentRequest]) + 1;
                            }
                            if (!myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests.ContainsKey(currentRequest))
                            {
                                myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests.Add(currentRequest, 1);
                            }
                            else
                            {
                                myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests[currentRequest]
                                    = ((int)myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadRequests[currentRequest]) + 1;
                            }
                            if (!myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests.ContainsKey(currentRequest))
                            {
                                myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests.Add(currentRequest, 1);
                            }
                            else
                            {
                                myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests[currentRequest]
                                    = ((int)myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadRequests[currentRequest]) + 1;
                            }

                            myHandler.Flows[streamID].ReadQueue.AddLast((ir as InternalWriteRequest).UpdateRead);
                            myFTL.ResourceAccessTable.ChannelEntries[addr.ChannelID].WaitingReadCount++;
                            myFTL.ResourceAccessTable.DieEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID].WaitingReadCount++;
                            myFTL.ResourceAccessTable.PlaneEntries[addr.ChannelID][addr.LocalFlashChipID][addr.DieID][addr.PlaneID].WaitingReadCount++;
                        }
                    }
                    (myFTL.IOScheduler as IOSchedulerRPB).UpdateGCQueuePriority(ir.TargetPageAddress);
                }
            }
            Locked = false;

            myFTL.IOScheduler.Schedule((uint)myHandler.Flows[streamID].PriorityClass, streamID);
        }
Example #7
0
 protected override bool updateStatistics(IORequest targetIORequest)
 {
     thisRoundHandledRequestsCount++;//used in replay
     return(base.updateStatistics(targetIORequest));
 }
Example #8
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
        public override void SendResponseToHost(InternalRequest internalReq)
        {
            sumOfInternalRequestLifeTime      += (XEngineFactory.XEngine.Time - internalReq.IssueTime) / 1000;                                                          //Nanoseconds is converted to microseconds
            sumOfInternalRequestExecutionTime += internalReq.ExecutionTime / 1000;                                                                                      //Nanoseconds is converted to microseconds
            sumOfInternalRequestTransferTime  += internalReq.TransferTime / 1000;                                                                                       //Nanoseconds is converted to microseconds
            sumOfInternalRequestWaitingTime   += (XEngineFactory.XEngine.Time - (internalReq.IssueTime + internalReq.ExecutionTime + internalReq.TransferTime)) / 1000; //Nanoseconds is converted to microseconds
            totalFlashOperations++;

            if (gcStarted)
            {
                sumOfInternalRequestLifeTime_AGC      += (XEngineFactory.XEngine.Time - internalReq.IssueTime) / 1000;
                sumOfInternalRequestExecutionTime_AGC += internalReq.ExecutionTime / 1000;
                sumOfInternalRequestTransferTime_AGC  += internalReq.TransferTime / 1000;
                sumOfInternalRequestWaitingTime_AGC   += (XEngineFactory.XEngine.Time - (internalReq.IssueTime + internalReq.ExecutionTime + internalReq.TransferTime)) / 1000;
                totalFlashOperations_AGC++;
            }

            if (internalReq.Type == InternalRequestType.Read)
            {
                sumOfReadRequestLifeTime      += (XEngineFactory.XEngine.Time - internalReq.IssueTime) / 1000;
                sumOfReadRequestExecutionTime += internalReq.ExecutionTime / 1000;
                sumOfReadRequestTransferTime  += internalReq.TransferTime / 1000;
                sumOfReadRequestWaitingTime   += (XEngineFactory.XEngine.Time - (internalReq.IssueTime + internalReq.ExecutionTime + internalReq.TransferTime)) / 1000;
                totalReadOperations++;
                if (gcStarted)
                {
                    sumOfReadRequestLifeTime_AGC      += (XEngineFactory.XEngine.Time - internalReq.IssueTime) / 1000;
                    sumOfReadRequestExecutionTime_AGC += internalReq.ExecutionTime / 1000;
                    sumOfReadRequestTransferTime_AGC  += internalReq.TransferTime / 1000;
                    sumOfReadRequestWaitingTime_AGC   += (XEngineFactory.XEngine.Time - (internalReq.IssueTime + internalReq.ExecutionTime + internalReq.TransferTime)) / 1000;
                    totalReadOperations_AGC++;
                }
            }
            else
            {
                FTL.OnLPNServiced(internalReq.RelatedIORequest.StreamID, internalReq.LPN);
                sumOfProgramRequestLifeTime      += (XEngineFactory.XEngine.Time - internalReq.IssueTime) / 1000;
                sumOfProgramRequestExecutionTime += internalReq.ExecutionTime / 1000;
                sumOfProgramRequestTransferTime  += internalReq.TransferTime / 1000;
                sumOfProgramRequestWaitingTime   += (XEngineFactory.XEngine.Time - (internalReq.IssueTime + internalReq.ExecutionTime + internalReq.TransferTime)) / 1000;
                totalProgramOperations++;
                if (gcStarted)
                {
                    sumOfProgramRequestLifeTime_AGC      += (XEngineFactory.XEngine.Time - internalReq.IssueTime) / 1000;
                    sumOfProgramRequestExecutionTime_AGC += internalReq.ExecutionTime / 1000;
                    sumOfProgramRequestTransferTime_AGC  += internalReq.TransferTime / 1000;
                    sumOfProgramRequestWaitingTime_AGC   += (XEngineFactory.XEngine.Time - (internalReq.IssueTime + internalReq.ExecutionTime + internalReq.TransferTime)) / 1000;
                    totalProgramOperations_AGC++;
                }
            }
            IORequest targetIORequest = internalReq.RelatedIORequest;

            if (_inputStreams[targetIORequest.StreamID].WriteToCompletionQueue(internalReq, requestProcessingTime))
            {
                checked
                {
                    try
                    {
                        sumResponseTime += (targetIORequest.ResponseTime / 1000);
                    }
                    catch (OverflowException ex)
                    {
                        Console.WriteLine("Overflow exception occured while calculating statistics in HostInterface.");
                        if (overflowOccured)
                        {
                            throw new Exception("I can just handle one overflow event, but I received the second one!");
                        }
                        overflowOccured = true;
                        XEngineFactory.XEngine.StopSimulation();
                        return;
                    }
                }
                thisRoundSumResponseTime += targetIORequest.ResponseTime / 1000;
                if (minResponseTime > targetIORequest.ResponseTime)
                {
                    minResponseTime = targetIORequest.ResponseTime;
                }
                else if (maxResponseTime < targetIORequest.ResponseTime)
                {
                    maxResponseTime = targetIORequest.ResponseTime;
                }
                transferredBytesCount += targetIORequest.SizeInByte;
                handledRequestsCount++;          //used for general statistics
                thisRoundHandledRequestsCount++; //used in replay
                if (gcStarted)
                {
                    sumResponseTime_AGC += (targetIORequest.ResponseTime / 1000);
                    if (minResponseTime_AGC > targetIORequest.ResponseTime)
                    {
                        minResponseTime_AGC = targetIORequest.ResponseTime;
                    }
                    else if (maxResponseTime_AGC < targetIORequest.ResponseTime)
                    {
                        maxResponseTime_AGC = targetIORequest.ResponseTime;
                    }
                    transferredBytesCount_AGC += targetIORequest.SizeInByte;
                    handledRequestsCount_AGC++;//used for general statistics
                }
                if (targetIORequest.Type == IORequestType.Write)
                {
                    sumResponseTimeW          += (targetIORequest.ResponseTime / 1000);
                    thisRoundSumResponseTimeW += (targetIORequest.ResponseTime / 1000);
                    transferredBytesCountW    += targetIORequest.SizeInByte;
                    handledWriteRequestsCount++;
                    thisRoundHandledWriteRequestsCount++;
                    if (minResponseTimeW > targetIORequest.ResponseTime)
                    {
                        minResponseTimeW = targetIORequest.ResponseTime;
                    }
                    else if (maxResponseTimeW < targetIORequest.ResponseTime)
                    {
                        maxResponseTimeW = targetIORequest.ResponseTime;
                    }
                    if (gcStarted)
                    {
                        sumResponseTimeW_AGC       += (targetIORequest.ResponseTime / 1000);
                        transferredBytesCountW_AGC += targetIORequest.SizeInByte;
                        handledWriteRequestsCount_AGC++;
                        if (minResponseTimeW_AGC > targetIORequest.ResponseTime)
                        {
                            minResponseTimeW_AGC = targetIORequest.ResponseTime;
                        }
                        else if (maxResponseTimeW_AGC < targetIORequest.ResponseTime)
                        {
                            maxResponseTimeW_AGC = targetIORequest.ResponseTime;
                        }
                    }
                }
                else
                {
                    sumResponseTimeR          += (targetIORequest.ResponseTime / 1000);
                    thisRoundSumResponseTimeR += (targetIORequest.ResponseTime / 1000);
                    transferredBytesCountR    += targetIORequest.SizeInByte;
                    handledReadRequestsCount++;
                    thisRoundHandledReadRequestsCount++;
                    if (minResponseTimeR > targetIORequest.ResponseTime)
                    {
                        minResponseTimeR = targetIORequest.ResponseTime;
                    }
                    else if (maxResponseTimeR < targetIORequest.ResponseTime)
                    {
                        maxResponseTimeR = targetIORequest.ResponseTime;
                    }
                    if (gcStarted)
                    {
                        sumResponseTimeR_AGC       += (targetIORequest.ResponseTime / 1000);
                        transferredBytesCountR_AGC += targetIORequest.SizeInByte;
                        handledReadRequestsCount_AGC++;
                        if (minResponseTimeR_AGC > targetIORequest.ResponseTime)
                        {
                            minResponseTimeR_AGC = targetIORequest.ResponseTime;
                        }
                        else if (maxResponseTimeR_AGC < targetIORequest.ResponseTime)
                        {
                            maxResponseTimeR_AGC = targetIORequest.ResponseTime;
                        }
                    }
                }

                if ((handledRequestsCount / (double)totalRequestsToGenerate) > nextAnnouncementMilestone)
                {
                    nextAnnouncementMilestone += announcementStep;
                    OnStatReady();
                }

                OnIORequestCompleted(targetIORequest.StreamID);
            }//_inputStreams[targetIORequest.StreamID].WriteToCompletionQueue...
        }
Example #11
0
        /* When an IO request is handled without creating any InternalRequest
         * this function is invoked (i.e., IO request is handled by cache or by requests currently being serviced.
         * For example if we have a read request for an lpn which is simultaneously being written with another
         * request, therefore we can simply return the value of write without performing any flash read operation.)*/
        public override void SendEarlyResponseToHost(IORequest targetIORequest)
        {
            _inputStreams[targetIORequest.StreamID].WriteToCompletionQueue(targetIORequest, requestProcessingTime);
            checked
            {
                try
                {
                    sumResponseTime += (targetIORequest.ResponseTime / 1000);
                }
                catch (OverflowException)
                {
                    Console.WriteLine("Overflow exception occured while calculating statistics in HostInterface.");
                    if (overflowOccured)
                    {
                        throw new Exception("I can just handle one overflow event, but I received the second one!");
                    }
                    overflowOccured = true;
                    XEngineFactory.XEngine.StopSimulation();
                    return;
                }
            }
            thisRoundSumResponseTime += targetIORequest.ResponseTime / 1000;
            transferredBytesCount    += targetIORequest.SizeInByte;
            handledRequestsCount++;          //used for general statistics
            thisRoundHandledRequestsCount++; //used in replay
            if (gcStarted)
            {
                sumResponseTime_AGC       += (targetIORequest.ResponseTime / 1000);
                transferredBytesCount_AGC += targetIORequest.SizeInByte;
                handledRequestsCount_AGC++;//used for general statistics
            }
            if (targetIORequest.Type == IORequestType.Write)
            {
                sumResponseTimeW          += (targetIORequest.ResponseTime / 1000);
                thisRoundSumResponseTimeW += (targetIORequest.ResponseTime / 1000);
                transferredBytesCountW    += targetIORequest.SizeInByte;
                handledWriteRequestsCount++;
                thisRoundHandledWriteRequestsCount++;
                if (gcStarted)
                {
                    sumResponseTimeW_AGC       += (targetIORequest.ResponseTime / 1000);
                    transferredBytesCountW_AGC += targetIORequest.SizeInByte;
                    handledWriteRequestsCount_AGC++;
                }
            }
            else
            {
                sumResponseTimeR          += (targetIORequest.ResponseTime / 1000);
                thisRoundSumResponseTimeR += (targetIORequest.ResponseTime / 1000);
                transferredBytesCountR    += targetIORequest.SizeInByte;
                handledReadRequestsCount++;
                thisRoundHandledReadRequestsCount++;
                if (gcStarted)
                {
                    sumResponseTimeR_AGC       += (targetIORequest.ResponseTime / 1000);
                    transferredBytesCountR_AGC += targetIORequest.SizeInByte;
                    handledReadRequestsCount_AGC++;
                }
            }

            if ((handledRequestsCount / (double)totalRequestsToGenerate) > nextAnnouncementMilestone)
            {
                nextAnnouncementMilestone += announcementStep;
                OnStatReady();
            }

            OnIORequestCompleted(targetIORequest.StreamID);
        }
Example #12
0
 public void CheckCache(IORequest currentRequest)
 {
     /*  uint index, state;
      * uint flag = 0, need_distb_flag, lsn_flag;
      * CacheUnit buffer_node;
      * CacheUnit key = new CacheUnit();
      * uint mask = 0;
      * uint offset1 = 0, offset2 = 0;
      *
      * bool requestedCompletedInDRAM = true;
      * uint full_page = ~(0xffffffff << (int)_FTL.SubpageNoPerPage);
      * ulong lsn = currentRequest.LSN;
      * ulong lpn = lsn / _FTL.SubpageNoPerPage;
      * ulong lastLpn = (lsn + currentRequest.SizeInSubpages - 1) / _FTL.SubpageNoPerPage;
      * ulong firstLpn = lpn;
      *
      * currentRequest.NeedDistrFlag = new uint[(lastLpn - firstLpn + 1) * _FTL.SubpageNoPerPage / 32 + 1];
      *
      * if (currentRequest.Type == IORequestType.Read)
      * {
      *    while (lpn <= lastLpn)
      *    {
      *        need_distb_flag = full_page;
      *        key.LPN = lpn;
      *        buffer_node = Buffer.Find(key);
      *        while ((buffer_node != null) && (lsn < (lpn + 1) * _FTL.SubpageNoPerPage) && (lsn <= (currentRequest.LSN + currentRequest.SizeInSubpages - 1)))
      *        {
      *            lsn_flag = full_page;
      *            mask = (uint)(1 << (int)(lsn % _FTL.SubpageNoPerPage));
      *            if (mask > 31)
      *            {
      *                Console.WriteLine("the subpage number is larger than 32!add some cases");
      *                Console.Read();
      *            }
      *            else if ((buffer_node.ValidSectors & mask) == mask)
      *            {
      *                flag = 1;
      *                lsn_flag = (uint)lsn & (~mask);
      *                throw new Exception("ulong casted to uint. Needs considration");
      *            }
      *
      *            if (flag == 1)
      *            {
      *                if (Buffer.buffer_head != buffer_node)
      *                {
      *                    if (Buffer.buffer_tail == buffer_node)
      *                    {
      *                        buffer_node.LRU_link_pre.LRU_link_next = null;
      *                        Buffer.buffer_tail = buffer_node.LRU_link_pre;
      *                    }
      *                    else
      *                    {
      *                        buffer_node.LRU_link_pre.LRU_link_next = buffer_node.LRU_link_next;
      *                        buffer_node.LRU_link_next.LRU_link_pre = buffer_node.LRU_link_pre;
      *                    }
      *                    buffer_node.LRU_link_next = Buffer.buffer_head;
      *                    Buffer.buffer_head.LRU_link_pre = buffer_node;
      *                    buffer_node.LRU_link_pre = null;
      *                    Buffer.buffer_head = buffer_node;
      *                }
      *                Buffer.read_hit++;
      *                currentRequest.CompleteLSNCount++;
      *            }
      *            else if (flag == 0)
      *            {
      *                Buffer.read_miss_hit++;
      *            }
      *            need_distb_flag = need_distb_flag & lsn_flag;
      *
      *            flag = 0;
      *            lsn++;
      *        }
      *
      *        index = (uint)((lpn - firstLpn) / (32 / _FTL.SubpageNoPerPage));
      *        currentRequest.NeedDistrFlag[index] = currentRequest.NeedDistrFlag[index] | (need_distb_flag << (int)(((lpn - firstLpn) % (32 / _FTL.SubpageNoPerPage)) * _FTL.SubpageNoPerPage));
      *        lpn++;
      *    }
      *
      *    for (int j = 0; j <= (int)((lastLpn - firstLpn + 1) * (_FTL.SubpageNoPerPage) / 32); j++)//? maybe: checks that the operation done completely and nothig remain.
      *        if (currentRequest.NeedDistrFlag[j] != 0)
      *            requestedCompletedInDRAM = false;
      * }
      * else// if (currentRequest.Type == IORequestType.Write)
      * {
      *    while (lpn <= lastLpn)
      *    {
      *        mask = ~(0xffffffff << (int)(_FTL.SubpageNoPerPage));
      *        state = mask;
      *        if (lpn == firstLpn)
      *        {
      *            offset1 = (uint)((_FTL.SubpageNoPerPage) - ((lpn + 1) * _FTL.SubpageNoPerPage - currentRequest.LSN));
      *            state = state & (0xffffffff << (int)offset1);
      *        }
      *        if (lpn == lastLpn)
      *        {
      *            offset2 = (uint)(_FTL.SubpageNoPerPage - ((lpn + 1) * _FTL.SubpageNoPerPage - (currentRequest.LSN + currentRequest.SizeInSubpages)));
      *            state = state & (~(0xffffffff << (int)offset2));
      *        }
      *        CacheUpdate(lpn, state, currentRequest);
      *        lpn++;
      *    }
      * }
      *
      * if (requestedCompletedInDRAM && (currentRequest.InternalRequestList.Count == 0))
      *    XEngineFactory.XEngine.EventList.InsertXEvent(new XEvent(XEngineFactory.XEngine.Time + this.DRAMServiceTime, _FTL.HostInterface, currentRequest, (int)HostInterface.HostInterfaceEventType.RequestCompletedByDRAM));
      */
 }
Example #13
0
 private void CacheUpdate(ulong lpn, uint state, IORequest currentRequest)
 {
     /*ulong write_back_count;
      * uint i, hit_flag, add_flag;
      * ulong lsn;
      * CacheUnit buffer_node = null;
      * CacheUnit pt;
      * CacheUnit new_node = null;
      * CacheUnit key = new CacheUnit();
      *
      * uint sub_req_state = 0, sub_req_size = 0;
      * ulong sub_req_lpn = 0;
      *
      * uint sectorCount = FTL.SizeInSubpages(state);
      * key.LPN = lpn;
      * buffer_node = Buffer.Find(key);
      *
      * if (buffer_node == null)
      * {
      *  if (Buffer.MaxBufferSector - Buffer.OccupiedSectorCount < sectorCount)
      *  {
      *      write_back_count = sectorCount - (Buffer.MaxBufferSector - Buffer.OccupiedSectorCount);
      *      Buffer.write_miss_hit += write_back_count;
      *      while (write_back_count > 0)
      *      {
      *          sub_req_state = Buffer.buffer_tail.ValidSectors;
      *          sub_req_size = _FTL.SizeInSubpages(Buffer.buffer_tail.ValidSectors);
      *          sub_req_lpn = Buffer.buffer_tail.LPN;
      *          FTL.CreatFlashTransaction(sub_req_lpn, sub_req_size, sub_req_state, currentRequest);//?create_sub_request done'nt exist.
      *
      *          Buffer.OccupiedSectorCount = Buffer.OccupiedSectorCount - sub_req_size;
      *          pt = Buffer.buffer_tail;
      *          Buffer.Del(pt);
      *          if (Buffer.buffer_head.LRU_link_next == null)
      *          {
      *              Buffer.buffer_head = null;
      *              Buffer.buffer_tail = null;
      *          }
      *          else
      *          {
      *              Buffer.buffer_tail = Buffer.buffer_tail.LRU_link_pre;
      *              Buffer.buffer_tail.LRU_link_next = null;
      *          }
      *          write_back_count -= sub_req_size;
      *      }
      *  }
      *  new_node = new CacheUnit();
      *  new_node.LPN = lpn;
      *  new_node.ValidSectors = state;
      *  new_node.DirtyClean = state;
      *  new_node.LRU_link_pre = null;
      *  new_node.LRU_link_next = Buffer.buffer_head;
      *  if (Buffer.buffer_head != null)
      *  {
      *      Buffer.buffer_head.LRU_link_pre = new_node;
      *  }
      *  else
      *  {
      *      Buffer.buffer_tail = new_node;
      *  }
      *  Buffer.buffer_head = new_node;
      *  new_node.LRU_link_pre = null;
      *  Buffer.Add(new_node);
      *  Buffer.OccupiedSectorCount += sectorCount;
      * }
      *
      * else
      * {
      *  for (i = 0; i < _FTL.SubpageNoPerPage; i++)
      *  {
      *      if ((state >> (int)i) % 2 != 0)
      *      {
      *          lsn = lpn * _FTL.SubpageNoPerPage + i;
      *          hit_flag = 0;
      *          hit_flag = (uint)((buffer_node.ValidSectors) & (0x00000001 << (int)i));
      *
      *          if (hit_flag != 0)
      *          {
      *              if (currentRequest != null)
      *              {
      *                  if (Buffer.buffer_head != buffer_node)
      *                  {
      *                      if (Buffer.buffer_tail == buffer_node)
      *                      {
      *                          Buffer.buffer_tail = buffer_node.LRU_link_pre;
      *                          buffer_node.LRU_link_pre.LRU_link_next = null;
      *                      }
      *                      else if (buffer_node != Buffer.buffer_head)
      *                      {
      *                          buffer_node.LRU_link_pre.LRU_link_next = buffer_node.LRU_link_next;
      *                          buffer_node.LRU_link_next.LRU_link_pre = buffer_node.LRU_link_pre;
      *                      }
      *                      buffer_node.LRU_link_next = Buffer.buffer_head;
      *                      Buffer.buffer_head.LRU_link_pre = buffer_node;
      *                      buffer_node.LRU_link_pre = null;
      *                      Buffer.buffer_head = buffer_node;
      *                  }
      *                  Buffer.write_hit++;
      *                  currentRequest.CompleteLSNCount++;//in moteghaiier vojood nadare.
      *              }
      *          }
      *          else
      *          {
      *              Buffer.write_miss_hit++;
      *              if (Buffer.OccupiedSectorCount >= Buffer.MaxBufferSector)
      *              {
      *                  if (buffer_node == Buffer.buffer_tail)
      *                  {
      *                      pt = Buffer.buffer_tail.LRU_link_pre;
      *                      Buffer.buffer_tail.LRU_link_pre = pt.LRU_link_pre;
      *                      Buffer.buffer_tail.LRU_link_pre.LRU_link_next = Buffer.buffer_tail;
      *                      Buffer.buffer_tail.LRU_link_next = pt;
      *                      pt.LRU_link_next = null;
      *                      pt.LRU_link_pre = Buffer.buffer_tail;
      *                      Buffer.buffer_tail = pt;
      *                  }
      *                  sub_req_state = Buffer.buffer_tail.ValidSectors;
      *                  sub_req_size = _FTL.SizeInSubpages(Buffer.buffer_tail.ValidSectors);
      *                  sub_req_lpn = Buffer.buffer_tail.LPN;
      *                  FTL.CreatFlashTransaction(sub_req_lpn, sub_req_size, sub_req_state, currentRequest);//create sub request deosn'g exsist
      *
      *                  Buffer.OccupiedSectorCount = Buffer.OccupiedSectorCount - sub_req_size;
      *                  pt = Buffer.buffer_tail;
      *                  Buffer.Del(pt);
      *
      *                  if (Buffer.buffer_head.LRU_link_next == null)
      *                  {
      *                      Buffer.buffer_head = null;
      *                      Buffer.buffer_tail = null;
      *                  }
      *                  else
      *                  {
      *                      Buffer.buffer_tail = Buffer.buffer_tail.LRU_link_pre;
      *                      Buffer.buffer_tail.LRU_link_next = null;
      *                  }
      *                  pt.LRU_link_next = null;
      *                  pt.LRU_link_pre = null;
      *                  //AVL_TREENODE_FREE(ssd->dram->buffer, (TREE_NODE*)pt);
      *                  pt = null;
      *              }
      *
      *              add_flag = (uint)(0x00000001 << (int)(lsn % _FTL.SubpageNoPerPage));
      *              if (Buffer.buffer_head != buffer_node)
      *              {
      *                  if (Buffer.buffer_tail == buffer_node)
      *                  {
      *                      buffer_node.LRU_link_pre.LRU_link_next = null;
      *                      Buffer.buffer_tail = buffer_node.LRU_link_pre;
      *                  }
      *                  else
      *                  {
      *                      buffer_node.LRU_link_pre.LRU_link_next = buffer_node.LRU_link_next;
      *                      buffer_node.LRU_link_next.LRU_link_pre = buffer_node.LRU_link_pre;
      *                  }
      *                  buffer_node.LRU_link_next = Buffer.buffer_head;
      *                  Buffer.buffer_head.LRU_link_pre = buffer_node;
      *                  buffer_node.LRU_link_pre = null;
      *                  Buffer.buffer_head = buffer_node;
      *              }
      *              buffer_node.ValidSectors = buffer_node.ValidSectors | add_flag;
      *              buffer_node.DirtyClean = buffer_node.DirtyClean | add_flag;//no dirty clean flag
      *              Buffer.OccupiedSectorCount++;
      *          }
      *      }
      *  }
      * }*/
 }