/// <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 <AsyncOperation>(); if (this.Owner != op) { throw new SynchronizationLockException(); } // 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. ControlledTask.Run(this.DrainPulseQueue); } }
/// <summary> /// Schedule a Coyote task to run the action. /// </summary> /// <param name="action">The action to schedule.</param> private static void ScheduleAction(Action action) { var task = ControlledTask.Run(action); ThreadTasks.TryAdd(Thread.CurrentThread, task); }