示例#1
0
 public Action <T, OTasks.ParallelLoopState> WrapBody(Action <T> body)
 {
     return((T t, OTasks.ParallelLoopState ls) =>
     {
         Exception exception = null;
         MChessChess.TraceEvent("body(" + t.ToString() + ")");
         MChessChess.LeaveChess();
         if (OThreading.Thread.CurrentThread == mainthread)
         {
             protectingcontext.Dispose();
         }
         try
         {
             body(t);
         }
         catch (Exception e)     // catch recoverable exception in user code
         {
             exception = e;
         }
         if (OThreading.Thread.CurrentThread == mainthread)
         {
             protectingcontext = _ProtectingThreadContext.Acquire();
         }
         MChessChess.EnterChess();
         if (exception != null)
         {
             global::System.Diagnostics.Debug.Fail("Not implemented: exceptions in Parallel loops");
             throw exception;     // once we implement this we'll rethrow and let TPL catch & aggregate it
         }
     });
 }
示例#2
0
 public static Action <Object> TaskCreateWrapper(ClrSyncManager manager)
 {
     return
         (delegate(Object o)
     {
         try
         {
             TaskArg p = (TaskArg)o;
             p.e.Set();
             manager.ThreadBegin(p.s);
             MChessChess.LeaveChess();
             Exception exception = null;
             try
             {
                 var tryExecuteTask = p.taskScheduler.GetType().GetMethod("TryExecuteTask",
                                                                          global::System.Reflection.BindingFlags.NonPublic |
                                                                          global::System.Reflection.BindingFlags.Instance);
                 tryExecuteTask.Invoke(p.taskScheduler, new object[] { p.task });
             }
             catch (Exception e)     // catch recoverable exception in user code
             {
                 exception = e;
             }
             MChessChess.EnterChess();
             manager.SetMethodInfo("Task.End");
             manager.AggregateSyncVarAccess(
                 new object[] { p.task, ((IAsyncResult)p.task).AsyncWaitHandle },
                 MSyncVarOp.RWEVENT);
             manager.CommitSyncVarAccess();
             if (manager.BreakDeadlockMode)
             {
                 MChessChess.WakeNextDeadlockedThread(false, true);
             }
             else if (exception == null)
             {
                 manager.ThreadEnd(Original::Thread.CurrentThread);
             }
             else
             {
                 manager.Shutdown(exception);
             }
         }
         catch (Exception e)     // catch fatal exception in our code
         {
             manager.Shutdown(e);
         }
     });
 }
示例#3
0
 public static WaitCallback ThreadCreateWrapper(ClrSyncManager manager)
 {
     return
         (delegate(object o)
     {
         try
         {
             ThreadRoutineArg p = (ThreadRoutineArg)o;
             manager.ThreadBegin(p.s);
             MChessChess.LeaveChess();
             Exception exception = null;
             try
             {
                 p.wcb(p.o);
             }
             catch (Exception e)     // catch recoverable exception in user code
             {
                 exception = e;
             }
             MChessChess.EnterChess();
             if (manager.BreakDeadlockMode)
             {
                 MChessChess.WakeNextDeadlockedThread(false, true);
             }
             else if (exception == null)
             {
                 manager.ThreadEnd(Original::Thread.CurrentThread);
             }
             else
             {
                 manager.Shutdown(exception);
             }
         }
         catch (Exception e)     // catch fatal exception in our code
         {
             manager.Shutdown(e);
         }
     });
 }
示例#4
0
 public static Original::ParameterizedThreadStart WrapParamThreadStart(Original::ParameterizedThreadStart del, ClrSyncManager manager)
 {
     return(delegate(object o)
     {
         try
         {
             manager.ThreadBegin(Original::Thread.CurrentThread);
             MChessChess.LeaveChess();
             Exception exception = null;
             try
             {
                 CheckThreadReadyForMonitoring();
                 del(o);
             }
             catch (Exception e) // catch recoverable exception in user code
             {
                 exception = e;
             }
             MChessChess.EnterChess();
             if (manager.BreakDeadlockMode)
             {
                 MChessChess.WakeNextDeadlockedThread(false, true);
             }
             else if (exception == null)
             {
                 manager.ThreadEnd(Original::Thread.CurrentThread);
             }
             else
             {
                 manager.Shutdown(exception);
             }
         }
         catch (Exception e) // catch fatal exception in our code
         {
             manager.Shutdown(e);
         }
     });
 }
示例#5
0
        public static WaitOrTimerCallback RegisterWaitForSingleObjectWrapper(ClrSyncManager manager)
        {
            return
                (delegate(object argument, bool timedOut)
            {
                try
                {
                    global::System.Diagnostics.Debug.Assert(!timedOut);
                    Helper.WaitOrTimerCallbackRoutineArg p = (Helper.WaitOrTimerCallbackRoutineArg)argument;
                    p.a.Set();

                    manager.ThreadBegin(p.s);
                    WaitHandle cancelObject = null;

                    while (true)
                    {
                        manager.SetMethodInfo("RegisteredWaitForSingleObject.CheckCancellation");
                        manager.SyncVarAccess(p, MSyncVarOp.RWVAR_READWRITE);
                        bool cancelled = p.canceled;
                        cancelObject = p.onCancellation;
                        if (cancelled)
                        {
                            p.finished = true;
                        }
                        manager.CommitSyncVarAccess();
                        if (cancelled)
                        {
                            break;
                        }

                        MChessChess.LeaveChess();
                        bool flag = __Substitutions.System.Threading.WaitHandle.WaitOne(p.waitObject, (int)p.millisecondsTimeOutInterval, false);
                        p.callback(p.state, !flag);
                        MChessChess.EnterChess();

                        if (p.executeOnlyOnce)
                        {
                            manager.SetMethodInfo("RegisteredWaitForSingleObject.ReadOnCancellation");
                            manager.SyncVarAccess(p, MSyncVarOp.RWVAR_READWRITE);
                            cancelObject = p.onCancellation;
                            p.finished = true;
                            manager.CommitSyncVarAccess();
                            break;
                        }
                    }

                    MChessChess.LeaveChess();
                    Exception exception = null;
                    try
                    {
                        if (cancelObject != null)
                        {
                            __Substitutions.System.Threading.EventWaitHandle.Set((EventWaitHandle)cancelObject);
                        }
                    }
                    catch (Exception e)     // catch recoverable exception in monitored code
                    {
                        exception = e;
                    }
                    MChessChess.EnterChess();
                    if (manager.BreakDeadlockMode)
                    {
                        MChessChess.WakeNextDeadlockedThread(false, true);
                    }
                    else if (exception == null)
                    {
                        manager.ThreadEnd(Original::Thread.CurrentThread);
                    }
                    else
                    {
                        manager.Shutdown(exception);
                    }
                }
                catch (Exception e)     // catch fatal exception in our code
                {
                    manager.Shutdown(e);
                }
            });
        }
示例#6
0
        public ChessMain(MChessOptions m, Assembly a, string testClassName, string unitTestName)
        {
            this.mco                = m;
            this.testAssembly       = a;
            this.testclass          = testClassName;
            this.unitTestMethodName = unitTestName;
            this.runUnitTest        = !String.IsNullOrEmpty(unitTestMethodName);

            this.manager = new ClrSyncManager(m);
            MChessChess.Init(manager, mco);

            TryLoadReferencedAssemblies(new[] { testAssembly });
            get_entries(testAssembly);
            popups(m);

            this.manager.SetExitCallBack((c, ex) => {
                string msg = "";
                if (ex != null)
                {
                    msg = @"Child thread raised exception
" + ex.Message + @"
Stack trace:
" + ex.StackTrace + @"
";
                    ReportErrorAndExit(msg, c, true, ex);
                }
                ReportErrorAndExitRaw("", c, true, true, null);
            });

            try
            {
                do_startup();

                // print warning if races are disabled
                if (MChessChess.GetExitCode() == 0 && !(mco.preemptAccesses || mco.sober ||
                                                        mco.maxExecutions == 1 || !String.IsNullOrEmpty(mco.enumerateObservations)))
                {
                    MChessChess.ReportWarning("Race Detection Disabled. Races May Hide Bugs.", "", false);
                }

                // RunTest loop
                bool moreToTest = true;
                while (moreToTest)
                {
                    if (!MChessChess.StartTest())
                    {
                        ReportErrorAndExit("Internal failure: CHESS.StartTest failed", ChessExitCode.ChessFailure, false, null);
                    }

                    if (MyEngine.EnvironmentVars.FlipPreemptSense)
                    {
                        MChessChess.PreemptionDisable();
                    }
                    do_run();
                    if (MyEngine.EnvironmentVars.FlipPreemptSense)
                    {
                        MChessChess.PreemptionEnable();
                    }

                    if (manager.BreakDeadlockMode)
                    {
                        MChessChess.EnterChess();
                        MChessChess.WakeNextDeadlockedThread(true, false);
                        // we are now done with the deadlock-breaking mode!
                        Debug.Assert(!MChessChess.IsBreakingDeadlock());
                        manager.BreakDeadlockMode = false;
                        MChessChess.LeaveChess();
                    }
                    moreToTest = MChessChess.EndTest();
                }

                do_shutdown();
            }
            catch (Exception ex)
            {
                string message = @"CHESS internal failure.
" + ex.Message + @"
" + ex.StackTrace + @"
";
                ReportErrorAndExit(message, ChessExitCode.ChessFailure, false, ex);
            }
            ReportErrorAndExit("", (ChessExitCode)MChessChess.GetExitCode(), false, null);
        }
示例#7
0
        // dueTime:  the amount of time to delay before callback is invoked, in milliseconds.
        // Specify Timeout.Infinite to prevent the timer from starting.
        //  Specify zero (0) to start the timer immediately.
        // period: The time interval between invocations of callback, in milliseconds.
        // Specify Timeout.Infinite to disable periodic signaling.

        // The method specified for callback should be reentrant, because it is called on ThreadPool threads.
        // The method can be executed simultaneously on two thread pool threads if the timer interval is less
        // than the time required to execute the method, or if all thread pool threads are in use and the method
        // is queued multiple times.

        public static void TimerCreateWrapper(object start)
        {
            try
            {
                TimerRoutineArg argument = (TimerRoutineArg)start;
                argument.inLoop  = true;
                argument.changed = false;
                argument.parentSemaphore.Release();
                ClrSyncManager manager = ClrSyncManager.SyncManager;
                manager.ThreadBegin(argument.selfSemaphore);
                Exception exception = null;
                while (true)
                {
                    manager.SetMethodInfo("Timer.read");
                    manager.SyncVarAccess(argument.timer, MSyncVarOp.RWVAR_READWRITE);
                    manager.CommitSyncVarAccess();

                    if (timer2tra[argument.timer].disposed)
                    {
                        // the timer only goes away when it is disposed of
                        // it may be disabled, but a Change can reenable it
                        break;
                    }

                    manager.TaskYield();    // until fairness deals with unbounded thread creation
                    manager.TaskYield();    // we yield twice

                    if (!argument.dueTime.Equals(TimeSpan.FromTicks(Timeout.Infinite)))
                    {
                        MChessChess.LeaveChess();
                        try
                        {
                            argument.callback(argument.state);
                        }
                        catch (Exception e) // catch recoverable exception in monitored code
                        {
                            exception = e;
                        }
                        MChessChess.EnterChess();
                        // If period is zero (0) or Infinite and dueTime is not Infinite, callback is invoked once;
                        // the periodic behavior of the timer is disabled, but can be re-enabled using the Change method.
                    }

                    if (exception != null)
                    {
                        break;
                    }

                    if (argument.changed)
                    {
                        argument.changed = false;
                        continue;
                    }

                    if (argument.Period.Equals(TimeSpan.FromTicks(Timeout.Infinite)) || argument.Period.Equals(TimeSpan.FromTicks(0)))
                    {
                        break;
                    }
                }
                argument.inLoop = false;
                if (timer2tra[argument.timer].disposed)
                {
                    timer2tra.Remove(argument.timer);
                }

                if (manager.BreakDeadlockMode)
                {
                    MChessChess.WakeNextDeadlockedThread(false, true);
                }
                else if (exception == null)
                {
                    manager.ThreadEnd(System.Threading.Thread.CurrentThread);
                }
                else
                {
                    manager.Shutdown(exception);
                }
            }
            catch (Exception e) // catch fatal error in our code
            {
                ClrSyncManager manager = ClrSyncManager.SyncManager;
                manager.Shutdown(e);
            }
        }
示例#8
0
 static long not_tracked = 0;  // 0 by default, means thread is *NOT* tracked by CHESS
 public WrapperSentry()
 {
     MChessChess.EnterChess();
 }
示例#9
0
        // variable-range parallel for loop helper
        internal static OTasks.ParallelLoopResult?ParallelForHelper(
            Func <Range> prologue,
            bool singlethread,
            string name,
            global::System.Action <long> body,
            Helper.SimpleDel <OTasks.ParallelLoopResult?> orig)
        {
            return
                (Helper.SimpleContextExposingWrap(
                     delegate(ClrSyncManager manager, ref IDisposable protectingcontext)
            {
                Range range = new Range();

                // do prologue outside chess... and switch protecting context
                MChessChess.LeaveChess();
                protectingcontext.Dispose();
                Exception ex = null;
                try
                {
                    range = prologue();
                }
                catch (Exception e)          // catch recoverable exception in user code
                {
                    ex = e;
                }
                IDisposable pc = _ProtectingThreadContext.Acquire();
                MChessChess.EnterChess();

                if (ex != null)
                {
                    global::System.Diagnostics.Debug.Fail("Not implemented: exceptions in enumerators of Parallel foreach");
                    throw ex;
                }

                if (range.to <= range.from)          // empty loop
                {
                    return orig();
                }

                long split;
                if (!singlethread)
                {
                    split = range.minsplit + manager.Choose((int)(range.maxsplit - range.minsplit + 1));
                }
                else
                {
                    split = (manager.Choose(2) == 0) ? range.minsplit : range.maxsplit;
                }

                MChessChess.TraceEvent(name + "(" + range.from + "," + range.to + "), split " + split);

                SimplePartitioner <long> partitioner = new SimplePartitioner <long>(
                    manager, range.from, range.to, split,
                    (long i) => { return i; },
                    true);

                // store protecting context
                partitioner.protectingcontext = pc;

                // TODO better job here
                OTasks.ParallelOptions options = new OTasks.ParallelOptions();
                options.MaxDegreeOfParallelism = 2;

                OTasks.ParallelLoopResult result = OTasks.Parallel.ForEach <long>(partitioner, options, partitioner.WrapBody(body));

                // switch protecting context back
                partitioner.protectingcontext.Dispose();
                protectingcontext = _ProtectingThreadContext.Acquire();

                return result;
            },
                     orig
                     ));
        }