コード例 #1
0
        public void TestPropertiesCorrect()
        {
            ThreadPoolGlobalQueue q = new ThreadPoolGlobalQueue(100);

            Assert.IsTrue(q.IsBounded);
            Assert.AreEqual(100, q.BoundedCapacity);
            Assert.AreEqual(0, q.OccupiedNodesCount);
            Assert.AreEqual(100, q.FreeNodesCount);
            Assert.AreEqual(100, q.ExtendedCapacity);


            q.RequestCapacityExtension(100);
            Assert.AreEqual(200, q.ExtendedCapacity);

            q.Add(new TestThreadPoolItem(10));
            Assert.AreEqual(1, q.OccupiedNodesCount);
            Assert.AreEqual(200, q.ExtendedCapacity);
            Assert.AreEqual(199, q.FreeNodesCount);

            ThreadPoolWorkItem res = q.Take();

            Assert.AreEqual(0, q.OccupiedNodesCount);
            Assert.AreEqual(199, q.ExtendedCapacity);
            Assert.AreEqual(199, q.FreeNodesCount);
        }
コード例 #2
0
        public void TestIsEmpty()
        {
            ThreadPoolConcurrentQueue q = new ThreadPoolConcurrentQueue();

            Assert.IsTrue(q.IsEmpty);

            for (int i = 0; i < 10000; i++)
            {
                q.Add(new TestThreadPoolItem(i));
                Assert.IsFalse(q.IsEmpty);
            }

            for (int i = 0; i < 10000; i++)
            {
                Assert.IsFalse(q.IsEmpty);
                ThreadPoolWorkItem res = null;
                Assert.IsTrue(q.TryTake(out res));
            }

            Assert.IsTrue(q.IsEmpty);


            ThreadPoolWorkItem tmp = null;

            Assert.IsFalse(q.TryTake(out tmp));
            Assert.IsNull(tmp);
            Assert.IsTrue(q.IsEmpty);
        }
コード例 #3
0
        public void TestSilentTakeCancellation()
        {
            ThreadPoolQueueController q    = new ThreadPoolQueueController(100, 1000);
            CancellationTokenSource   cSrc = new CancellationTokenSource();


            bool takeCompleted           = false;
            bool takeResult              = false;
            ThreadPoolWorkItem takenItem = null;
            int startedFlag              = 0;

            Task.Run(() =>
            {
                Interlocked.Exchange(ref startedFlag, 1);
                var res = q.TryTake(null, out takenItem, -1, cSrc.Token, false);
                Volatile.Write(ref takeResult, res);
                Volatile.Write(ref takeCompleted, true);
            });

            TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1);
            Thread.Sleep(100);
            Assert.IsFalse(takeCompleted);

            cSrc.Cancel();
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref takeCompleted));
            Assert.IsFalse(takeResult);

            Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(1), null, false, 0, CancellationToken.None));
            Assert2.AreEqual(1, q.Take(null));

            Assert.AreEqual(0, q.GlobalQueue.OccupiedNodesCount);
            Assert.AreEqual(100, q.GlobalQueue.FreeNodesCount);
        }
コード例 #4
0
            /// <summary>
            /// Попробовать добавить элемент в сегмент
            /// </summary>
            /// <param name="item">Элемент</param>
            /// <returns>Удалось ли добавить</returns>
            public bool TryAdd(ThreadPoolWorkItem item)
            {
                TurboContract.Requires(item != null, conditionString: "item != null");

                if (!HasFreeSpace(_tail))
                {
                    return(false);
                }

                bool result = false;

                try { }
                finally
                {
                    int tail = Interlocked.Increment(ref _tail) - 1;
                    if (HasFreeSpace(tail))
                    {
                        Volatile.Write(ref _data[tail], item);
                        if (tail == SegmentSize - 1)
                        {
                            Grow();
                        }

                        result = true;
                    }
                }

                return(result);
            }
コード例 #5
0
        /// <summary>
        /// Выборка элемента из головы (может вызываться из любого потока)
        /// </summary>
        /// <param name="item">Выбранный элемент</param>
        /// <returns>Удалось ли сделать выборку</returns>
        public bool TrySteal(out ThreadPoolWorkItem item)
        {
            Contract.Ensures(Contract.Result <bool>() == false || Contract.ValueAtReturn(out item) != null);

            if (HasElements(_head, _tail))
            {
                lock (_syncObj)
                {
                    int head = _head;
                    if (HasElements(head, _tail))
                    {
                        item = Interlocked.Exchange(ref _data[head % QueueSize], null);
                        if (item != null)
                        {
                            //RemoveElementFromHead();
                            _head = head + 1;
                            return(true);
                        }
                    }
                }
            }

            item = null;
            return(false);
        }
コード例 #6
0
        public ThreadPoolWorkItem Take(ThreadPoolLocalQueue localQueue)
        {
            ThreadPoolWorkItem item = null;
            bool result             = TryTake(localQueue, true, true, out item, -1, new CancellationToken(), true);

            TurboContract.Assert(result, "Something went wrong. Take not return any result.");
            return(item);
        }
コード例 #7
0
        /// <summary>
        /// Добавить элемент в очередь
        /// </summary>
        /// <param name="item">Элемент</param>
        public void Add(ThreadPoolWorkItem item)
        {
            TurboContract.Requires(item != null, conditionString: "item != null");

            bool result = TryAdd(item, Timeout.Infinite);

            TurboContract.Assert(result, "Element was not added to ThreadPoolGlobalQueue due to unknown reason");
        }
コード例 #8
0
            public void UnsafeOnCompleted(Action continuation)
            {
#if NETCOREAPP3_1
                ThreadPool.UnsafeQueueUserWorkItem(ThreadPoolWorkItem.Create(continuation), false);
#else
                ThreadPool.UnsafeQueueUserWorkItem(switchToCallback, continuation);
#endif
            }
コード例 #9
0
ファイル: ThreadPool.cs プロジェクト: zmyer/ice
 public void executeNonBlocking(ThreadPoolWorkItem workItem)
 {
     lock (this)
     {
         Debug.Assert(!_destroyed);
         _instance.asyncIOThread().queue(workItem);
     }
 }
コード例 #10
0
        /// <summary>
        /// Добавить элемент в очередь
        /// </summary>
        /// <param name="item">Элемент</param>
        public void Add(ThreadPoolWorkItem item)
        {
            Contract.Requires(item != null);

            bool result = TryAdd(item, Timeout.Infinite);

            Debug.Assert(result, "Element was not added to ThreadPoolGlobalQueue due to unknown reason");
        }
コード例 #11
0
        public ThreadPoolWorkItem Take(ThreadPoolLocalQueue localQueue, CancellationToken token)
        {
            ThreadPoolWorkItem item = null;
            bool result             = TryTake(localQueue, true, true, out item, -1, token, true);

            Debug.Assert(result, "Something went wrong. Take not return any result.");
            return(item);
        }
コード例 #12
0
        private void ThreadProc(ThreadPrivateData privateData, CancellationToken token)
        {
            if (privateData == null)
            {
                throw new InvalidOperationException("privateData for Thread of ThreadPool can't be null");
            }


            ThreadPoolWorkItem currentWorkItem = null;

            try
            {
                while (!token.IsCancellationRequested && !ShouldIDie())
                {
                    if (this.TryTakeWorkItemFromQueue(privateData, out currentWorkItem, Timeout.Infinite, token, false))
                    {
                        this.RunWorkItem(currentWorkItem);
                        currentWorkItem = null;

                        if (_wasSomeProcessByThreadsFlag == false)
                        {
                            _wasSomeProcessByThreadsFlag = true;
                        }
                    }
                    else
                    {
                        TurboContract.Assert(token.IsCancellationRequested, conditionString: "token.IsCancellationRequested");
                    }
                }
            }
            catch (OperationCanceledException)
            {
                if (!token.IsCancellationRequested)
                {
                    throw;
                }
            }


            if (token.IsCancellationRequested)
            {
                if (LetFinishedProcess)
                {
                    while (this.TryTakeWorkItemFromQueue(privateData, out currentWorkItem))
                    {
                        this.RunWorkItem(currentWorkItem);
                    }
                }
                else
                {
                    while (this.TryTakeWorkItemFromQueue(privateData, out currentWorkItem))
                    {
                        this.CancelWorkItem(currentWorkItem);
                    }
                }
            }
        }
コード例 #13
0
ファイル: AsyncIOThread.cs プロジェクト: zk2013/ice
 public void queue(ThreadPoolWorkItem callback)
 {
     lock (this)
     {
         Debug.Assert(!_destroyed);
         _queue.AddLast(callback);
         Monitor.Pulse(this);
     }
 }
コード例 #14
0
ファイル: AsyncIOThread.cs プロジェクト: joshmoore/ice
 public void queue(ThreadPoolWorkItem callback)
 {
     lock(this)
     {
         Debug.Assert(!_destroyed);
         _queue.AddLast(callback);
         System.Threading.Monitor.Pulse(this);
     }
 }
コード例 #15
0
ファイル: ThreadPool.cs プロジェクト: stick/zeroc-ice
        execute(ThreadPoolWorkItem workItem)
        {
            _m.Lock();
            try
            {
                Debug.Assert(!_destroyed);
                if (_workItems.Count == 0)
                {
                    _m.Notify();
                }
                _workItems.Enqueue(workItem);

                //
                // If this is a dynamic thread pool which can still grow and if all threads are
                // currently busy dispatching or about to dispatch, we spawn a new thread to
                // execute this new work item right away.
                //
                if (_threads.Count < _sizeMax &&
                    (_inUse + _workItems.Count) > _threads.Count &&
                    !_destroyed)
                {
                    if (_instance.traceLevels().threadPool >= 1)
                    {
                        string s = "growing " + _prefix + ": Size = " + (_threads.Count + 1);
                        _instance.initializationData().logger.trace(_instance.traceLevels().threadPoolCat, s);
                    }

                    try
                    {
                        WorkerThread t = new WorkerThread(this, _threadPrefix + "-" + _threadIndex++);
#if !SILVERLIGHT
                        if (_hasPriority)
                        {
                            t.start(_priority);
                        }
                        else
                        {
                            t.start(ThreadPriority.Normal);
                        }
#else
                        t.start();
#endif
                        _threads.Add(t);
                    }
                    catch (System.Exception ex)
                    {
                        string s = "cannot create thread for `" + _prefix + "':\n" + ex;
                        _instance.initializationData().logger.error(s);
                    }
                }
            }
            finally
            {
                _m.Unlock();
            }
        }
コード例 #16
0
        public void TestSimpleAddTake()
        {
            ThreadPoolGlobalQueue q = new ThreadPoolGlobalQueue(100);

            Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(10), 0, CancellationToken.None));
            ThreadPoolWorkItem res = null;

            Assert.IsTrue(q.TryTake(out res, 0, CancellationToken.None, true));
            Assert2.AreEqual(10, res);
        }
コード例 #17
0
        /// <summary>
        /// Забрать элемент из очереди
        /// </summary>
        /// <returns>Полученный элемент</returns>
        public ThreadPoolWorkItem Take()
        {
            Contract.Ensures(Contract.Result <ThreadPoolWorkItem>() != null);

            ThreadPoolWorkItem result = null;
            bool success = TryTake(out result, Timeout.Infinite, new CancellationToken(), true);

            Debug.Assert(success, "Element was not taken from ThreadPoolGlobalQueue due to unknown reason");
            return(result);
        }
コード例 #18
0
        public void TestSimpleAddTake()
        {
            ThreadPoolQueueController q = new ThreadPoolQueueController(100, 1000);

            Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(10), null, false, 0, CancellationToken.None));
            ThreadPoolWorkItem res = null;

            Assert.IsTrue(q.TryTake(null, out res, 0, CancellationToken.None, true));
            Assert2.AreEqual(10, res);
        }
コード例 #19
0
        /// <summary>
        /// Places a new task to the thread pool queue
        /// </summary>
        /// <param name="item">Thread pool work item</param>
        protected sealed override void AddWorkItem(ThreadPoolWorkItem item)
        {
            CheckDisposed();
            if (IsAddingCompleted)
            {
                throw new InvalidOperationException("Adding was completed for ThreadPool: " + Name);
            }

            this.PrepareWorkItem(item);
            this.AddWorkItemToQueue(item);
        }
コード例 #20
0
        public void TestSingleAddTake()
        {
            ThreadPoolConcurrentQueue q = new ThreadPoolConcurrentQueue();

            q.Add(new TestThreadPoolItem(10));
            ThreadPoolWorkItem res = null;

            Assert.IsTrue(q.TryTake(out res));
            Assert.IsNotNull(res);
            Assert2.AreEqual(10, res);
        }
コード例 #21
0
        public void TestSingleAddSteal()
        {
            ThreadPoolLocalQueue q = new ThreadPoolLocalQueue();

            Assert.IsTrue(q.TryAddLocal(new TestThreadPoolItem(1)));
            ThreadPoolWorkItem item = null;

            Assert.IsTrue(q.TrySteal(out item));
            Assert.IsNotNull(item);
            Assert2.AreEqual(1, item);
        }
コード例 #22
0
        /// <summary>
        /// Форсировать добавление элемента в главную очередь (игнорирует ограничения по размеру)
        /// </summary>
        /// <param name="item">Элемент</param>
        public void ForceAdd(ThreadPoolWorkItem item)
        {
            Contract.Requires(item != null);

            _mainQueue.Add(item);
            if (_freeNodes != null)
            {
                UpdateExtendedCapacityRequestField(1);
            }
            _occupiedNodes.Release();
        }
コード例 #23
0
ファイル: ThreadPool.cs プロジェクト: stick/zeroc-ice
 executeNonBlocking(ThreadPoolWorkItem workItem)
 {
     _m.Lock();
     try
     {
         Debug.Assert(!_destroyed);
         _instance.asyncIOThread().queue(workItem);
     }
     finally
     {
         _m.Unlock();
     }
 }
コード例 #24
0
        /// <summary>
        /// Добавить элемент в очередь
        /// </summary>
        /// <param name="item">Элемент</param>
        public void Add(ThreadPoolWorkItem item)
        {
            Contract.Requires(item != null);

            SpinWait sw   = new SpinWait();
            Segment  tail = _tail;

            while (!tail.TryAdd(item))
            {
                sw.SpinOnce();
                tail = _tail;
            }
        }
コード例 #25
0
        /// <summary>
        /// Places a new task to the thread pool queue
        /// </summary>
        /// <param name="item">Thread pool work item</param>
        protected sealed override void AddWorkItem(ThreadPoolWorkItem item)
        {
            TurboContract.Requires(item != null, conditionString: "item != null");

            CheckDisposed();
            if (IsAddingCompleted)
            {
                throw new InvalidOperationException("Adding was completed for ThreadPool: " + Name);
            }

            this.PrepareWorkItem(item);
            this.AddWorkItemToQueue(item);
        }
コード例 #26
0
        /// <summary>
        /// Добавить элемент в очередь
        /// </summary>
        /// <param name="item">Элемент</param>
        public void Add(ThreadPoolWorkItem item)
        {
            TurboContract.Requires(item != null, conditionString: "item != null");

            SpinWait sw   = new SpinWait();
            Segment  tail = _tail;

            while (!tail.TryAdd(item))
            {
                sw.SpinOnce();
                tail = _tail;
            }
        }
コード例 #27
0
        public bool TryTakeItem(ThreadPoolThreadLocals local, out ThreadPoolWorkItem item)
        {
            Contract.Ensures(Contract.Result <bool>() == false || Contract.ValueAtReturn(out item) != null);
            Debug.Assert(!_isDisposed);

            if (local != null)
            {
                return(_queues.TryTake(local.LocalQueue, out item, 0, new CancellationToken(), true));
            }
            else
            {
                return(_queues.TryTake(null, out item, 0, new CancellationToken(), true));
            }
        }
コード例 #28
0
 public void queue(ThreadPoolWorkItem callback)
 {
     _m.Lock();
     try
     {
         Debug.Assert(!_destroyed);
         _queue.AddLast(callback);
         _m.Notify();
     }
     finally
     {
         _m.Unlock();
     }
 }
コード例 #29
0
ファイル: AsyncIOThread.cs プロジェクト: 2008hatake/zeroc-ice
 public void queue(ThreadPoolWorkItem callback)
 {
     _m.Lock();
     try
     {
         Debug.Assert(!_destroyed);
         _queue.AddLast(callback);
         _m.Notify();
     }
     finally
     {
         _m.Unlock();
     }
 }
コード例 #30
0
        // ================


        /// <summary>
        /// Переместить все элементы из локальной очереди в общую
        /// </summary>
        /// <param name="localQueue">Локальная очередь</param>
        public void MoveItemsFromLocalQueueToGlobal(ThreadPoolLocalQueue localQueue)
        {
            TurboContract.Requires(localQueue != null, conditionString: "localQueue != null");
            TurboContract.Assert(!_isDisposed, conditionString: "!_isDisposed");

            try { }
            finally
            {
                ThreadPoolWorkItem item = null;
                while (localQueue.TrySteal(out item))
                {
                    _globalQueue.ForceAdd(item);
                }
            }
        }
コード例 #31
0
        public bool TryAddItem(ThreadPoolWorkItem item, bool forceGlobal)
        {
            Contract.Requires(item != null);
            Debug.Assert(!_isDisposed);

            ThreadPoolLocalQueue localQueue = null;

            if (!forceGlobal)
            {
                ThreadPoolThreadLocals threadLocal = _perThreadData.Value;
                localQueue = threadLocal != null ? threadLocal.LocalQueue : null;
            }

            return(_queues.TryAdd(item, localQueue, forceGlobal));
        }
コード例 #32
0
        /// <summary>
        /// Добавить элемент в очередь
        /// </summary>
        /// <param name="item">Элемент</param>
        /// <param name="localQueue">Локальная очередь (если есть)</param>
        /// <param name="forceGlobal">Обязательное добавление в глобальную очередь</param>
        public void Add(ThreadPoolWorkItem item, ThreadPoolLocalQueue localQueue, bool forceGlobal)
        {
            TurboContract.Requires(item != null, conditionString: "item != null");
            TurboContract.Assert(!_isDisposed, conditionString: "!_isDisposed");

            try { }
            finally
            {
                if (forceGlobal || localQueue == null || !localQueue.TryAddLocal(item))
                {
                    bool addToMainRes = _globalQueue.TryAdd(item, -1);
                    TurboContract.Assert(addToMainRes, conditionString: "addToMainRes");
                }
            }
        }
コード例 #33
0
ファイル: ThreadPool.cs プロジェクト: bholl/zeroc-ice
        execute(ThreadPoolWorkItem workItem)
        {
            _m.Lock();
            try
            {
                Debug.Assert(!_destroyed);
                if(_workItems.Count == 0)
                {
                    _m.Notify();
                }
                _workItems.Enqueue(workItem);

                //
                // If this is a dynamic thread pool which can still grow and if all threads are
                // currently busy dispatching or about to dispatch, we spawn a new thread to 
                // execute this new work item right away.
                //
                if(_threads.Count < _sizeMax && 
                   (_inUse + _workItems.Count) > _threads.Count &&
                   !_destroyed)
                {
                    if(_instance.traceLevels().threadPool >= 1)
                    {
                        string s = "growing " + _prefix + ": Size = " + (_threads.Count + 1);
                        _instance.initializationData().logger.trace(_instance.traceLevels().threadPoolCat, s);
                    }
                    
                    try
                    {
                        WorkerThread t = new WorkerThread(this, _threadPrefix + "-" + _threadIndex++);
                        if(_hasPriority)
                        {
                            t.start(_priority);
                        }
                        else
                        {
                            t.start(ThreadPriority.Normal);
                        }
                        _threads.Add(t);
                    }
                    catch(System.Exception ex)
                    {
                        string s = "cannot create thread for `" + _prefix + "':\n" + ex;
                        _instance.initializationData().logger.error(s);
                    }
                }
            }
            finally
            {
                _m.Unlock();
            }
        }
コード例 #34
0
 public void executeNonBlocking(ThreadPoolWorkItem workItem)
 {
     lock(this)
     {
         Debug.Assert(!_destroyed);
         _instance.asyncIOThread().queue(workItem);
     }
 }
コード例 #35
0
ファイル: ThreadPool.cs プロジェクト: bholl/zeroc-ice
 executeNonBlocking(ThreadPoolWorkItem workItem)
 {
     _m.Lock();
     try
     {
         Debug.Assert(!_destroyed);
         _instance.asyncIOThread().queue(workItem);
     }
     finally
     {
         _m.Unlock();
     }
 }