/// <summary> /// This function is called by the underlying timers. /// </summary> /// <param name="whichTimer">Reference to the timer that caused this function call.</param> private void AlarmClockThreadFinishedHdl(AlarmClockThread whichTimer) { AlarmClock whichClock = null; lock (this.lockObj) { if (this.targetFunctions.ContainsKey(whichTimer) && this.parameters.ContainsKey(whichTimer) && this.alarmClocks.ContainsKey(whichTimer) && this.clockTimerMap.ContainsKey(this.alarmClocks[whichTimer]) && this.clockTimerMap[this.alarmClocks[whichTimer]] == whichTimer) { whichClock = this.alarmClocks[whichTimer]; } } if (whichClock != null) { TraceManager.WriteAllTrace(string.Format("AlarmClock-{0} timeout", whichClock.testID), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); this.alarmClkFinishedIface.AlarmClockFinished(whichClock); } else { throw new DssException("Invalid timer call."); } }
/// <see cref="IDisposable.Dispose"/> public void Dispose() { if (this.dssThread != RCThread.CurrentThread) { throw new DssException("AlarmClockManager.Dispose must be called from the DSS-thread!"); } /// Stop and dispose every unused timer. int numOfTimers = this.timers.Length; for (int i = 0; i < numOfTimers; i++) { AlarmClockThread timer = this.timers.Get(); TraceManager.WriteAllTrace(string.Format("Get timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); timer.Stop(); timer.Dispose(); this.timers.Push(timer); TraceManager.WriteAllTrace(string.Format("Push timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); } /// Stop and dispose every timer that are currently in use. foreach (KeyValuePair <AlarmClockThread, AlarmClock> item in this.alarmClocks) { AlarmClockThread timer = item.Key; timer.Stop(); timer.Dispose(); } }
/// <see cref="IAlarmClockInvoke.CancelAlarmClock"/> public void CancelAlarmClock(AlarmClock whichClock) { if (this.dssThread != RCThread.CurrentThread) { throw new DssException("AlarmClockManager.CancelAlarmClock must be called from the DSS-thread!"); } lock (this.lockObj) { if (this.clockTimerMap.ContainsKey(whichClock)) { AlarmClockThread correspondingTimer = this.clockTimerMap[whichClock]; correspondingTimer.Stop(); } else { TraceManager.WriteAllTrace("Warning! Invalid alarm clock cancel!", DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); } } }
/// <see cref="IAlarmClockInvoke.InvokeIfNecessary"/> public void InvokeIfNecessary(AlarmClock whichClock, bool invoke) { if (this.dssThread != RCThread.CurrentThread) { throw new DssException("AlarmClockManager.InvokeIfNecessary must be called from the DSS-thread!"); } lock (this.lockObj) { if (this.clockTimerMap.ContainsKey(whichClock)) { AlarmClockThread correspondingTimer = this.clockTimerMap[whichClock]; if (this.alarmClocks.ContainsKey(correspondingTimer) && this.alarmClocks[correspondingTimer] == whichClock && this.targetFunctions.ContainsKey(correspondingTimer) && this.parameters.ContainsKey(correspondingTimer)) { TraceManager.WriteAllTrace(string.Format("Invoking alarm clock @ {0}", DssRoot.Time), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); if (invoke) { this.targetFunctions[correspondingTimer](whichClock, this.parameters[correspondingTimer]); } this.clockTimerMap.Remove(whichClock); this.alarmClocks.Remove(correspondingTimer); this.targetFunctions.Remove(correspondingTimer); this.parameters.Remove(correspondingTimer); this.timers.Push(correspondingTimer); /// Put the timer back to the FIFO TraceManager.WriteAllTrace(string.Format("Push timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); } else { TraceManager.WriteAllTrace("Warning! Invalid alarm clock invocation!", DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); } } else { TraceManager.WriteAllTrace("Warning! Invalid alarm clock invocation!", DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); } } }
/// <summary> /// Asks the AlarmClockManager to call the given function at the given time with the given parameter. /// </summary> /// <param name="when">The time when the call must be performed.</param> /// <param name="funcToCall">The function that must be called.</param> /// <param name="param">The parameter of the function to call with.</param> /// <returns>A reference to the allocated alarm clock.</returns> public AlarmClock SetAlarmClock(int when, AlarmFunction funcToCall, object param) { if (this.dssThread != RCThread.CurrentThread) { throw new DssException("AlarmClockManager.SetAlarmClock must be called from the DSS-thread!"); } if (funcToCall == null) { throw new ArgumentNullException("funcToCall"); } if (when < 0) { throw new ArgumentOutOfRangeException("when"); } int currentTime = DssRoot.Time; if (when > currentTime) { /// Delayed invoke lock (this.lockObj) { if (this.timers.Length == 0) { /// No free timer found --> create a new one AlarmClockThread newTimer = new AlarmClockThread(); this.currentCapacity++; this.timers = new Fifo <AlarmClockThread>(currentCapacity); this.timers.Push(newTimer); TraceManager.WriteAllTrace(string.Format("Delayed: New timer: {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); TraceManager.WriteAllTrace(string.Format("Push timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); } else { TraceManager.WriteAllTrace("Delayed: clock reuse", DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); } AlarmClockThread timerToUse = this.timers.Get(); TraceManager.WriteAllTrace(string.Format("Get timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); AlarmClock retClock = new AlarmClock(when, this); this.targetFunctions.Add(timerToUse, funcToCall); this.parameters.Add(timerToUse, param); this.alarmClocks.Add(timerToUse, retClock); this.clockTimerMap.Add(retClock, timerToUse); timerToUse.Start(when - currentTime, this.AlarmClockThreadFinishedHdl, this.AlarmClockThreadFinishedHdl); TraceManager.WriteAllTrace(string.Format("AlarmClock-{0} started", retClock.testID), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); return(retClock); } } else { /// Immediate invoke lock (this.lockObj) { if (this.timers.Length == 0) { /// No free timer found --> create a new one AlarmClockThread newTimer = new AlarmClockThread(); this.currentCapacity++; this.timers = new Fifo <AlarmClockThread>(currentCapacity); this.timers.Push(newTimer); TraceManager.WriteAllTrace(string.Format("Immediate: New timer: {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); TraceManager.WriteAllTrace(string.Format("Push timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); } else { TraceManager.WriteAllTrace("Immediate: clock reuse", DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); } AlarmClockThread timerToUse = this.timers.Get(); TraceManager.WriteAllTrace(string.Format("Get timer - {0}", this.timers.Length), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); AlarmClock retClock = new AlarmClock(when, this); this.targetFunctions.Add(timerToUse, funcToCall); this.parameters.Add(timerToUse, param); this.alarmClocks.Add(timerToUse, retClock); this.clockTimerMap.Add(retClock, timerToUse); TraceManager.WriteAllTrace(string.Format("AlarmClock-{0} started immediately", retClock.testID), DssTraceFilters.ALARM_CLOCK_MANAGER_INFO); this.alarmClkFinishedIface.AlarmClockFinished(retClock); return(retClock); } } }