public Buffer SetState(QpcTimeStamp qpcTimeStamp, BufferState state, string reason) { BufferState entryState = State; State = state; TimeStamp = qpcTimeStamp; switch (state) { case BufferState.SendPosted: CopyHeaderToByteArray(); SendPostedTimeStamp = qpcTimeStamp; break; case BufferState.Received: UpdateHeaderFromByteArray(); break; default: break; } if (StateEmitter.IsEnabled) { StateEmitter.Emit("{0} State changed to {1} [from: {2}, reason: {3}]", BufferName, state, entryState, reason ?? "NoReasonGiven"); } INotifyable notifyOnStateChange = NotifyOnSetState; if (notifyOnStateChange != null) { notifyOnStateChange.Notify(); } return(this); }
private void ReadGroupOfBuffersFromFile(FileStream fs, Histogram perBuffer) { try { QpcTimeStamp now = QpcTimeStamp.Now; QpcTimeStamp perGroupStartTime = now; for (int groupIdx = 0; groupIdx < numReadBuffersPerGroup; groupIdx++) { byte[] buffer = readBufferArray[nextReadBufferSelect]; nextReadBufferSelect = (nextReadBufferSelect + 1) % numReadBuffers; nextReadOffset = (nextReadOffset + bufferSize * readStride) % fileSize; QpcTimeStamp perBufferStartTime = now; fs.Seek(nextWriteOffset, SeekOrigin.Begin); fs.Read(buffer, 0, bufferSize); perBuffer.Add((now.SetToNow() - perBufferStartTime).TotalSeconds); } } catch (System.Exception ex) { Log.Debug.Emit("{0} generated unexpected exception: {1}", CurrentMethodName, ex.ToString(ExceptionFormat.TypeAndMessage)); } }
public MovingAverageTool <TCustomValuesType> AddRecordedValuesToHistory(QpcTimeStamp qpcTimeStamp = default(QpcTimeStamp)) { qpcTimeStamp = qpcTimeStamp.MapDefaultToNow(); HistoryItem queueItem = new HistoryItem() { sampleStartTimeStamp = accumulatorStartTime, sampleEndTimeStamp = qpcTimeStamp, accumulatedValues = accumulator, }; int historyListCount = historyList.Count; if (historyListCount >= maxAveragingHistoryLength && historyListCount > 0) { historyList.RemoveAt(historyListCount - 1); historyList.Insert(0, queueItem); } else { historyList.Insert(0, queueItem); } accumulator = new TCustomValuesType(); accumulatedValueCount = 0; accumulatorStartTime = qpcTimeStamp; hasNewSample = true; _sampleSeqNum = _sampleSeqNum.IncrementSkipZero(); return(this); }
protected override void PerformMainLoopService() { if (sampleIntervalTimer.Started != BaseState.IsOnline) { if (BaseState.IsOnline) { sampleIntervalTimer.Reset(triggerImmediately: true); } else { sampleIntervalTimer.Stop(); } } if (BaseState.IsOnline && (sampleIntervalTimer.IsTriggered || firstTime)) { QpcTimeStamp getStartTime = QpcTimeStamp.Now; processes = Process.GetProcesses(); getElpased = QpcTimeStamp.Now - getStartTime; TrackProcesss(processes, getStartTime); firstTime = false; } }
public void ReturnBuffersToPool(QpcTimeStamp qpcTimeStamp) { if (bufferList.Count > 0) { bufferList.DoForEach(buffer => buffer.ReturnToPool(qpcTimeStamp)); bufferList.Clear(); } }
/// <summary> /// Sets the current object's values from DateTime/QpcTimeStamp Now. Sets the fileDeltaTimeStamp to 0.0. /// <para/>Supports call chaining /// </summary> public DateTimeStampPair SetToNow() { qpcTimeStamp = QpcTimeStamp.Now; dateTime = DateTime.Now; utcTimeSince1601 = dateTime.GetUTCTimeSince1601(); fileDeltaTimeStamp = 0.0; return(this); }
/// <summary> /// Use this method to "drain the pool". This removes all of the buffers from the pool and Releases each of them. /// </summary> public void Drain(QpcTimeStamp qpcTimeStamp, string reason = null) { Buffer[] capturedBufferArray = capturedBufferArray = bufferArray.SafeToArray(); bufferArray.SetAll(null); bufferCount = 0; capturedBufferArray.Where(buffer => buffer != null).DoForEach(buffer => buffer.Release(qpcTimeStamp)); }
/// <summary> /// Used to indicate that this buffer is being abandoned so that its storage may be relcaimed during a future GC cycle. /// Sets the byteArray to null and the byteArraySize to zero. /// </summary> public void Release(QpcTimeStamp qpcTimeStamp, string reason = null) { header = BufferHeaderV1.Empty; bufferPool = null; byteArray = null; byteArraySize = 0; SetState(qpcTimeStamp, Buffers.BufferState.Released, reason); }
public MovingAverageTool <TCustomValuesType> Service(QpcTimeStamp qpcTimeStamp = default(QpcTimeStamp)) { qpcTimeStamp = qpcTimeStamp.MapDefaultToNow(); if (!rateIntervalTimer.GetIsTriggered(qpcTimeStamp)) { return(this); } return(AddRecordedValuesToHistory(qpcTimeStamp)); }
/// <summary> /// Asks the buffer to return itself to the pool from which it was allocated. /// </summary> public void ReturnToPool(QpcTimeStamp qpcTimeStamp, string reason = null) { if (bufferPool != null) { bufferPool.Release(qpcTimeStamp, this, reason); } else { Release(qpcTimeStamp, reason); } }
void TimerEvent10Hz_Callback() { QpcTimeStamp now = QpcTimeStamp.Now; foreach (IServiceable s in Timer10HzServiceList) { s.Service(now); } WVIA.Service(); }
public Message SetContents(QpcTimeStamp qpcTimeStamp, byte[] byteArray, int offset, int count) { ReturnBuffersToPool(qpcTimeStamp); if (count > 0) { using (var mbs = MessageBuildingStream) mbs.Write(byteArray, offset, count); } return(this); }
private void ChangeBufferSize(QpcTimeStamp qpcTimeStamp, int value) { if (_bufferSize != value) { Drain(qpcTimeStamp); _bufferSize = value.Clip(128, 16384); MaxBuffersToRetain = Math.Max(5, MaxTotalSpaceInBytes / _bufferSize); bufferArray = new Buffer[MaxBuffersToRetain]; } }
/// <summary> /// Basic service method. /// Uses the given <paramref name="qpc"/> value (after mapping Zero to Now) and the LastServiceQpcTimeStamp to measure the elapsed time since the last Service call /// and then passes the resulting elapsed time value to the TimeSpan Service method variant which does the actual slew limited update. /// <para/>Returns 1 if Value was changed or 0 if it was not. /// </summary> public int Service(QpcTimeStamp qpc = default(QpcTimeStamp)) { if (qpc.IsZero) { qpc = QpcTimeStamp.Now; } TimeSpan elapsed = qpc - LastServiceQpcTimeStamp; LastServiceQpcTimeStamp = qpc; return(Service(elapsed)); }
/// <summary> /// Copy constructor helper method. Sets the contents of this object to match the given other object, or to Zero if the other object is null /// <para/>Supports call chaining /// </summary> public DateTimeStampPair SetFrom(DateTimeStampPair other) { if (other == null) { other = internalZero; } qpcTimeStamp = other.qpcTimeStamp; dateTime = other.dateTime; utcTimeSince1601 = other.utcTimeSince1601; fileDeltaTimeStamp = other.fileDeltaTimeStamp; return(this); }
/// <summary> /// Sets the byteCount to the headerSize and sets the header's BufferSeqNum to zero. /// </summary> public void Clear(QpcTimeStamp qpcTimeStamp, bool clearByteArrayContents = false, string reason = null) { header = BufferHeaderV1.Empty; byteCount = header.Length; Message = null; NotifyOnSetState = null; if (clearByteArrayContents) { System.Array.Clear(byteArray, 0, byteArraySize); } SetState(qpcTimeStamp, Buffers.BufferState.Clear, reason); }
public Message SetState(QpcTimeStamp qpcTimeStamp, MessageState state, string reason, bool autoReleaseByState = false) { MessageState entryState = State; reason = reason ?? "NoReasonGiven"; State = state; TimeStamp = qpcTimeStamp; Reason = reason; Logging.IMesgEmitter emitterToUse = StateEmitter; switch (state) { case MessageState.Initial: case MessageState.Released: ReturnBuffersToPool(qpcTimeStamp); break; case MessageState.Delivered: if (autoReleaseByState) { ReturnBuffersToPool(qpcTimeStamp); } break; case MessageState.Failed: emitterToUse = IssueEmitter; break; case MessageState.SendPosted: SendPostedTimeStamp = qpcTimeStamp; break; default: break; } if (emitterToUse.IsEnabled) { emitterToUse.Emit("Message_{0:x4} State changed to {1} [from: {2}, reason: {3}]", instanceNum & 0x0ffff, state, entryState, reason); } return(this); }
public ProcessTracker(Process p, QpcTimeStamp getTimeStamp) { activePTSetIndex = -1; touchedTimeStamp = getTimeStamp; process = p; pid = p.Id; name = Utils.ExtensionMethods.TryGet(() => p.ProcessName); basePriority = Utils.ExtensionMethods.TryGet(() => p.BasePriority); mainModule = Utils.ExtensionMethods.TryGet(() => p.MainModule); if (mainModule != null) { mainModuleFilePath = Utils.ExtensionMethods.TryGet(() => mainModule.FileName); mainModuleFileVersion = Utils.ExtensionMethods.TryGet(() => mainModule.FileVersionInfo); } availableItemsToTrack = TrackedValues.TestAvailableItems(p); prevTrackedValues = default(TrackedValues); trackedValues = TrackedValues.TryGetFrom(p, getTimeStamp, availableItemsToTrack, prevTrackedValues); }
/// <summary> /// This returns the given <paramref name="buffer"/> to the pool provided that it was originally obtained from this pool and provided that the pool is not already full. /// </summary> public void Release(QpcTimeStamp qpcTimeStamp, Buffer buffer, string reason) { if (buffer == null) { } else if (buffer.bufferPool == this && buffer.byteArraySize >= BufferSize && bufferCount < MaxBuffersToRetain) { buffer.Clear(qpcTimeStamp, clearByteArrayContents: ClearBufferContentsOnRelease, reason: reason ?? "BufferPool.{0}.1".CheckedFormat(Fcns.CurrentMethodName)); int bufferIndex = bufferCount++; bufferArray[bufferIndex] = buffer; } else { buffer.Release(qpcTimeStamp, reason ?? "BufferPool.{0}.1".CheckedFormat(Fcns.CurrentMethodName)); } }
public TCustomValuesType GetAvg(QpcTimeStamp nominalAcceptanceTimeStamp) { hasNewSample = false; int gotCount = 0; var avgValues = new TCustomValuesType(); foreach (var item in historyList.Where(item => item.sampleEndTimeStamp >= nominalAcceptanceTimeStamp)) { avgValues = avgValues.Add(item.accumulatedValues); gotCount++; } avgValues = avgValues.ComputeAverage(gotCount); return(avgValues); }
/// <summary> /// This obtains a buffer instance from the pool, or creates a new one if the pool is empty. /// </summary> public Buffer Acquire(QpcTimeStamp qpcTimeStamp, string reason = null) { if (bufferCount > 0) { int bufferIndex = --bufferCount; Buffer buffer = bufferArray[bufferIndex]; bufferArray[bufferIndex] = null; return(buffer.SetState(qpcTimeStamp, BufferState.Acquired, reason ?? "BufferPool.{0}.1".CheckedFormat(Fcns.CurrentMethodName))); } else { Buffer buffer = new Buffer(bufferSize: BufferSize, bufferPool: this, stateEmitter: BufferStateEmitter) .SetState(qpcTimeStamp, BufferState.Created, reason ?? "BufferPool.{0}.2".CheckedFormat(Fcns.CurrentMethodName)); return(buffer); } }
public MovingAverageTool <TCustomValuesType> Reset(QpcTimeStamp qpcTimeStamp = default(QpcTimeStamp), bool clearTotalizer = true) { qpcTimeStamp = qpcTimeStamp.MapDefaultToNow(); accumulator = new TCustomValuesType(); accumulatedValueCount = 0; accumulatorStartTime = qpcTimeStamp; if (clearTotalizer) { totalAccumulator = new TCustomValuesType(); totalAccumulatorCount = 0; } historyList.Clear(); rateIntervalTimer.Start(qpcTimeStamp); hasNewSample = false; return(this); }
/// <summary> /// Resets the Value to the given <paramref name="value"/> /// and optionally resets the TargetValue to the given non-null <paramref name="targetValue"/> or to <paramref name="value"/> if <paramref name="replaceNullTargetWithValue"/> is true. /// Optionally sets LastServiceQpcTimeStamp to QpcTimeStamp.Now if <paramref name="setLastServiceQpcTimeStampToNow"/> is true. /// </summary> public SlewRateLimitTool Reset(double value, double?targetValue = null, bool replaceNullTargetWithValue = true, bool setLastServiceQpcTimeStampToNow = true) { Value = value; if (targetValue != null) { TargetValue = targetValue ?? 0.0; } else if (replaceNullTargetWithValue) { TargetValue = Value; } if (setLastServiceQpcTimeStampToNow) { LastServiceQpcTimeStamp = QpcTimeStamp.Now; } return(this); }
protected void Service(bool forcePublish, QpcTimeStamp now, bool reset) { if (PrivateState.IsAtTarget && !reset) return; ActuatorPosition nextState = ActuatorPosition.None; switch (PrivateState.TargetPos) { case ActuatorPosition.AtPos1: if (reset) nextState = PrivateState.TargetPos; else if (PrivateState.PosState != ActuatorPosition.MovingToPos1) nextState = ActuatorPosition.MovingToPos1; else if (PrivateState.TimeInState >= Config.Motion2To1Time.TotalSeconds) nextState = PrivateState.TargetPos; break; case ActuatorPosition.AtPos2: if (reset) nextState = PrivateState.TargetPos; else if (PrivateState.PosState != ActuatorPosition.MovingToPos2) nextState = ActuatorPosition.MovingToPos2; else if (PrivateState.TimeInState >= Config.Motion1To2Time.TotalSeconds) nextState = PrivateState.TargetPos; break; case ActuatorPosition.None: if (reset) nextState = PrivateState.TargetPos; else if (PrivateState.IsInMotion) nextState = ActuatorPosition.Inbetween; break; // do not change the current state default: nextState = PrivateState.TargetPos; break; } if (reset || (PrivateState.PosState != nextState && nextState != ActuatorPosition.None)) { ActuatorPosition entryState = PrivateState.PosState; string entryStateStr = PrivateState.PosStateStr; PrivateState.PosState = nextState; PrivateState.PosStateStr = Config.ToString(nextState); PrivateState.TimeStamp = now; logger.Info.Emit("State changed to {0} [{1}] from {2}, target:{3}", PrivateState.PosStateStr, PrivateState.PosState, entryStateStr, PrivateState.TargetPosStr); forcePublish = true; } if (forcePublish || reset) PublishState(); }
public void Service(QpcTimeStamp now) { Service(false, now, false); }
/// <summary> /// Provides the server specific version of the Part's Main Loop Service method. /// </summary> protected override void PerformMainLoopService() { InnerServiceFCServerAndStateRelay(); bool portIsConnected = portBaseStateObserver.Object.IsConnected; if (portWriteAction.ActionState.IsPendingCompletion || portFlushAction.ActionState.IsPendingCompletion) { // we cannot service a new request until the write and/or flush from a prior service loop have completed. return; } bool startFlush = false; bool startWrite = false; if (portIsConnected && portReadAction.ActionState.CanStart) { if (portReadAction.ActionState.IsComplete) { serverFunctionContainer.requestAdu.PktBuf.numBytes = portReadActionParam.BytesRead; string ec = null; TimeSpan bufferAge = bufferFillStartTime.Age; if (serverFunctionContainer.AttemptToDecodeRequestPkt(out ec)) { if (String.IsNullOrEmpty(ec)) { Log.Trace.Emit("Attempting to perform request ADU:{0}", serverFunctionContainer.requestAdu); if (serverFunctionContainer.ServiceDecodedRequest(fcServer)) startWrite = true; else Log.Trace.Emit("Decoded request produced no response [ADU:{0}]", serverFunctionContainer.requestAdu); } else { Log.Error.Emit("Invalid request received: {0} [numBytes:{1}]", ec, portReadActionParam.BytesRead); } portReadActionParam.BytesRead = 0; } else if (portReadActionParam.BytesRead > 0) { if (port.PortBehavior.IsDatagramPort) { Log.Warning.Emit("Invalid partial request received from datagram port. Discarding {0} bytes", portReadActionParam.BytesRead); portReadActionParam.BytesRead = 0; } else if (bufferAge > Timeout) { Log.Warning.Emit("Incomplete Partial Request timeout after {0:f3} seconds. Discarding {0} bytes", bufferAge.TotalSeconds, portReadActionParam.BytesRead); portReadActionParam.BytesRead = 0; } } else { Log.Trace.Emit("Empty read completed"); } } if (!startFlush) { // start the read immediately even if we are also starting a write (keep the interface primed) if (portReadActionParam.BytesRead == 0) bufferFillStartTime = QpcTimeStamp.Now; if (portReadActionParam.Buffer == null) { portReadActionParam.Buffer = serverFunctionContainer.requestAdu.PktBuf.bytes; portReadActionParam.BytesToRead = serverFunctionContainer.requestAdu.PktBuf.bytes.Length; } portReadAction.Start(); } } else if (portReadAction.ActionState.IsComplete && portReadActionParam.BytesRead > 0) { Log.Debug.Emit("Discarding {0} bytes of read data: port is no longer connected"); portReadActionParam.BytesRead = 0; } if (!portIsConnected) { } else if (startWrite) { Log.Trace.Emit("Writing response ADU:{0}", serverFunctionContainer.responseAdu); portWriteActionParam.Buffer = serverFunctionContainer.responseAdu.PktBuf.bytes; portWriteActionParam.BytesToWrite = serverFunctionContainer.responseAdu.PktBuf.numBytes; portWriteActionParam.BytesWritten = 0; portWriteAction.Start(); } else if (startFlush) { portFlushAction.Start(); } }
public bool IsComplete(QpcTimeStamp timeStamp) { return IsComplete(timeStamp - FirstPhaseStartTimeStamp); }
public AxisTarget GetAxisTarget(QpcTimeStamp timeStamp) { return GetAxisTarget(timeStamp - FirstPhaseStartTimeStamp); }
/// <summary>Caller is indicating that characters have been added to the buffer.</summary> /// <param name="n">Gives the number of bytes that have been appended/copied into the buffer by the caller.</param> public virtual void AddedNChars(int n) { putIdx += n; putTimeStamp = QpcTimeStamp.Now; BufferHasBeenIncreased(n); }
/// <summary>Shifts any existing buffered data down so that the first byte in the buffer is obtained from index zero. This makes the space available be as large as possible.</summary> public virtual void AlignBuffer() { if (!BufferEmpty) { if (getIdx != 0) { int shiftByN = getIdx; System.Buffer.BlockCopy(buffer, shiftByN, buffer, 0, BufferDataCount); putIdx -= shiftByN; getIdx = 0; BufferHasBeenShifted(shiftByN); } getTimeStamp = putTimeStamp; // over estimate the get timestamp on a shift (act as if some bytes were obtained during the shift). } else { // buffer is empty - just reset it. ResetBuffer(false); } }
/// <summary> /// This method is called to indicate that the given number of bytes have been used from the buffer. This causes the /// SlidingBuffer to advance the getIdx by the given number of bytes. It may cause the buffer to be Reset or Aligned /// depending on the final state after the getIdx has been advanced. /// </summary> public virtual void UsedNChars(int n) { getIdx += n; getTimeStamp = QpcTimeStamp.Now; if (BufferEmpty) ResetBuffer(); else if (BufferDataSpaceRemaining <= 0) AlignBuffer(); }
/// <summary>Clears the buffer contents, aligns the empty buffer and updates the get and put timestamps. Optionally resets the get and put timers</summary> protected virtual void ResetBuffer(bool resetTimers) { getIdx = 0; putIdx = 0; if (resetTimers) getTimeStamp = putTimeStamp = QpcTimeStamp.Now; BufferHasBeenReset(); }