Example #1
0
            /// <summary>
            /// Invokes the pulse operation.
            /// </summary>
            private void Pulse(PulseOperation pulseOperation)
            {
                if (pulseOperation is PulseOperation.Next)
                {
                    if (this.WaitQueue.Count > 0)
                    {
                        // System.Threading.Monitor has FIFO semantics.
                        var waitingOp = this.WaitQueue[0];
                        this.WaitQueue.RemoveAt(0);
                        this.ReadyQueue.Add(waitingOp);
                        IO.Debug.WriteLine("<Coyote> Operation '{0}' is pulsed by task '{1}'.",
                                           waitingOp.Id, SystemTask.CurrentId);
                    }
                }
                else
                {
                    foreach (var waitingOp in this.WaitQueue)
                    {
                        this.ReadyQueue.Add(waitingOp);
                        IO.Debug.WriteLine("<Coyote> Operation '{0}' is pulsed by task '{1}'.",
                                           waitingOp.Id, SystemTask.CurrentId);
                    }

                    this.WaitQueue.Clear();
                }
            }
Example #2
0
            /// <summary>
            /// Schedules a pulse operation that will either execute immediately or be scheduled
            /// to execute after the current owner releases the lock. This nondeterministic action
            /// is controlled by the runtime to simulate scenarios where the pulse is delayed by
            /// the operation system.
            /// </summary>
            private void SchedulePulse(PulseOperation pulseOperation)
            {
                var op = this.Resource.Runtime.GetExecutingOperation();

                if (this.Owner != op)
                {
                    throw new SystemSynchronizationLockException();
                }

                // Pulse has a delay in the operating system, we can simulate that here
                // by scheduling the pulse operation to be executed nondeterministically.
                this.PulseQueue.Enqueue(pulseOperation);
                if (this.PulseQueue.Count is 1)
                {
                    // Create a task for draining the queue. To optimize the testing performance,
                    // we create and maintain a single task to perform this role.
                    Task.Run(this.DrainPulseQueue);
                }
            }