예제 #1
0
 /// <summary>
 /// Initializes this monitor.
 /// </summary>
 /// <param name="mid">MachineId</param>
 internal void Initialize(MachineId mid)
 {
     this.Id             = mid;
     this.Runtime        = mid.Runtime;
     this.IsInsideOnExit = false;
     this.CurrentActionCalledTransitionStatement = false;
 }
예제 #2
0
        /// <summary>
        /// Creates a new machine id.
        /// </summary>
        /// <param name="type">Machine type</param>
        /// <param name="friendlyName">Friendly machine name</param>
        /// <param name="runtime">PSharpRuntime</param>
        /// <param name="useNameForHashing">Use friendly name as the id</param>
        internal MachineId(Type type, string friendlyName, PSharpRuntime runtime, bool useNameForHashing = false)
        {
            Runtime  = runtime;
            Endpoint = Runtime.NetworkProvider.GetLocalEndpoint();

            if (useNameForHashing)
            {
                Value     = 0;
                NameValue = friendlyName;
                Runtime.Assert(!string.IsNullOrEmpty(NameValue), "Input friendlyName cannot be null when used as Id");
            }
            else
            {
                // Atomically increments and safely wraps into an unsigned long.
                Value     = (ulong)Interlocked.Increment(ref runtime.MachineIdCounter) - 1;
                NameValue = string.Empty;

                // Checks for overflow.
                Runtime.Assert(Value != ulong.MaxValue, "Detected MachineId overflow.");
            }

            Generation = runtime.Configuration.RuntimeGeneration;

            Type = type.FullName;
            if (IsNameUsedForHashing)
            {
                Name = NameValue;
            }
            else
            {
                Name = string.Format("{0}({1})", string.IsNullOrEmpty(friendlyName) ? Type : friendlyName, Value);
            }
        }
예제 #3
0
 /// <summary>
 /// Sends an asynchronous event to a machine.
 /// </summary>
 /// <param name="target">Target machine id</param>
 /// <param name="e">Event</param>
 /// <param name="payload">Optional payload</param>
 public static void SendEvent(MachineId target, Event e, params Object[] payload)
 {
     // If the event is null then report an error and exit.
     PSharpRuntime.Assert(e != null, "Cannot send a null event.");
     e.AssignPayload(payload);
     PSharpRuntime.Send(target, e);
 }
예제 #4
0
 /// <summary>
 /// Invokes the specified monitor with the given event.
 /// </summary>
 /// <typeparam name="T">Type of the monitor</typeparam>
 /// <param name="e">Event</param>
 /// <param name="payload">Optional payload</param>
 public static void InvokeMonitor <T>(Event e, params Object[] payload)
 {
     // If the event is null then report an error and exit.
     PSharpRuntime.Assert(e != null, "Cannot send a null event.");
     e.AssignPayload(payload);
     PSharpRuntime.Monitor <T>(e);
 }
예제 #5
0
 /// <summary>
 /// Notifies that a scheduling point should be instrumented
 /// due to a wait synchronization operation.
 /// </summary>
 /// <param name="blockingTasks">Blocking tasks</param>
 /// <param name="waitAll">Boolean value</param>
 internal static void ScheduleOnWait(IEnumerable <Task> blockingTasks, bool waitAll)
 {
     PSharpRuntime.Assert(PSharpRuntime.BugFinder is TaskAwareBugFindingScheduler,
                          "Cannot schedule on wait without enabling the task-aware bug finding scheduler.");
     (PSharpRuntime.BugFinder as TaskAwareBugFindingScheduler).NotifyTaskBlocked(
         Task.CurrentId, blockingTasks, waitAll);
     PSharpRuntime.BugFinder.Schedule();
 }
예제 #6
0
        /// <summary>
        /// Blocks and waits to receive an event of the given types, and
        /// executes a given action on receiving the event. Returns a
        /// payload, if there is any, else returns null.
        /// </summary>
        /// <returns>Payload</returns>
        public static Object Receive(params Tuple <Type, Action>[] events)
        {
            PSharpRuntime.Assert(Task.CurrentId != null, "Only machines can wait to receive an event.");
            PSharpRuntime.Assert(PSharpRuntime.TaskMap.ContainsKey((int)Task.CurrentId),
                                 "Only machines can wait to receive an event; task {0} does not belong to a machine.",
                                 (int)Task.CurrentId);
            Machine machine = PSharpRuntime.TaskMap[(int)Task.CurrentId];

            machine.Receive(events);
            return(machine.Payload);
        }
예제 #7
0
 /// <summary>
 /// Sends an asynchronous event to a machine.
 /// </summary>
 /// <param name="mid">Machine id</param>
 /// <param name="e">Event</param>
 void IDispatcher.Send(MachineId mid, Event e)
 {
     if (mid.IpAddress.Length > 0)
     {
         PSharpRuntime.SendRemotely(mid, e);
     }
     else
     {
         PSharpRuntime.Send(mid, e);
     }
 }
예제 #8
0
        /// <summary>
        /// Creates a new machine of the given type with an optional payload.
        /// </summary>
        /// <param name="type">Type of the machine</param>
        /// <param name="payload">Optional payload</param>
        /// <returns>Machine id</returns>
        public static MachineId CreateMachine(Type type, params Object[] payload)
        {
            lock (PSharpRuntime.Lock)
            {
                if (!PSharpRuntime.IsRunning)
                {
                    PSharpRuntime.Initialize();
                }
            }

            return(PSharpRuntime.TryCreateMachine(type, payload));
        }
예제 #9
0
        /// <summary>
        /// Sends an asynchronous event to a machine.
        /// </summary>
        /// <param name="target">Target machine id</param>
        /// <param name="e">Event</param>
        /// <param name="payload">Optional payload</param>
        public static void SendEvent(MachineId target, Event e, params Object[] payload)
        {
            e.AssignPayload(payload);

            try
            {
                PSharpRuntime.Send(target, e);
            }
            catch (TaskCanceledException)
            {
                Output.Log("<Exception> TaskCanceledException was thrown.");
            }
        }
예제 #10
0
        /// <summary>
        /// Sends an asynchronous event to a machine.
        /// </summary>
        /// <param name="target">Target machine id</param>
        /// <param name="e">Event</param>
        /// <param name="payload">Optional payload</param>
        public static void SendEvent(MachineId target, Event e, params Object[] payload)
        {
            // If the event is null then report an error and exit.
            PSharpRuntime.Assert(e != null, "Cannot send a null event.");
            e.AssignPayload(payload);

            try
            {
                PSharpRuntime.Send(target, e);
            }
            catch (TaskCanceledException)
            {
                Output.Debug("<Exception> TaskCanceledException was thrown.");
            }
        }
예제 #11
0
        /// <summary>
        /// Tries to create a new monitor of the given type with an optional payload.
        /// </summary>
        /// <param name="type">Type of the monitor</param>
        /// <param name="payload">Optional payload</param>
        internal static void TryCreateMonitor(Type type, params Object[] payload)
        {
            PSharpRuntime.Assert(type.IsSubclassOf(typeof(Monitor)), "Type '{0}' is not a " +
                                 "subclass of Monitor.\n", type.Name);

            Object monitor = Activator.CreateInstance(type);

            Output.Debug(DebugType.Runtime, "<CreateLog> Monitor {0} is created.", type.Name);

            PSharpRuntime.Monitors.Add(monitor as Monitor);

            if (Configuration.CheckLiveness)
            {
                PSharpRuntime.LivenessChecker.RegisterMonitor(monitor as Monitor);
            }

            (monitor as Monitor).AssignInitialPayload(payload);
            (monitor as Monitor).GotoStartState();
        }
예제 #12
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="type">Machine type</param>
        /// <param name="friendlyName">Friendly machine name</param>
        /// <param name="runtime">PSharpRuntime</param>
        internal MachineId(Type type, string friendlyName, PSharpRuntime runtime)
        {
            this.FriendlyName = friendlyName;
            this.Runtime      = runtime;

            this.Type     = type.FullName;
            this.EndPoint = this.Runtime.NetworkProvider.GetLocalEndPoint();

            this.Value = Interlocked.Increment(ref IdCounter);

            if (this.FriendlyName != null && this.FriendlyName.Length > 0)
            {
                this.Name = string.Format("{0}({1})", this.FriendlyName, this.Value);
            }
            else
            {
                this.Name = string.Format("{0}({1})", this.Type, this.Value);
            }
        }
예제 #13
0
        /// <summary>
        /// Creates a new machine id.
        /// </summary>
        /// <param name="type">Machine type string</param>
        /// <param name="friendlyName">Friendly machine name</param>
        /// <param name="runtime">PSharpRuntime</param>
        internal MachineId(string type, string friendlyName, PSharpRuntime runtime)
        {
            Type    = type;
            Runtime = runtime;

            if (this.Runtime.IsTest())
            {
                this.Value = runtime.GenerateTestId();
                // Checks for overflow.
                Runtime.Assert(Value != ulong.MaxValue, "Detected MachineId overflow.");
            }

            if (string.IsNullOrWhiteSpace(friendlyName))
            {
                friendlyName = Runtime.GetFriendlyName(Type);
            }

            FriendlyName = friendlyName;
            Endpoint     = Runtime.NetworkProvider.GetLocalEndpoint();
            Name         = $"({Type})-{FriendlyName}";
        }
예제 #14
0
파일: MachineId.cs 프로젝트: wxdtony/PSharp
        /// <summary>
        /// Create a fresh MachineId borrowing information from a given id.
        /// </summary>
        /// <param name="mid">MachineId</param>
        internal MachineId(MachineId mid)
        {
            Runtime  = mid.Runtime;
            Endpoint = mid.Endpoint;

            // Atomically increments and safely wraps into an unsigned long.
            Value = (ulong)Interlocked.Increment(ref Runtime.MachineIdCounter) - 1;

            // Checks for overflow.
            Runtime.Assert(Value != ulong.MaxValue, "Detected MachineId overflow.");

            Generation = mid.Generation;
            Type       = mid.Type;

            if (FriendlyName != null && FriendlyName.Length > 0)
            {
                Name = string.Format("{0}({1})", FriendlyName, Value);
            }
            else
            {
                Name = string.Format("{0}({1})", Type, Value);
            }
        }
예제 #15
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="type">Machine type</param>
        /// <param name="friendlyName">Friendly machine name</param>
        /// <param name="runtime">PSharpRuntime</param>
        internal MachineId(Type type, string friendlyName, PSharpRuntime runtime)
        {
            this.FriendlyName = friendlyName;
            this.Runtime      = runtime;

            this.Type     = type.FullName;
            this.Endpoint = this.Runtime.NetworkProvider.GetLocalEndpoint();

            // Atomically increments and safely wraps into an unsigned long.
            this.Value = (uint)Interlocked.Increment(ref runtime.MachineIdCounter);

            // Checks for overflow.
            Runtime.Assert(this.Value != ulong.MaxValue, "Detected MachineId overflow.");

            if (this.FriendlyName != null && this.FriendlyName.Length > 0)
            {
                this.Name = string.Format("{0}({1})", this.FriendlyName, this.Value);
            }
            else
            {
                this.Name = string.Format("{0}({1})", this.Type, this.Value);
            }
        }
예제 #16
0
파일: MachineId.cs 프로젝트: wxdtony/PSharp
        /// <summary>
        /// Creates a new machine id.
        /// </summary>
        /// <param name="type">Machine type</param>
        /// <param name="friendlyName">Friendly machine name</param>
        /// <param name="runtime">PSharpRuntime</param>
        internal MachineId(Type type, string friendlyName, PSharpRuntime runtime)
        {
            FriendlyName = friendlyName;
            Runtime      = runtime;
            Endpoint     = Runtime.NetworkProvider.GetLocalEndpoint();

            // Atomically increments and safely wraps into an unsigned long.
            Value = (ulong)Interlocked.Increment(ref runtime.MachineIdCounter) - 1;

            // Checks for overflow.
            Runtime.Assert(Value != ulong.MaxValue, "Detected MachineId overflow.");

            Generation = runtime.Configuration.RuntimeGeneration;

            Type = type.FullName;
            if (friendlyName != null && friendlyName.Length > 0)
            {
                Name = string.Format("{0}({1})", friendlyName, Value);
            }
            else
            {
                Name = string.Format("{0}({1})", Type, Value);
            }
        }
예제 #17
0
        /// <summary>
        /// Tries to create a new task machine.
        /// </summary>
        /// <param name="userTask">Task</param>
        internal static void TryCreateTaskMachine(Task userTask)
        {
            PSharpRuntime.Assert(PSharpRuntime.TaskScheduler is TaskWrapperScheduler, "Unable to wrap " +
                                 "the task in a machine, because the task wrapper scheduler is not enabled.\n");
            TaskMachine taskMachine = new TaskMachine(PSharpRuntime.TaskScheduler as TaskWrapperScheduler, userTask);

            MachineId mid = taskMachine.Id;

            Output.Log("<CreateLog> TaskMachine({0}) is created.", mid.MVal);

            Task task = new Task(() =>
            {
                PSharpRuntime.BugFinder.NotifyTaskStarted();
                taskMachine.Run();
                PSharpRuntime.BugFinder.NotifyTaskCompleted();
            });

            lock (PSharpRuntime.Lock)
            {
                PSharpRuntime.MachineTasks.Add(task);
            }

            PSharpRuntime.BugFinder.NotifyNewTaskCreated(task.Id, taskMachine);

            if (PSharpRuntime.Configuration.ScheduleIntraMachineConcurrency)
            {
                task.Start(PSharpRuntime.TaskScheduler);
            }
            else
            {
                task.Start();
            }

            PSharpRuntime.BugFinder.WaitForTaskToStart(task.Id);
            PSharpRuntime.BugFinder.Schedule();
        }
예제 #18
0
 /// <summary>
 /// Tries to create a new monitor of the given type with an optional payload.
 /// </summary>
 /// <param name="type">Type of the machine</param>
 /// <param name="payload">Optional payload</param>
 void IDispatcher.TryCreateMonitor(Type type, params Object[] payload)
 {
     PSharpRuntime.TryCreateMonitor(type, payload);
 }
예제 #19
0
 /// <summary>
 /// Tries to create a new remote machine of the given type with an optional payload.
 /// </summary>
 /// <param name="type">Type of the machine</param>
 /// <param name="payload">Optional payload</param>
 /// <returns>Machine id</returns>
 MachineId IDispatcher.TryCreateRemoteMachine(Type type, params Object[] payload)
 {
     // Remote does not work in the bug-finding runtime.
     return(PSharpRuntime.TryCreateMachine(type, payload));
 }
예제 #20
0
 /// <summary>
 /// Tries to create a new machine of the given type with an optional payload.
 /// </summary>
 /// <param name="type">Type of the machine</param>
 /// <param name="payload">Optional payload</param>
 /// <returns>Machine id</returns>
 MachineId IDispatcher.TryCreateMachine(Type type, params Object[] payload)
 {
     return(PSharpRuntime.TryCreateMachine(type, payload));
 }
예제 #21
0
 /// <summary>
 /// Notifies that a scheduling point should be instrumented
 /// due to a wait synchronization operation.
 /// </summary>
 /// <param name="blockingTasks">Blocking tasks</param>
 /// <param name="waitAll">Boolean value</param>
 void IDispatcher.ScheduleOnWait(IEnumerable <Task> blockingTasks, bool waitAll)
 {
     PSharpRuntime.ScheduleOnWait(blockingTasks, waitAll);
 }
예제 #22
0
 /// <summary>
 /// Notifies that a default handler has been used.
 /// </summary>
 void IDispatcher.NotifyDefaultHandlerFired()
 {
     PSharpRuntime.NotifyDefaultHandlerFired();
 }
예제 #23
0
 /// <summary>
 /// Invokes the specified monitor with the given event.
 /// </summary>
 /// <typeparam name="T">Type of the monitor</typeparam>
 /// <param name="e">Event</param>
 void IDispatcher.Monitor <T>(Event e)
 {
     PSharpRuntime.Monitor <T>(e);
 }
예제 #24
0
 /// <summary>
 /// Checks if the assertion holds, and if not it reports
 /// an error and exits.
 /// </summary>
 /// <param name="predicate">Predicate</param>
 /// <param name="s">Message</param>
 /// <param name="args">Message arguments</param>
 void IDispatcher.Assert(bool predicate, string s, params object[] args)
 {
     PSharpRuntime.Assert(predicate, s, args);
 }
예제 #25
0
 /// <summary>
 /// Checks if the assertion holds, and if not it reports
 /// an error and exits.
 /// </summary>
 /// <param name="predicate">Predicate</param>
 void IDispatcher.Assert(bool predicate)
 {
     PSharpRuntime.Assert(predicate);
 }
예제 #26
0
 /// <summary>
 /// Tries to create a new task machine.
 /// </summary>
 /// <param name="userTask">Task</param>
 void IDispatcher.TryCreateTaskMachine(Task userTask)
 {
     PSharpRuntime.TryCreateTaskMachine(userTask);
 }
예제 #27
0
 /// <summary>
 /// Sends an asynchronous event to a machine.
 /// </summary>
 /// <param name="mid">Machine id</param>
 /// <param name="e">Event</param>
 void IDispatcher.Send(MachineId mid, Event e)
 {
     PSharpRuntime.Send(mid, e);
 }
예제 #28
0
 /// <summary>
 /// Notifies that a machine is waiting to receive an event.
 /// </summary>
 /// <param name="mid">Machine id</param>
 void IDispatcher.NotifyWaitEvent(MachineId mid)
 {
     PSharpRuntime.NotifyWaitEvent();
 }
예제 #29
0
 /// <summary>
 /// Returns a nondeterministic boolean choice, that can be
 /// controlled during analysis or testing.
 /// </summary>
 /// <returns>Boolean</returns>
 bool IDispatcher.Nondet()
 {
     return(PSharpRuntime.Nondet());
 }
예제 #30
0
 /// <summary>
 /// Notifies that a machine received an event that it was waiting for.
 /// </summary>
 /// <param name="mid">Machine id</param>
 void IDispatcher.NotifyReceivedEvent(MachineId mid)
 {
     PSharpRuntime.NotifyReceivedEvent(mid);
 }