public void Announce(PrtValue ev, PrtValue payload, PrtMachine parent) { foreach (var spec in specObservers[ev]) { spec.PrtEnqueueEvent(ev, payload, parent); } }
public void Announce(PrtEventValue ev, PrtValue payload, PrtMachine parent) { if (ev.Equals(PrtValue.@null)) { throw new PrtIllegalEnqueueException("Enqueued event must not be null"); } PrtType prtType = ev.evt.payloadType; //assertion to check if argument passed inhabits the payload type. if (prtType is PrtNullType) { if (!payload.Equals(PrtValue.@null)) { throw new PrtIllegalEnqueueException("Did not expect a payload value"); } } else if (!PrtValue.PrtInhabitsType(payload, prtType)) { throw new PrtInhabitsTypeException(String.Format("Payload <{0}> does not match the expected type <{1}> with event <{2}>", payload.ToString(), prtType.ToString(), ev.evt.name)); } var allSpecMachines = GetSpecMachines(parent.renamedName); foreach (var mon in allSpecMachines) { if (mon.observes.Contains(ev)) { TraceLine("<AnnounceLog> Enqueued Event <{0}, {1}> to Spec Machine {2}", ev, payload, mon.Name); mon.PrtEnqueueEvent(ev, payload, parent); } } }
public PrtInterfaceValue CreateInterface(PrtMachine currMach, string interfaceOrMachineName, PrtValue payload) { //add visible action to trace if (visibleInterfaces.Contains(interfaceOrMachineName)) { currentVisibleTrace.AddAction(interfaceOrMachineName, payload.ToString()); } var renamedImpMachine = linkMap[currMach.renamedName][interfaceOrMachineName]; var impMachineName = machineDefMap[renamedImpMachine]; var machine = createMachineMap[impMachineName](this, payload); machine.isSafe = isSafeMap[renamedImpMachine]; machine.renamedName = renamedImpMachine; AddImplMachineToStateImpl(machine); CreateMachineCallback?.Invoke(machine); //TraceLine("<CreateLog> Machine {0}-{1} was created by machine {2}-{3}", currMach.renamedName, currMach.instanceNumber, machine.renamedName, machine.instanceNumber); TraceLine("<CreateLog> Machine {0}-{1} was created by machine {2}-{3}", machine.renamedName, machine.instanceNumber, currMach.renamedName, currMach.instanceNumber); if (interfaceMap.ContainsKey(interfaceOrMachineName)) { return(new PrtInterfaceValue(machine, interfaceMap[interfaceOrMachineName])); } else { return(new PrtInterfaceValue(machine, machine.self.permissions)); } }
public override void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source) { if (e is PrtNullValue) { throw new PrtIllegalEnqueueException("Enqueued event must be non-null"); } PrtType prtType; PrtEventValue ev = e as PrtEventValue; //assertion to check if argument passed inhabits the payload type. prtType = ev.evt.payloadType; if (!(prtType is PrtNullType) && !PrtValue.PrtInhabitsType(arg, prtType)) { throw new PrtInhabitsTypeException(String.Format("Payload <{0}> does not match the expected type <{1}> with event <{2}>", arg.GetString(), prtType.GetString(), ev.evt.name)); } else if (prtType is PrtNullType && !(arg is PrtNullValue)) { throw new PrtIllegalEnqueueException("Did not expect a payload value"); } if (currentStatus == PrtMachineStatus.Halted) { stateImpl.Trace( @"<EnqueueLog> {0}-{1} Machine has been halted and Event {2} is dropped", this.Name, this.instanceNumber, ev.evt.name); } else { stateImpl.Trace( @"<EnqueueLog> Enqueued Event <{0}, {1}> in {2}-{3} by {4}-{5}", ev.evt.name, arg.GetString(), this.Name, this.instanceNumber, source.Name, source.instanceNumber); this.eventQueue.EnqueueEvent(e, arg); if (this.maxBufferSize != -1 && this.eventQueue.Size() > this.maxBufferSize) { if (this.doAssume) { throw new PrtAssumeFailureException(); } else { throw new PrtMaxBufferSizeExceededException( String.Format(@"<EXCEPTION> Event Buffer Size Exceeded {0} in Machine {1}-{2}", this.maxBufferSize, this.Name, this.instanceNumber)); } } if (currentStatus == PrtMachineStatus.Blocked && this.eventQueue.IsEnabled(this)) { currentStatus = PrtMachineStatus.Enabled; } } //Announce it to all the monitors stateImpl.Announce(e, arg, source); }
public PrtValue ExecuteToCompletion(StateImpl application, PrtMachine parent, params PrtValue[] args) { parent.PrtPushFunStackFrame(this, CreateLocals(args)); Execute(application, parent); if (parent.continuation.reason != PrtContinuationReason.Return) { throw new PrtInternalException("Unexpected continuation reason"); } return(parent.continuation.retVal.Clone()); }
public void Announce(PrtEventValue ev, PrtValue payload, PrtMachine parent) { var allSpecMachines = GetSpecMachines(parent.renamedName); foreach (var mon in allSpecMachines) { if (mon.observes.Contains(ev)) { Trace("<AnnounceLog> Enqueued Event <{0}, {1}> to Spec Machine {2}", ev, payload, mon.Name); mon.PrtEnqueueEvent(ev, payload, parent); } } }
public virtual void DbgCompare(PrtMachine machine) { Debug.Assert(renamedName == machine.renamedName); Debug.Assert(isSafe == machine.isSafe); Debug.Assert(instanceNumber == machine.instanceNumber); Debug.Assert(fields.Count == machine.fields.Count); for (int i = 0; i < fields.Count; i++) { Debug.Assert(fields[i].GetHashCode() == machine.fields[i].GetHashCode()); } Debug.Assert(eventValue.GetHashCode() == machine.eventValue.GetHashCode()); Debug.Assert(stateStack.GetHashCode() == machine.stateStack.GetHashCode()); Debug.Assert(invertedFunStack.GetHashCode() == machine.invertedFunStack.GetHashCode()); Debug.Assert(continuation.GetHashCode() == machine.continuation.GetHashCode()); Debug.Assert(currentStatus == machine.currentStatus); Debug.Assert(nextSMOperation == machine.nextSMOperation); Debug.Assert(stateExitReason == machine.stateExitReason); Debug.Assert(currentTrigger.GetHashCode() == machine.currentTrigger.GetHashCode()); Debug.Assert(currentPayload.GetHashCode() == machine.currentPayload.GetHashCode()); Debug.Assert((destOfGoto == null && machine.destOfGoto == null) || (destOfGoto != null && machine.destOfGoto != null && destOfGoto.GetHashCode() == machine.destOfGoto.GetHashCode())); }
public override void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source, PrtMachineValue target = null) { PrtEventValue ev = e as PrtEventValue; if (ev.evt.name == "null") { throw new PrtIllegalEnqueueException("Enqueued event must not be null"); } //check if the sent event is in source send set if (!source.sends.Contains(e as PrtEventValue)) { throw new PrtIllegalEnqueueException(String.Format("Machine <0> cannot send event {1}", source.Name, e.ToString())); } //check if the sent event is in target permissions if (target is PrtInterfaceValue) { if (!(target as PrtInterfaceValue).permissions.Contains(e as PrtEventValue)) { throw new PrtIllegalEnqueueException(String.Format("Event {1} is not in the permission set of the target", e.ToString())); } } PrtType prtType = ev.evt.payloadType; //assertion to check if argument passed inhabits the payload type. if (prtType is PrtNullType) { if (!arg.Equals(PrtValue.@null)) { throw new PrtIllegalEnqueueException("Did not expect a payload value"); } } else if (!PrtValue.PrtInhabitsType(arg, prtType)) { throw new PrtInhabitsTypeException(String.Format("Payload <{0}> does not match the expected type <{1}> with event <{2}>", arg.ToString(), prtType.ToString(), ev.evt.name)); } //check if the event sent is in the permissions if (currentStatus == PrtMachineStatus.Halted) { stateImpl.Trace( @"<EnqueueLog> {0}-{1} Machine has been halted and Event {2} is dropped", this.Name, this.instanceNumber, ev.evt.name); } else { stateImpl.Trace( @"<EnqueueLog> Enqueued Event <{0}, {1}> in {2}-{3} by {4}-{5}", ev.evt.name, arg.ToString(), this.Name, this.instanceNumber, source.Name, source.instanceNumber); this.eventQueue.EnqueueEvent(e, arg); if (this.maxBufferSize != DefaultMaxBufferSize && this.eventQueue.Size() > this.maxBufferSize) { if (this.doAssume) { throw new PrtAssumeFailureException(); } else { throw new PrtMaxBufferSizeExceededException( String.Format(@"<EXCEPTION> Event Buffer Size Exceeded {0} in Machine {1}-{2}", this.maxBufferSize, this.Name, this.instanceNumber)); } } if (currentStatus == PrtMachineStatus.Blocked && this.eventQueue.IsEnabled(this)) { currentStatus = PrtMachineStatus.Enabled; } } //Announce it to all the spec machines stateImpl.Announce(e as PrtEventValue, arg, source); }
public abstract void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source);
public abstract void Execute(StateImpl application, PrtMachine parent);
public override void Execute(StateImpl application, PrtMachine parent) { throw new NotImplementedException(); }
public override void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source, PrtMachineValue target = null) { int numOfStepsTaken = 0; // set the currentTrigger and currentPayload fields // so that we can reuse the common functions currentPayload = arg.Clone(); currentTrigger = e; PrtValue currEventValue; PrtFun currAction; bool hasMoreWork = false; try { Start: switch (nextSMOperation) { case PrtNextStatemachineOperation.ExecuteFunctionOperation: goto DoExecuteFunction; case PrtNextStatemachineOperation.HandleEventOperation: goto DoHandleEvent; } DoExecuteFunction: if (invertedFunStack.TopOfStack == null) { //Trace: entered state PrtFun entryFun = CurrentState.entryFun; if (entryFun.IsAnonFun) { PrtPushFunStackFrame(entryFun, entryFun.CreateLocals(currentPayload)); } else { PrtPushFunStackFrame(entryFun, entryFun.CreateLocals()); } } //invoke the function invertedFunStack.TopOfStack.fun.Execute(stateImpl, this); goto CheckFunLastOperation; DoAction: currAction = PrtFindActionHandler(eventValue); if (currAction == PrtFun.IgnoreFun) { //Trace: Performed ignore action for the event currentTrigger = PrtValue.@null; currentPayload = PrtValue.@null; } else { if (invertedFunStack.TopOfStack == null) { //Trace: executed the action handler for event if (currAction.IsAnonFun) { PrtPushFunStackFrame(currAction, currAction.CreateLocals(currentPayload)); } else { PrtPushFunStackFrame(currAction, currAction.CreateLocals()); } } //invoke the action handler invertedFunStack.TopOfStack.fun.Execute(stateImpl, this); } goto CheckFunLastOperation; CheckFunLastOperation: switch (continuation.reason) { case PrtContinuationReason.Goto: { stateExitReason = PrtStateExitReason.OnGotoStatement; nextSMOperation = PrtNextStatemachineOperation.ExecuteFunctionOperation; PrtPushExitFunction(); goto DoExecuteFunction; } case PrtContinuationReason.Raise: { nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation; hasMoreWork = true; goto Finish; } case PrtContinuationReason.Return: { switch (stateExitReason) { case PrtStateExitReason.NotExit: { nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation; hasMoreWork = false; goto Finish; } case PrtStateExitReason.OnGotoStatement: { PrtChangeState(destOfGoto); currentTemperature = destOfGoto.temperature; nextSMOperation = PrtNextStatemachineOperation.ExecuteFunctionOperation; stateExitReason = PrtStateExitReason.NotExit; hasMoreWork = true; goto Finish; } case PrtStateExitReason.OnUnhandledEvent: { hasMoreWork = !PrtPopState(false); nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation; stateExitReason = PrtStateExitReason.NotExit; goto Finish; } case PrtStateExitReason.OnTransition: { stateExitReason = PrtStateExitReason.OnTransitionAfterExit; nextSMOperation = PrtNextStatemachineOperation.ExecuteFunctionOperation; PrtPushTransitionFun(eventValue); goto DoExecuteFunction; } case PrtStateExitReason.OnTransitionAfterExit: { // The parameter to an anonymous transition function is always passed as swap. // Update currentPayload to the latest value of the parameter so that the correct // value gets passed to the entry function of the target state. PrtTransition transition = CurrentState.transitions[eventValue]; PrtFun transitionFun = transition.transitionFun; if (transitionFun.IsAnonFun) { currentPayload = continuation.retLocals[0]; } PrtChangeState(transition.gotoState); currentTemperature = transition.gotoState.temperature; hasMoreWork = true; nextSMOperation = PrtNextStatemachineOperation.ExecuteFunctionOperation; stateExitReason = PrtStateExitReason.NotExit; goto Finish; } default: { Debug.Assert(false, "Unexpected value for exit reason"); goto Finish; } } } default: { Debug.Assert(false, "Unexpected value for continuation reason"); goto Finish; } } DoHandleEvent: if (!currentTrigger.Equals(PrtValue.@null)) { currEventValue = currentTrigger; currentTrigger = PrtValue.@null; } else { currEventValue = eventValue; } if (PrtIsTransitionPresent(currEventValue)) { stateExitReason = PrtStateExitReason.OnTransition; nextSMOperation = PrtNextStatemachineOperation.ExecuteFunctionOperation; eventValue = currEventValue; PrtPushExitFunction(); goto DoExecuteFunction; } else if (PrtIsActionInstalled(currEventValue)) { eventValue = currEventValue; goto DoAction; } else { stateExitReason = PrtStateExitReason.OnUnhandledEvent; nextSMOperation = PrtNextStatemachineOperation.ExecuteFunctionOperation; eventValue = currEventValue; PrtPushExitFunction(); goto DoExecuteFunction; } Finish: if (hasMoreWork) { if (numOfStepsTaken > 100000) { throw new PrtInfiniteRaiseLoop("Infinite loop in spec machine"); } else { numOfStepsTaken++; goto Start; } } else { return; } } catch (PrtException ex) { stateImpl.Exception = ex; } }
public abstract void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source, PrtMachineValue target = null);
public override void DbgCompare(PrtMachine machine) { base.DbgCompare(machine); Debug.Assert(currentTemperature.GetHashCode() == (machine as PrtSpecMachine).currentTemperature.GetHashCode()); Debug.Assert(GetHashCode() == machine.GetHashCode()); }
public override void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source) { int numOfStepsTaken = 0; // set the currentTrigger and currentPayload fields // so that we can reuse the common functions currentPayload = arg.Clone(); currentTrigger = e; PrtValue currEventValue; PrtFun currAction; bool hasMoreWork = false; try { Start: switch (nextSMOperation) { case PrtNextStatemachineOperation.EntryOperation: goto DoEntry; case PrtNextStatemachineOperation.HandleEventOperation: goto DoHandleEvent; } DoEntry: if (invertedFunStack.TopOfStack == null) { //Trace: entered state if (CurrentState.entryFun.IsAnonFun) { PrtPushFunStackFrame(CurrentState.entryFun, CurrentState.entryFun.CreateLocals(currentPayload)); } else { PrtPushFunStackFrame(CurrentState.entryFun, CurrentState.entryFun.CreateLocals()); } } //invoke the function invertedFunStack.TopOfStack.fun.Execute(stateImpl, this); goto CheckFunLastOperation; DoAction: currAction = PrtFindActionHandler(eventValue); if (currAction == PrtCommonFunctions.IgnoreFun) { //Trace: Performed ignore action for the event currentTrigger = PrtValue.NullValue; currentPayload = PrtValue.NullValue; } else { if (invertedFunStack.TopOfStack == null) { //Trace: executed the action handler for event PrtPushFunStackFrame(currAction, currAction.CreateLocals(currentPayload)); } //invoke the action handler invertedFunStack.TopOfStack.fun.Execute(stateImpl, this); } goto CheckFunLastOperation; CheckFunLastOperation: switch (continuation.reason) { case PrtContinuationReason.Goto: { stateExitReason = PrtStateExitReason.OnGotoStatement; PrtExecuteExitFunction(); goto CheckFunLastOperation; } case PrtContinuationReason.Raise: { nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation; hasMoreWork = true; goto Finish; } case PrtContinuationReason.Return: { switch (stateExitReason) { case PrtStateExitReason.NotExit: { nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation; hasMoreWork = false; goto Finish; } case PrtStateExitReason.OnGotoStatement: { PrtChangeState(destOfGoto); nextSMOperation = PrtNextStatemachineOperation.EntryOperation; stateExitReason = PrtStateExitReason.NotExit; hasMoreWork = true; goto Finish; } case PrtStateExitReason.OnUnhandledEvent: { hasMoreWork = !PrtPopState(false); nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation; stateExitReason = PrtStateExitReason.NotExit; goto Finish; } case PrtStateExitReason.OnTransition: { stateExitReason = PrtStateExitReason.OnTransitionAfterExit; PrtExecuteTransitionFun(eventValue); goto CheckFunLastOperation; } case PrtStateExitReason.OnTransitionAfterExit: { PrtChangeState(CurrentState.transitions[eventValue].gotoState); hasMoreWork = true; nextSMOperation = PrtNextStatemachineOperation.EntryOperation; stateExitReason = PrtStateExitReason.NotExit; goto Finish; } default: { Debug.Assert(false, "Unexpected value for exit reason"); goto Finish; } } } default: { Debug.Assert(false, "Unexpected value for continuation reason"); goto Finish; } } DoHandleEvent: if (!currentTrigger.IsEqual(PrtValue.NullValue)) { currEventValue = currentTrigger; currentTrigger = PrtValue.NullValue; } else { currEventValue = eventValue; } if (PrtIsTransitionPresent(currEventValue)) { stateExitReason = PrtStateExitReason.OnTransition; eventValue = currEventValue; PrtExecuteExitFunction(); goto CheckFunLastOperation; } else if (PrtIsActionInstalled(currEventValue)) { goto DoAction; } else { stateExitReason = PrtStateExitReason.OnUnhandledEvent; eventValue = currEventValue; PrtExecuteExitFunction(); goto CheckFunLastOperation; } Finish: if (hasMoreWork) { if (numOfStepsTaken > 100000) { throw new PrtInfiniteRaiseLoop("Infinite loop in monitor"); } else { numOfStepsTaken++; goto Start; } } else { return; } } catch (PrtException ex) { stateImpl.Exception = ex; } }