public static void StartHelper(Original::Thread t, object o, bool parameterized) { Helper.SimpleDel <bool> common = delegate() { if (parameterized) { t.Start(o); } else { t.Start(); } return(false); }; Helper.SimpleWrap <bool>( delegate(ClrSyncManager manager) { ChessTask child = manager.TaskFork(); Original.Semaphore childSem = new Original.Semaphore(0, 1); manager.RegisterTaskSemaphore(child, childSem, true); manager.AddChildHandle(child, t); manager.TaskResume(child); common(); return(false); }, common); }
// fixed-range parallel for loop helper internal static OTasks.ParallelLoopResult?ParallelForHelper( long from, long to, bool singlethread, long minsplit, long maxsplit, string name, global::System.Action <long> body, Helper.SimpleDel <OTasks.ParallelLoopResult?> orig) { return(ParallelForHelper(() => new Range(from, to, minsplit, maxsplit), singlethread, name, body, orig)); }
// 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 )); }