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
         }
     });
 }
Beispiel #2
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
                     ));
        }
Beispiel #3
0
 public static void TraceEvent(string info)
 {
     using (new WrapperSentry())
         MChessChess.TraceEvent(info);
 }