/// <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); } } }