Пример #1
0
 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);
 }
Пример #2
0
 // 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));
 }
Пример #3
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
                     ));
        }