コード例 #1
0
        /* ------------  composite operations ------------------- */


        /// <summary> Main runloop
        ///
        /// </summary>

        private void DoStart()
        {
            try
            {
                while (!Interrupted)
                {
                    FJTask task = pop();
                    if (task != null)
                    {
                        if (!task.Done)
                        {
                            // inline FJTask.invoke
                            if (CollectStats)
                            {
                                ++runs;
                            }
                            task.Run();
                            task.SetDone();
                        }
                    }
                    else
                    {
                        scanWhileIdling();
                    }
                }
            }
            finally
            {
                group_.Inactive = this;
            }
        }
コード例 #2
0
        /// <summary> Process tasks until w is done.
        /// Equivalent to <code>while(!w.isDone()) taskYield(); </code>
        ///
        /// </summary>

        protected internal void  taskJoin(FJTask w)
        {
            while (!w.Done)
            {
                FJTask task = pop();
                if (task != null)
                {
                    if (!task.Done)
                    {
                        if (CollectStats)
                        {
                            ++runs;
                        }
                        task.Run();
                        task.SetDone();
                        if (task == w)
                        {
                            return;                              // fast exit if we just ran w
                        }
                    }
                }
                else
                {
                    scan(w);
                }
            }
        }
コード例 #3
0
        /// <summary> Enqueue task at base of DEQ.
        /// Called ONLY by current thread.
        /// This method is currently not called from class FJTask. It could be used
        /// as a faster way to do FJTask.start, but most users would
        /// find the semantics too confusing and unpredictable.
        ///
        /// </summary>

        protected internal void  put(FJTask r)
        {
            lock (this)
            {
                for (; ;)
                {
                    int b = base_Renamed - 1;
                    if (top < b + deq.Length)
                    {
                        int newBase = b & (deq.Length - 1);
                        deq[newBase].Put(r);
                        base_Renamed = newBase;

                        if (b != newBase)
                        {
                            // Adjust for index underflow
                            int newTop = top & (deq.Length - 1);
                            if (newTop < newBase)
                            {
                                newTop += deq.Length;
                            }
                            top = newTop;
                        }
                        return;
                    }
                    else
                    {
                        checkOverflow();
                        // ... and retry
                    }
                }
            }
        }
コード例 #4
0
ファイル: FJTask.cs プロジェクト: denise-amiga/diddy
 /// <summary>
 /// Runs this instance.
 /// </summary>
 public override void  Run()
 {
     for (int i = 0; i < tasks.Length; ++i)
     {
         FJTask.Invoke(tasks[i]);
     }
 }
コード例 #5
0
        /// <summary> Handle slow case for push
        ///
        /// </summary>

        protected internal virtual void  slowPush(FJTask r)
        {
            lock (this)
            {
                checkOverflow();
                push(r);                 // just recurse -- this one is sure to succeed.
            }
        }
コード例 #6
0
ファイル: FJTask.cs プロジェクト: denise-amiga/diddy
        /// <summary> Immediately execute task t by calling its run method. Has no
        /// effect if t has already been run or has been cancelled.
        /// It is equivalent to  calling t.run except that it
        /// deals with completion status, so should always be used
        /// instead of directly calling run.
        /// The method can be useful
        /// when a computation has been packaged as a FJTask, but you just need to
        /// directly execute its body from within some other task.
        ///
        /// </summary>

        public static void  Invoke(FJTask t)
        {
            if (!t.Done)
            {
                t.Run();
                t.SetDone();
            }
        }
コード例 #7
0
        /// <summary> A specialized expansion of
        /// <code> w.fork(); invoke(v); w.join(); </code>
        ///
        /// </summary>


        protected internal void  coInvoke(FJTask w, FJTask v)
        {
            // inline  push

            int t = top;

            if (t < (base_Renamed & (deq.Length - 1)) + deq.Length)
            {
                deq[t & (deq.Length - 1)].Put(w);
                top = t + 1;

                // inline  invoke

                if (!v.Done)
                {
                    if (CollectStats)
                    {
                        ++runs;
                    }
                    v.Run();
                    v.SetDone();
                }

                // inline  taskJoin

                while (!w.Done)
                {
                    FJTask task = pop();
                    if (task != null)
                    {
                        if (!task.Done)
                        {
                            if (CollectStats)
                            {
                                ++runs;
                            }
                            task.Run();
                            task.SetDone();
                            if (task == w)
                            {
                                return;                                  // fast exit if we just ran w
                            }
                        }
                    }
                    else
                    {
                        scan(w);
                    }
                }
            }
            // handle non-inlinable cases
            else
            {
                slowCoInvoke(w, v);
            }
        }
コード例 #8
0
 /// <summary>
 /// Specialized form of execute called only from within FJTasks
 /// </summary>
 public virtual void ExecuteTask(FJTask t)
 {
     try
     {
         entryQueue.Put(t);
         SignalNewTask();
     }
     catch (System.Threading.ThreadInterruptedException)
     {
         ThreadClass.Current.Interrupt();
     }
 }
コード例 #9
0
 /// <summary>
 /// <see cref="IRunnable"/>
 /// </summary>
 public override void  Run()
 {
     try
     {
         if (wrapped is FJTask)
         {
             FJTask.Invoke((FJTask)(wrapped));
         }
         else
         {
             wrapped.Run();
         }
     }
     finally
     {
         SetTerminated();
     }
 }
コード例 #10
0
        /// <summary> Execute a task in this thread. Generally called when current task
        /// cannot otherwise continue.
        ///
        /// </summary>


        protected internal void  taskYield()
        {
            FJTask task = pop();

            if (task != null)
            {
                if (!task.Done)
                {
                    if (CollectStats)
                    {
                        ++runs;
                    }
                    task.Run();
                    task.SetDone();
                }
            }
            else
            {
                scan(null);
            }
        }
コード例 #11
0
        /* ------------ DEQ operations ------------------- */


        /// <summary> Push a task onto DEQ.
        /// Called ONLY by current thread.
        ///
        /// </summary>

        protected internal void  push(FJTask r)
        {
            int t = top;

            /*
             * This test catches both overflows and index wraps.  It doesn't
             * really matter if base value is in the midst of changing in take.
             * As long as deq length is < 2^30, we are guaranteed to catch wrap in
             * time since base can only be incremented at most length times
             * between pushes (or puts).
             */

            if (t < (base_Renamed & (deq.Length - 1)) + deq.Length)
            {
                deq[t & (deq.Length - 1)].Put(r);
                top = t + 1;
            }
            // isolate slow case to increase chances push is inlined
            else
            {
                slowPush(r);                 // check overflow and retry
            }
        }
コード例 #12
0
ファイル: FJTaskRunner.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary>Set the reference *</summary>
 internal void Put(FJTask r)
 {
     ref_ = r;
 }
コード例 #13
0
        /// <summary> Backup to handle noninlinable cases of coInvoke
        ///
        /// </summary>

        protected internal virtual void  slowCoInvoke(FJTask w, FJTask v)
        {
            push(w);             // let push deal with overflow
            FJTask.Invoke(v);
            taskJoin(w);
        }
コード例 #14
0
        /// <summary> Same as scan, but called when current thread is idling.
        /// It repeatedly scans other threads for tasks,
        /// sleeping while none are available.
        /// <p>
        /// This differs from scan mainly in that
        /// since there is no reason to return to recheck any
        /// condition, we iterate until a task is found, backing
        /// off via sleeps if necessary.
        /// </p>
        ///
        /// </summary>

        protected internal virtual void  scanWhileIdling()
        {
            FJTask task = null;

            bool lowered = false;
            long iters   = 0;

            FJTaskRunner[] ts  = group_.Array;
            int            idx = victimRNG.Next(ts.Length);

            do
            {
                for (int i = 0; i < ts.Length; ++i)
                {
                    FJTaskRunner t = ts[idx];
                    if (++idx >= ts.Length)
                    {
                        idx = 0;                         // circularly traverse
                    }
                    if (t != null && t != this)
                    {
                        if (CollectStats)
                        {
                            ++scans;
                        }

                        task = t.take();
                        if (task != null)
                        {
                            if (CollectStats)
                            {
                                ++steals;
                            }
                            if (lowered)
                            {
                                Priority = (ThreadPriority)runPriority_;
                            }
                            group_.SetActive(this);
                            break;
                        }
                    }
                }

                if (task == null)
                {
                    if (Interrupted)
                    {
                        return;
                    }

                    if (CollectStats)
                    {
                        ++scans;
                    }
                    task = group_.PollEntryQueue(this);

                    if (task != null)
                    {
                        if (CollectStats)
                        {
                            ++steals;
                        }
                        if (lowered)
                        {
                            Priority = (ThreadPriority)runPriority_;
                        }
                        group_.SetActive(this);
                    }
                    else
                    {
                        ++iters;
                        //  Check here for yield vs sleep to avoid entering group synch lock
                        if (iters >= FJTaskRunnerGroup.ScansPerSleep)
                        {
                            group_.CheckActive(this, iters);
                            if (Interrupted)
                            {
                                return;
                            }
                        }
                        else if (!lowered)
                        {
                            lowered  = true;
                            Priority = (ThreadPriority)scanPriority_;
                        }
                        else
                        {
                            Thread.Sleep(0);
                        }
                    }
                }
            }while (task == null);


            if (!task.Done)
            {
                if (CollectStats)
                {
                    ++runs;
                }
                task.Run();
                task.SetDone();
            }
        }
コード例 #15
0
ファイル: FJTaskRunner.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> Handle slow case for push
 /// 
 /// </summary>
 protected internal virtual void slowPush(FJTask r)
 {
     lock (this)
     {
         checkOverflow();
         push(r); // just recurse -- this one is sure to succeed.
     }
 }
コード例 #16
0
ファイル: FJTaskRunner.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> Backup to handle noninlinable cases of coInvoke
 /// 
 /// </summary>
 protected internal virtual void slowCoInvoke(FJTask w, FJTask v)
 {
     push(w); // let push deal with overflow
     FJTask.Invoke(v);
     taskJoin(w);
 }
コード例 #17
0
ファイル: FJTaskRunner.cs プロジェクト: nobuyukinyuu/diddy
        /// <summary> Enqueue task at base of DEQ.
        /// Called ONLY by current thread.
        /// This method is currently not called from class FJTask. It could be used
        /// as a faster way to do FJTask.start, but most users would
        /// find the semantics too confusing and unpredictable.
        /// 
        /// </summary>
        protected internal void put(FJTask r)
        {
            lock (this)
            {
                for (; ; )
                {
                    int b = base_Renamed - 1;
                    if (top < b + deq.Length)
                    {

                        int newBase = b & (deq.Length - 1);
                        deq[newBase].Put(r);
                        base_Renamed = newBase;

                        if (b != newBase)
                        {
                            // Adjust for index underflow
                            int newTop = top & (deq.Length - 1);
                            if (newTop < newBase)
                                newTop += deq.Length;
                            top = newTop;
                        }
                        return ;
                    }
                    else
                    {
                        checkOverflow();
                        // ... and retry
                    }
                }
            }
        }
コード例 #18
0
ファイル: FJTaskRunner.cs プロジェクト: nobuyukinyuu/diddy
        /// <summary> Array-based version of coInvoke
        /// 
        /// </summary>
        protected internal void coInvoke(FJTask[] tasks)
        {
            int nforks = tasks.Length - 1;

            // inline bulk push of all but one task

            int t = top;

            if (nforks >= 0 && t + nforks < (base_Renamed & (deq.Length - 1)) + deq.Length)
            {
                for (int i = 0; i < nforks; ++i)
                {
                    deq[t++ & (deq.Length - 1)].Put(tasks[i]);
                    top = t;
                }

                // inline invoke of one task
                FJTask v = tasks[nforks];
                if (!v.Done)
                {
                    if (CollectStats)
                        ++runs;
                    v.Run();
                    v.SetDone();
                }

                // inline  taskJoins

                for (int i = 0; i < nforks; ++i)
                {
                    FJTask w = tasks[i];
                    while (!w.Done)
                    {

                        FJTask task = pop();
                        if (task != null)
                        {
                            if (!task.Done)
                            {
                                if (CollectStats)
                                    ++runs;
                                task.Run();
                                task.SetDone();
                            }
                        }
                        else
                            scan(w);
                    }
                }
            }
            // handle non-inlinable cases
            else
                slowCoInvoke(tasks);
        }
コード例 #19
0
ファイル: FJTask.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> Construct and return a FJTask object that, when executed, will
 /// invoke the tasks in the tasks array in parallel using coInvoke
 /// 
 /// </summary>
 public static FJTask NewPar(FJTask[] tasks, FJTaskRunner runner)
 {
     return new Par(tasks);
 }
コード例 #20
0
ファイル: FJTask.cs プロジェクト: denise-amiga/diddy
 /// <summary>
 /// Two-task constructor, for compatibility with previous release.
 /// </summary>
 public Seq(FJTask task1, FJTask task2)
     : this(new FJTask[] { task1, task2 })
 {
 }
コード例 #21
0
ファイル: FJTask.cs プロジェクト: denise-amiga/diddy
 /// <summary> Fork both tasks and then wait for their completion. It behaves as:
 /// <pre>
 /// task1.fork(); task2.fork(); task2.join(); task1.join();
 /// </pre>
 /// As a simple classic example, here is
 /// a class that computes the Fibonacci function:
 /// <pre>
 /// public class Fib extends FJTask {
 ///
 /// // Computes fibonacci(n) = fibonacci(n-1) + fibonacci(n-2);  for n> 1
 /// //          fibonacci(0) = 0;
 /// //          fibonacci(1) = 1.
 ///
 /// // Value to compute fibonacci function for.
 /// // It is replaced with the answer when computed.
 /// private volatile int number;
 ///
 /// public Fib(int n) { number = n; }
 ///
 /// public int getAnswer() {
 /// if (!isDone()) throw new Error("Not yet computed");
 /// return number;
 /// }
 ///
 /// public void run() {
 /// int n = number;
 /// if (n > 1) {
 /// Fib f1 = new Fib(n - 1);
 /// Fib f2 = new Fib(n - 2);
 ///
 /// coInvoke(f1, f2); // run these in parallel
 ///
 /// // we know f1 and f2 are computed, so just directly access numbers
 /// number = f1.number + f2.number;
 /// }
 /// }
 ///
 /// public static void main(String[] args) { // sample driver
 /// try {
 /// int groupSize = 2;    // 2 worker threads
 /// int num = 35;         // compute fib(35)
 /// FJTaskRunnerGroup group = new FJTaskRunnerGroup(groupSize);
 /// Fib f = new Fib(num);
 /// group.invoke(f);
 /// int result = f.getAnswer();
 /// System.out.println(" Answer: " + result);
 /// }
 /// catch (InterruptedException ex) {
 /// System.out.println("Interrupted");
 /// }
 /// }
 /// }
 /// </pre>
 ///
 /// </summary>
 public void  CoInvoke(FJTask task1, FJTask task2)
 {
     FJTaskRunner.coInvoke(task1, task2);
 }
コード例 #22
0
        /// <summary> Array-based version of coInvoke
        ///
        /// </summary>

        protected internal void  coInvoke(FJTask[] tasks)
        {
            int nforks = tasks.Length - 1;

            // inline bulk push of all but one task

            int t = top;

            if (nforks >= 0 && t + nforks < (base_Renamed & (deq.Length - 1)) + deq.Length)
            {
                for (int i = 0; i < nforks; ++i)
                {
                    deq[t++ & (deq.Length - 1)].Put(tasks[i]);
                    top = t;
                }

                // inline invoke of one task
                FJTask v = tasks[nforks];
                if (!v.Done)
                {
                    if (CollectStats)
                    {
                        ++runs;
                    }
                    v.Run();
                    v.SetDone();
                }

                // inline  taskJoins

                for (int i = 0; i < nforks; ++i)
                {
                    FJTask w = tasks[i];
                    while (!w.Done)
                    {
                        FJTask task = pop();
                        if (task != null)
                        {
                            if (!task.Done)
                            {
                                if (CollectStats)
                                {
                                    ++runs;
                                }
                                task.Run();
                                task.SetDone();
                            }
                        }
                        else
                        {
                            scan(w);
                        }
                    }
                }
            }
            // handle non-inlinable cases
            else
            {
                slowCoInvoke(tasks);
            }
        }
コード例 #23
0
 /// <summary>Set the reference *</summary>
 internal void  Put(FJTask r)
 {
     ref_ = r;
 }
コード例 #24
0
 /// <summary>Return the reference and clear it *</summary>
 internal FJTask Take()
 {
     FJTask r = ref_; ref_ = null; return(r);
 }
コード例 #25
0
ファイル: FJTaskRunner.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary>Return the reference and clear it *</summary>
 internal FJTask Take()
 {
     FJTask r = ref_; ref_ = null; return r;
 }
コード例 #26
0
ファイル: FJTask.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> Construct and return a FJTask object that, when executed, will
 /// invoke task1 and task2, in order
 /// 
 /// </summary>
 public static FJTask NewSeq(FJTask task1, FJTask task2, FJTaskRunner fjTaskRunner)
 {
     return new Seq2(task1, task2);
 }
コード例 #27
0
ファイル: FJTaskRunner.cs プロジェクト: nobuyukinyuu/diddy
        /// <summary> A specialized expansion of
        /// <code> w.fork(); invoke(v); w.join(); </code>
        /// 
        /// </summary>
        protected internal void coInvoke(FJTask w, FJTask v)
        {
            // inline  push

            int t = top;
            if (t < (base_Renamed & (deq.Length - 1)) + deq.Length)
            {

                deq[t & (deq.Length - 1)].Put(w);
                top = t + 1;

                // inline  invoke

                if (!v.Done)
                {
                    if (CollectStats)
                        ++runs;
                    v.Run();
                    v.SetDone();
                }

                // inline  taskJoin

                while (!w.Done)
                {
                    FJTask task = pop();
                    if (task != null)
                    {
                        if (!task.Done)
                        {
                            if (CollectStats)
                                ++runs;
                            task.Run();
                            task.SetDone();
                            if (task == w)
                                return ; // fast exit if we just ran w
                        }
                    }
                    else
                        scan(w);
                }
            }
            // handle non-inlinable cases
            else
                slowCoInvoke(w, v);
        }
コード例 #28
0
ファイル: FJTask.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> Fork all tasks in array, and await their completion.
 /// Behaviorally equivalent to:
 /// <pre>
 /// for (int i = 0; i &lt; tasks.length; ++i) tasks[i].fork();
 /// for (int i = 0; i &lt; tasks.length; ++i) tasks[i].join();
 /// </pre>
 /// 
 /// </summary>
 public void CoInvoke(FJTask[] tasks)
 {
     FJTaskRunner.coInvoke(tasks);
 }
コード例 #29
0
ファイル: FJTaskRunner.cs プロジェクト: nobuyukinyuu/diddy
        /* ------------ DEQ operations ------------------- */
        /// <summary> Push a task onto DEQ.
        /// Called ONLY by current thread.
        /// 
        /// </summary>
        protected internal void push(FJTask r)
        {
            int t = top;

            /*
            This test catches both overflows and index wraps.  It doesn't
            really matter if base value is in the midst of changing in take.
            As long as deq length is < 2^30, we are guaranteed to catch wrap in
            time since base can only be incremented at most length times
            between pushes (or puts).
            */

            if (t < (base_Renamed & (deq.Length - 1)) + deq.Length)
            {

                deq[t & (deq.Length - 1)].Put(r);
                top = t + 1;
            }
            // isolate slow case to increase chances push is inlined
            else
                slowPush(r); // check overflow and retry
        }
コード例 #30
0
ファイル: FJTask.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> Two-task constructor, for compatibility with previous release.
 /// 
 /// </summary>
 public Par(FJTask task1, FJTask task2)
 {
     this.tasks = new FJTask[]{task1, task2};
 }
コード例 #31
0
ファイル: FJTaskRunner.cs プロジェクト: nobuyukinyuu/diddy
        /* ------------ Scheduling  ------------------- */
        /// <summary> Do all but the pop() part of yield or join, by
        /// traversing all DEQs in our group looking for a task to
        /// steal. If none, it checks the entry queue. 
        /// <p>
        /// Since there are no good, portable alternatives,
        /// we rely here on a mixture of Thread.yield and priorities
        /// to reduce wasted spinning, even though these are
        /// not well defined. We are hoping here that the JVM
        /// does something sensible.
        /// </p>
        /// </summary>
        /// <param name="waitingFor">if non-null, the current task being joined
        /// 
        /// </param>
        protected internal virtual void scan(FJTask waitingFor)
        {
            FJTask task = null;

            // to delay lowering priority until first failure to steal
            bool lowered = false;

            /*
            Circularly traverse from a random start index.

            This differs slightly from cilk version that uses a random index
            for each attempted steal.
            Exhaustive scanning might impede analytic tractablity of
            the scheduling policy, but makes it much easier to deal with
            startup and shutdown.
            */

            FJTaskRunner[] ts = group_.Array;
            int idx = victimRNG.Next(ts.Length);

            for (int i = 0; i < ts.Length; ++i)
            {

                FJTaskRunner t = ts[idx];
                if (++idx >= ts.Length)
                    idx = 0; // circularly traverse

                if (t != null && t != this)
                {

                    if (waitingFor != null && waitingFor.Done)
                    {
                        break;
                    }
                    else
                    {
                        if (CollectStats)
                            ++scans;
                        task = t.take();
                        if (task != null)
                        {
                            if (CollectStats)
                                ++steals;
                            break;
                        }
                        else
                        {
                            if (Interrupted)
                            {
                                break;
                            }
                            else if (!lowered)
                            {
                                // if this is first fail, lower priority
                                lowered = true;
                                Priority = (ThreadPriority) scanPriority_;
                            }
                            else
                            {
                                // otherwise we are at low priority; just yield
                                Thread.Sleep(0);
                            }
                        }
                    }
                }
            }

            if (task == null)
            {
                if (CollectStats)
                    ++scans;
                task = group_.PollEntryQueue(this);
                if (CollectStats)
                    if (task != null)
                        ++steals;
            }

            if (lowered)
            {
                Priority = (ThreadPriority) runPriority_;
            }

            if (task != null && !task.Done)
            {
                if (CollectStats)
                    ++runs;
                task.Run();
                task.SetDone();
            }
        }
コード例 #32
0
ファイル: FJTask.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> Construct a Seq that, when executed, will process each of the
 /// tasks in the tasks array in order
 /// 
 /// </summary>
 public Seq(FJTask[] tasks)
 {
     this.tasks = tasks;
 }
コード例 #33
0
ファイル: FJTaskRunner.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> Backup to handle atypical or noninlinable cases of coInvoke
 /// 
 /// </summary>
 protected internal virtual void slowCoInvoke(FJTask[] tasks)
 {
     for (int i = 0; i < tasks.Length; ++i)
         push(tasks[i]);
     for (int i = 0; i < tasks.Length; ++i)
         taskJoin(tasks[i]);
 }
コード例 #34
0
ファイル: FJTask.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary>
 /// Creates a new <see cref="Seq2"/> instance.
 /// </summary>
 /// <param name="task1">Task1.</param>
 /// <param name="task2">Task2.</param>
 public Seq2(FJTask task1, FJTask task2)
 {
     fst = task1;
     snd = task2;
 }
コード例 #35
0
ファイル: FJTask.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> Immediately execute task t by calling its run method. Has no
 /// effect if t has already been run or has been cancelled.
 /// It is equivalent to  calling t.run except that it
 /// deals with completion status, so should always be used
 /// instead of directly calling run.
 /// The method can be useful
 /// when a computation has been packaged as a FJTask, but you just need to 
 /// directly execute its body from within some other task.
 /// 
 /// </summary>
 public static void Invoke(FJTask t)
 {
     if (!t.Done)
     {
         t.Run();
         t.SetDone();
     }
 }
コード例 #36
0
        /* ------------ Scheduling  ------------------- */


        /// <summary> Do all but the pop() part of yield or join, by
        /// traversing all DEQs in our group looking for a task to
        /// steal. If none, it checks the entry queue.
        /// <p>
        /// Since there are no good, portable alternatives,
        /// we rely here on a mixture of Thread.yield and priorities
        /// to reduce wasted spinning, even though these are
        /// not well defined. We are hoping here that the JVM
        /// does something sensible.
        /// </p>
        /// </summary>
        /// <param name="waitingFor">if non-null, the current task being joined
        ///
        /// </param>

        protected internal virtual void  scan(FJTask waitingFor)
        {
            FJTask task = null;

            // to delay lowering priority until first failure to steal
            bool lowered = false;

            /*
             * Circularly traverse from a random start index.
             *
             * This differs slightly from cilk version that uses a random index
             * for each attempted steal.
             * Exhaustive scanning might impede analytic tractablity of
             * the scheduling policy, but makes it much easier to deal with
             * startup and shutdown.
             */

            FJTaskRunner[] ts  = group_.Array;
            int            idx = victimRNG.Next(ts.Length);

            for (int i = 0; i < ts.Length; ++i)
            {
                FJTaskRunner t = ts[idx];
                if (++idx >= ts.Length)
                {
                    idx = 0;                     // circularly traverse
                }
                if (t != null && t != this)
                {
                    if (waitingFor != null && waitingFor.Done)
                    {
                        break;
                    }
                    else
                    {
                        if (CollectStats)
                        {
                            ++scans;
                        }
                        task = t.take();
                        if (task != null)
                        {
                            if (CollectStats)
                            {
                                ++steals;
                            }
                            break;
                        }
                        else
                        {
                            if (Interrupted)
                            {
                                break;
                            }
                            else if (!lowered)
                            {
                                // if this is first fail, lower priority
                                lowered  = true;
                                Priority = (ThreadPriority)scanPriority_;
                            }
                            else
                            {
                                // otherwise we are at low priority; just yield
                                Thread.Sleep(0);
                            }
                        }
                    }
                }
            }

            if (task == null)
            {
                if (CollectStats)
                {
                    ++scans;
                }
                task = group_.PollEntryQueue(this);
                if (CollectStats)
                {
                    if (task != null)
                    {
                        ++steals;
                    }
                }
            }

            if (lowered)
            {
                Priority = (ThreadPriority)runPriority_;
            }

            if (task != null && !task.Done)
            {
                if (CollectStats)
                {
                    ++runs;
                }
                task.Run();
                task.SetDone();
            }
        }
コード例 #37
0
ファイル: FJTask.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> Construct and return a FJTask object that, when executed, will
 /// invoke the tasks in the tasks array in array order
 /// </summary>		
 public static FJTask NewSeq(FJTask[] tasks, FJTaskRunner fjTaskRunner)
 {
     return new Seq(tasks);
 }
コード例 #38
0
ファイル: FJTask.cs プロジェクト: denise-amiga/diddy
 /// <summary> Two-task constructor, for compatibility with previous release.
 ///
 /// </summary>
 public Par(FJTask task1, FJTask task2)
 {
     this.tasks = new FJTask[] { task1, task2 };
 }
コード例 #39
0
ファイル: FJTask.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> Fork both tasks and then wait for their completion. It behaves as:
 /// <pre>
 /// task1.fork(); task2.fork(); task2.join(); task1.join();
 /// </pre>
 /// As a simple classic example, here is
 /// a class that computes the Fibonacci function:
 /// <pre>
 /// public class Fib extends FJTask {
 /// 
 /// // Computes fibonacci(n) = fibonacci(n-1) + fibonacci(n-2);  for n> 1
 /// //          fibonacci(0) = 0; 
 /// //          fibonacci(1) = 1.       
 /// 
 /// // Value to compute fibonacci function for.
 /// // It is replaced with the answer when computed.
 /// private volatile int number;
 /// 
 /// public Fib(int n) { number = n; }
 /// 
 /// public int getAnswer() {
 /// if (!isDone()) throw new Error("Not yet computed");
 /// return number;
 /// }
 /// 
 /// public void run() {
 /// int n = number;
 /// if (n > 1) {
 /// Fib f1 = new Fib(n - 1);
 /// Fib f2 = new Fib(n - 2);
 /// 
 /// coInvoke(f1, f2); // run these in parallel
 /// 
 /// // we know f1 and f2 are computed, so just directly access numbers
 /// number = f1.number + f2.number;
 /// }
 /// }
 /// 
 /// public static void main(String[] args) { // sample driver
 /// try {
 /// int groupSize = 2;    // 2 worker threads
 /// int num = 35;         // compute fib(35)
 /// FJTaskRunnerGroup group = new FJTaskRunnerGroup(groupSize);
 /// Fib f = new Fib(num);
 /// group.invoke(f);
 /// int result = f.getAnswer();
 /// System.out.println(" Answer: " + result);
 /// }
 /// catch (InterruptedException ex) {
 /// System.out.println("Interrupted");
 /// }
 /// }
 /// }
 /// </pre>
 /// 
 /// </summary>
 public void CoInvoke(FJTask task1, FJTask task2)
 {
     FJTaskRunner.coInvoke(task1, task2);
 }
コード例 #40
0
ファイル: FJTask.cs プロジェクト: denise-amiga/diddy
 /// <summary>
 /// Creates a new <see cref="Seq2"/> instance.
 /// </summary>
 /// <param name="task1">Task1.</param>
 /// <param name="task2">Task2.</param>
 public Seq2(FJTask task1, FJTask task2)
 {
     fst = task1;
     snd = task2;
 }
コード例 #41
0
ファイル: FJTask.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> Construct a Seq that, when executed, will process each of the
 /// tasks in the tasks array in parallel
 /// 
 /// </summary>
 public Par(FJTask[] tasks)
 {
     this.tasks = tasks;
 }
コード例 #42
0
ファイル: FJTask.cs プロジェクト: denise-amiga/diddy
 /// <summary>
 /// Invoke first and second task
 /// </summary>
 public override void  Run()
 {
     FJTask.Invoke(fst);
     FJTask.Invoke(snd);
 }
コード例 #43
0
ファイル: FJTask.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary>
 /// Creates a new <see cref="Par2"/> instance.
 /// </summary>
 /// <param name="task1">Task1.</param>
 /// <param name="task2">Task2.</param>
 public Par2(FJTask task1, FJTask task2)
 {
     fst = task1;
     snd = task2;
 }
コード例 #44
0
ファイル: FJTask.cs プロジェクト: denise-amiga/diddy
 /// <summary>
 /// Creates a new <see cref="Par2"/> instance.
 /// </summary>
 /// <param name="task1">Task1.</param>
 /// <param name="task2">Task2.</param>
 public Par2(FJTask task1, FJTask task2)
 {
     fst = task1;
     snd = task2;
 }
コード例 #45
0
ファイル: FJTask.cs プロジェクト: nobuyukinyuu/diddy
 /// <summary> 
 /// Two-task constructor, for compatibility with previous release.
 /// </summary>
 public Seq(FJTask task1, FJTask task2)
     : this(new FJTask[]{task1, task2})
 {
 }
コード例 #46
0
ファイル: FJTask.cs プロジェクト: denise-amiga/diddy
 /// <summary> Construct and return a FJTask object that, when executed, will
 /// invoke task1 and task2, in parallel
 ///
 /// </summary>
 public static FJTask NewPar(FJTask task1, FJTask task2, FJTaskRunner fjTaskRunner)
 {
     return(new Par2(task1, task2));
 }
コード例 #47
0
 /// <summary> 
 /// Specialized form of execute called only from within FJTasks
 /// </summary>
 public virtual void ExecuteTask(FJTask t)
 {
     try
     {
         entryQueue.Put(t);
         SignalNewTask();
     }
     catch (System.Threading.ThreadInterruptedException)
     {
         ThreadClass.Current.Interrupt();
     }
 }
コード例 #48
0
ファイル: FJTaskRunner.cs プロジェクト: nobuyukinyuu/diddy
        /// <summary> Process tasks until w is done.
        /// Equivalent to <code>while(!w.isDone()) taskYield(); </code>
        /// 
        /// </summary>
        protected internal void taskJoin(FJTask w)
        {
            while (!w.Done)
            {

                FJTask task = pop();
                if (task != null)
                {
                    if (!task.Done)
                    {
                        if (CollectStats)
                            ++runs;
                        task.Run();
                        task.SetDone();
                        if (task == w)
                            return ; // fast exit if we just ran w
                    }
                }
                else
                    scan(w);
            }
        }