Ejemplo n.º 1
0
        public ThreadWorker(IScheduler sched, ThreadWorker[] others, IProducerConsumerCollection <Task> sharedWorkQueue,
                            bool createThread, int maxStackSize, ThreadPriority priority)
        {
            this.others = others;

            this.dDeque = new CyclicDeque <Task> ();

            this.sharedWorkQueue = sharedWorkQueue;
            this.workerLength    = others.Length;
            this.isLocal         = !createThread;

            this.childWorkAdder = delegate(Task t) {
                dDeque.PushBottom(t);
                sched.PulseAll();
            };

            // Find the stealing start index randomly (then the traversal
            // will be done in Round-Robin fashion)
            do
            {
                this.stealingStart = r.Next(0, workerLength);
            } while (others[stealingStart] == this);

            InitializeUnderlyingThread(maxStackSize, priority);
        }
Ejemplo n.º 2
0
		public ThreadWorker (IScheduler sched, ThreadWorker[] others, IProducerConsumerCollection<Task> sharedWorkQueue,
		                     bool createThread, int maxStackSize, ThreadPriority priority)
		{
			this.others          = others;

//			if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("USE_CYCLIC"))) {
//				Console.WriteLine ("Using cyclic deque");
//				this.dDeque = new CyclicDeque<Task> ();
//			} else {
//				this.dDeque = new DynamicDeque<Task> ();
//			}
			this.dDeque = new CyclicDeque<Task> ();
			
			this.sharedWorkQueue = sharedWorkQueue;
			this.workerLength    = others.Length;
			this.isLocal         = !createThread;
			
			this.childWorkAdder = delegate (Task t) { 
				dDeque.PushBottom (t);
				sched.PulseAll ();
			};
			
			// Find the stealing start index randomly (then the traversal
			// will be done in Round-Robin fashion)
			do {
				this.stealingStart = r.Next(0, workerLength);
			} while (others[stealingStart] == this);
			
			InitializeUnderlyingThread (maxStackSize, priority);
		}
Ejemplo n.º 3
0
		public ThreadWorker (IScheduler sched, ThreadWorker[] others, IProducerConsumerCollection<Task> sharedWorkQueue,
		                     bool createThread, int maxStackSize, ThreadPriority priority, EventWaitHandle handle)
		{
			this.others          = others;

			this.dDeque = new CyclicDeque<Task> ();
			
			this.sharedWorkQueue = sharedWorkQueue;
			this.workerLength    = others.Length;
			this.isLocal         = !createThread;
			this.waitHandle      = handle;
			
			this.childWorkAdder = delegate (Task t) { 
				dDeque.PushBottom (t);
				sched.PulseAll ();
			};
			
			// Find the stealing start index randomly (then the traversal
			// will be done in Round-Robin fashion)
			do {
				this.stealingStart = r.Next(0, workerLength);
			} while (others[stealingStart] == this);
			
			InitializeUnderlyingThread (maxStackSize, priority);
		}
Ejemplo n.º 4
0
        public ThreadWorker(IScheduler sched, ThreadWorker[] others, IProducerConsumerCollection <Task> sharedWorkQueue,
                            bool createThread, int maxStackSize, ThreadPriority priority)
        {
            this.others = others;

//			if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("USE_CYCLIC"))) {
//				Console.WriteLine ("Using cyclic deque");
//				this.dDeque = new CyclicDeque<Task> ();
//			} else {
//				this.dDeque = new DynamicDeque<Task> ();
//			}
            this.dDeque = new CyclicDeque <Task> ();

            this.sharedWorkQueue = sharedWorkQueue;
            this.workerLength    = others.Length;
            this.isLocal         = !createThread;

            this.childWorkAdder = delegate(Task t) {
                dDeque.PushBottom(t);
                sched.PulseAll();
            };

            // Find the stealing start index randomly (then the traversal
            // will be done in Round-Robin fashion)
            do
            {
                this.stealingStart = r.Next(0, workerLength);
            } while (others[stealingStart] == this);

            InitializeUnderlyingThread(maxStackSize, priority);
        }
Ejemplo n.º 5
0
        // Main method, used to do all the logic of retrieving, processing and stealing work.
        bool WorkerMethod()
        {
            bool result = false;
            bool hasStolenFromOther;

            do
            {
                hasStolenFromOther = false;

                Task value;

                // We fill up our work deque concurrently with other ThreadWorker
                while (sharedWorkQueue.Count > 0)
                {
                    while (sharedWorkQueue.TryTake(out value))
                    {
                        dDeque.PushBottom(value);
                    }

                    // Now we process our work
                    while (dDeque.PopBottom(out value) == PopResult.Succeed)
                    {
                        if (value != null)
                        {
                            value.Execute(childWorkAdder);
                            result = true;
                        }
                    }
                }

                // When we have finished, steal from other worker
                ThreadWorker other;

                // Repeat the operation a little so that we can let other things process.
                for (int j = 0; j < maxRetry; j++)
                {
                    // Start stealing with the ThreadWorker at our right to minimize contention
                    for (int it = stealingStart; it < stealingStart + workerLength; it++)
                    {
                        int i = it % workerLength;
                        if ((other = others [i]) == null || other == this)
                        {
                            continue;
                        }

                        // Maybe make this steal more than one item at a time, see TODO.
                        if (other.dDeque.PopTop(out value) == PopResult.Succeed)
                        {
                            hasStolenFromOther = true;
                            if (value != null)
                            {
                                value.Execute(childWorkAdder);
                                result = true;
                            }
                        }
                    }
                }
            } while (sharedWorkQueue.Count > 0 || hasStolenFromOther);

            return(result);
        }