예제 #1
0
 /// <summary>
 /// Constructor called only during FJTaskRunnerGroup initialization
 /// </summary>
 protected internal FJTaskRunner(FJTaskRunnerGroup g)
 {
     deq           = VolatileTaskRef.NewArray(INITIAL_CAPACITY);
     barrier       = new Object();
     scanPriority_ = FJTaskRunnerGroup.DefaultScanPriority;
     group_        = g;
     victimRNG     = new Random(this.GetHashCode());
 }
예제 #2
0
 /// <summary> Initialization utility for constructing arrays.
 /// Make an array of given capacity and fill it with
 /// VolatileTaskRefs.
 ///
 /// </summary>
 internal static VolatileTaskRef[] NewArray(int cap)
 {
     VolatileTaskRef[] a = new VolatileTaskRef[cap];
     for (int k = 0; k < cap; k++)
     {
         a[k] = new VolatileTaskRef();
     }
     return(a);
 }
예제 #3
0
        /// <summary> Adjust top and base, and grow DEQ if necessary.
        /// Called only while DEQ synch lock being held.
        /// We don't expect this to be called very often. In most
        /// programs using FJTasks, it is never called.
        /// 
        /// </summary>
        protected internal virtual void checkOverflow()
        {
            int t = top;
            int b = base_Renamed;

            if (t - b < deq.Length - 1)
            {
                // check if just need an index reset

                int newBase = b & (deq.Length - 1);
                int newTop = top & (deq.Length - 1);
                if (newTop < newBase)
                    newTop += deq.Length;
                top = newTop;
                base_Renamed = newBase;

                /*
                Null out refs to stolen tasks.
                This is the only time we can safely do it.
                */

                int i = newBase;
                while (i != newTop && deq[i].ref_ != null)
                {
                    deq[i].ref_ = null;
                    i = (i - 1) & (deq.Length - 1);
                }
            }
            else
            {
                // grow by doubling array

                int newTop = t - b;
                int oldcap = deq.Length;
                int newcap = oldcap * 2;

                if (newcap >= MAX_CAPACITY)
                    throw new ApplicationException("FJTask queue maximum capacity exceeded");

                VolatileTaskRef[] newdeq = new VolatileTaskRef[newcap];

                // copy in bottom half of new deq with refs from old deq
                for (int j = 0; j < oldcap; ++j)
                    newdeq[j] = deq[b++ & (oldcap - 1)];

                // fill top half of new deq with new refs
                for (int j = oldcap; j < newcap; ++j)
                    newdeq[j] = new VolatileTaskRef();

                deq = newdeq;
                base_Renamed = 0;
                top = newTop;
            }
        }
예제 #4
0
 /// <summary> Initialization utility for constructing arrays. 
 /// Make an array of given capacity and fill it with
 /// VolatileTaskRefs.
 /// 
 /// </summary>
 internal static VolatileTaskRef[] NewArray(int cap)
 {
     VolatileTaskRef[] a = new VolatileTaskRef[cap];
     for (int k = 0; k < cap; k++)
         a[k] = new VolatileTaskRef();
     return a;
 }
예제 #5
0
        /// <summary> Adjust top and base, and grow DEQ if necessary.
        /// Called only while DEQ synch lock being held.
        /// We don't expect this to be called very often. In most
        /// programs using FJTasks, it is never called.
        ///
        /// </summary>

        protected internal virtual void  checkOverflow()
        {
            int t = top;
            int b = base_Renamed;

            if (t - b < deq.Length - 1)
            {
                // check if just need an index reset

                int newBase = b & (deq.Length - 1);
                int newTop  = top & (deq.Length - 1);
                if (newTop < newBase)
                {
                    newTop += deq.Length;
                }
                top          = newTop;
                base_Renamed = newBase;

                /*
                 * Null out refs to stolen tasks.
                 * This is the only time we can safely do it.
                 */

                int i = newBase;
                while (i != newTop && deq[i].ref_ != null)
                {
                    deq[i].ref_ = null;
                    i           = (i - 1) & (deq.Length - 1);
                }
            }
            else
            {
                // grow by doubling array

                int newTop = t - b;
                int oldcap = deq.Length;
                int newcap = oldcap * 2;

                if (newcap >= MAX_CAPACITY)
                {
                    throw new ApplicationException("FJTask queue maximum capacity exceeded");
                }

                VolatileTaskRef[] newdeq = new VolatileTaskRef[newcap];

                // copy in bottom half of new deq with refs from old deq
                for (int j = 0; j < oldcap; ++j)
                {
                    newdeq[j] = deq[b++ & (oldcap - 1)];
                }

                // fill top half of new deq with new refs
                for (int j = oldcap; j < newcap; ++j)
                {
                    newdeq[j] = new VolatileTaskRef();
                }

                deq          = newdeq;
                base_Renamed = 0;
                top          = newTop;
            }
        }