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); }
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); }
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); }
/// <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); }
/// <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); }
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); }
/// <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"); }
public void UnsafeOnCompleted(Action continuation) { #if NETCOREAPP3_1 ThreadPool.UnsafeQueueUserWorkItem(ThreadPoolWorkItem.Create(continuation), false); #else ThreadPool.UnsafeQueueUserWorkItem(switchToCallback, continuation); #endif }
public void executeNonBlocking(ThreadPoolWorkItem workItem) { lock (this) { Debug.Assert(!_destroyed); _instance.asyncIOThread().queue(workItem); } }
/// <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"); }
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); }
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); } } } }
public void queue(ThreadPoolWorkItem callback) { lock (this) { Debug.Assert(!_destroyed); _queue.AddLast(callback); Monitor.Pulse(this); } }
public void queue(ThreadPoolWorkItem callback) { lock(this) { Debug.Assert(!_destroyed); _queue.AddLast(callback); System.Threading.Monitor.Pulse(this); } }
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(); } }
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); }
/// <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); }
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); }
/// <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); }
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); }
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); }
/// <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(); }
executeNonBlocking(ThreadPoolWorkItem workItem) { _m.Lock(); try { Debug.Assert(!_destroyed); _instance.asyncIOThread().queue(workItem); } finally { _m.Unlock(); } }
/// <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; } }
/// <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); }
/// <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; } }
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)); } }
public void queue(ThreadPoolWorkItem callback) { _m.Lock(); try { Debug.Assert(!_destroyed); _queue.AddLast(callback); _m.Notify(); } finally { _m.Unlock(); } }
// ================ /// <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); } } }
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)); }
/// <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"); } } }
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(); } }
public void executeNonBlocking(ThreadPoolWorkItem workItem) { lock(this) { Debug.Assert(!_destroyed); _instance.asyncIOThread().queue(workItem); } }