Beispiel #1
0
        /// <summary>
        /// Returns the next controlled operation to schedule.
        /// </summary>
        /// <param name="ops">The set of available operations.</param>
        /// <param name="current">The currently scheduled operation.</param>
        /// <param name="isYielding">True if the current operation is yielding, else false.</param>
        /// <param name="next">The next operation to schedule.</param>
        /// <returns>True if there is a next choice, else false.</returns>
        internal bool GetNextOperation(IEnumerable <ControlledOperation> ops, ControlledOperation current,
                                       bool isYielding, out ControlledOperation next)
        {
            // Filter out any operations that cannot be scheduled.
            var enabledOps = ops.Where(op => op.Status is OperationStatus.Enabled);

            if (enabledOps.Any())
            {
                // Invoke any installed schedule reducers.
                foreach (var reducer in this.Reducers)
                {
                    var reducedOps = reducer.ReduceOperations(enabledOps, current);
                    if (reducedOps.Any())
                    {
                        enabledOps = reducedOps;
                    }
                }

                // Invoke the strategy to choose the next operation.
                if (this.Strategy is InterleavingStrategy strategy &&
                    strategy.GetNextOperation(enabledOps, current, isYielding, out next))
                {
                    this.Trace.AddSchedulingChoice(next.Id);
                    return(true);
                }
            }

            next = null;
            return(false);
        }
Beispiel #2
0
 /// <summary>
 /// Signals the specified waiting operation that the resource has been released.
 /// </summary>
 internal void Signal(ControlledOperation op)
 {
     if (this.AwaitingOperations.Contains(op))
     {
         op.Status = OperationStatus.Enabled;
         this.AwaitingOperations.Remove(op);
     }
 }
Beispiel #3
0
        /// <summary>
        /// Explores a possible interleaving due to a 'WRITE' operation on the specified shared state.
        /// </summary>
        /// <param name="state">The shared state that is being written represented as a string.</param>
        /// <param name="comparer">
        /// Checks if the written shared state is equal with another shared state that is being accessed concurrently.
        /// </param>
        public static void Write(string state, IEqualityComparer <string> comparer = default)
        {
            var runtime = CoyoteRuntime.Current;

            if (runtime.SchedulingPolicy is SchedulingPolicy.Interleaving)
            {
                ControlledOperation op = runtime.GetExecutingOperation();
                op.LastAccessedSharedState = state;
                runtime.ScheduleNextOperation(SchedulingPointType.Write, isSuppressible: false);
                op.LastAccessedSharedState = string.Empty;
            }
        }
Beispiel #4
0
        /// <summary>
        /// Returns the next integer choice.
        /// </summary>
        /// <param name="current">The currently scheduled operation.</param>
        /// <param name="maxValue">The max value.</param>
        /// <param name="next">The next integer choice.</param>
        /// <returns>True if there is a next choice, else false.</returns>
        internal bool GetNextIntegerChoice(ControlledOperation current, int maxValue, out int next)
        {
            if (this.Strategy is InterleavingStrategy strategy &&
                strategy.GetNextIntegerChoice(current, maxValue, out next))
            {
                this.Trace.AddNondeterministicIntegerChoice(next);
                return(true);
            }

            next = 0;
            return(false);
        }
Beispiel #5
0
        /// <inheritdoc/>
        public IEnumerable <ControlledOperation> ReduceOperations(IEnumerable <ControlledOperation> ops,
                                                                  ControlledOperation current)
        {
            // Find all operations that are not invoking a user-defined scheduling decision.
            var noUserDefinedSchedulingOps = ops.Where(
                op => !SchedulingPoint.IsUserDefined(op.LastSchedulingPoint));

            if (noUserDefinedSchedulingOps.Any())
            {
                // One or more operations exist that are not invoking a user-defined
                // scheduling decision, so return them.
                return(noUserDefinedSchedulingOps);
            }
            else
            {
                // Split the operations that are accessing shared state into a 'READ' and 'WRITE' group.
                var readAccessOps  = ops.Where(op => op.LastSchedulingPoint is SchedulingPointType.Read);
                var writeAccessOps = ops.Where(op => op.LastSchedulingPoint is SchedulingPointType.Write);

                // Update the known 'READ' and 'WRITE' access sets so far.
                this.ReadAccesses.UnionWith(readAccessOps.Select(op => op.LastAccessedSharedState));
                this.WriteAccesses.UnionWith(writeAccessOps.Select(op => op.LastAccessedSharedState));

                // Find if any operations are explicitly interleaving, and if yes do not perform any reduction.
                if (!ops.Any(op => op.LastSchedulingPoint is SchedulingPointType.Interleave ||
                             op.LastSchedulingPoint is SchedulingPointType.Yield))
                {
                    // Find if there are any read-only accesses. Note that this is just an approximation
                    // based on current knowledge. An access that is considered read-only might not be
                    // considered anymore in later steps or iterations once the known 'READ' and 'WRITE'
                    // access sets have been updated.
                    var readOnlyAccessOps = readAccessOps.Where(op => !this.WriteAccesses.Any(
                                                                    state => state.StartsWith(op.LastAccessedSharedState) ||
                                                                    op.LastAccessedSharedState.StartsWith(state)));
                    if (readOnlyAccessOps.Any())
                    {
                        // Return all read-only access operations.
                        return(readOnlyAccessOps);
                    }
                }
            }

            return(ops);
        }
Beispiel #6
0
 /// <summary>
 /// Returns the next delay.
 /// </summary>
 /// <param name="ops">Operations executing during the current test iteration.</param>
 /// <param name="current">The operation requesting the delay.</param>
 /// <param name="maxValue">The max value.</param>
 /// <param name="next">The next delay.</param>
 /// <returns>True if there is a next delay, else false.</returns>
 internal bool GetNextDelay(IEnumerable <ControlledOperation> ops, ControlledOperation current,
                            int maxValue, out int next) =>
 (this.Strategy as FuzzingStrategy).GetNextDelay(ops, current, maxValue, out next);