/// <summary> /// Захватить лучший элемент из доступных /// </summary> /// <param name="element">Захваченный элемент</param> /// <returns>Удалось ли захватить</returns> private bool TryTakeBest(out PoolElementWrapper <T> element) { TurboContract.Ensures((TurboContract.Result <bool>() == false && TurboContract.ValueAtReturn(out element) == null) || (TurboContract.Result <bool>() == true && TurboContract.ValueAtReturn(out element) != null && TurboContract.ValueAtReturn(out element).IsBusy)); PoolElementWrapper <T> b1, b2, b3; PoolElementWrapper <T> earlyStopResult = FindBest3WithStopping(out b1, out b2, out b3); if (earlyStopResult != null) { TurboContract.Assert(earlyStopResult.IsBusy, conditionString: "earlyStopResult.IsBusy"); element = earlyStopResult; return(true); } if (b1 != null && b1.TryMakeBusyAtomic() && !b1.IsRemoved) { element = b1; return(true); } if (b2 != null && b2.TryMakeBusyAtomic() && !b2.IsRemoved) { element = b2; return(true); } if (b3 != null && b3.TryMakeBusyAtomic() && !b3.IsRemoved) { element = b3; return(true); } element = null; return(false); }
/// <summary> /// Выборка элемента из головы (может вызываться из любого потока) /// </summary> /// <param name="item">Выбранный элемент</param> /// <returns>Удалось ли сделать выборку</returns> public bool TrySteal(out ThreadPoolWorkItem item) { TurboContract.Ensures(TurboContract.Result <bool>() == false || TurboContract.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); }
/// <summary>Code contracts</summary> public bool TryGetAssociation(T key, out LifetimeBase val) { TurboContract.Ensures((TurboContract.Result <bool>() == true && TurboContract.ValueAtReturn <LifetimeBase>(out val) != null) || (TurboContract.Result <bool>() == false && TurboContract.ValueAtReturn <LifetimeBase>(out val) == null)); throw new NotImplementedException(); }
// ===================== /// <summary> /// Попробовать выполнить похищение элемента из соседних локальных очередей /// </summary> /// <param name="localQueue">Локальная очередь текущего потока</param> /// <param name="otherLocalQueues">Разреженный массив локальных очередей других потоков</param> /// <param name="item">Выбранный элемент</param> /// <returns>Удалось ли сделать выборку</returns> private bool TryTakeFromOtherLocalQueues(ThreadPoolLocalQueue localQueue, ThreadPoolLocalQueue[] otherLocalQueues, out ThreadPoolWorkItem item) { TurboContract.Requires(otherLocalQueues != null, conditionString: "otherLocalQueues != null"); TurboContract.Ensures(TurboContract.Result <bool>() == false || TurboContract.ValueAtReturn(out item) != null); bool result = false; item = null; try { } finally { int length = otherLocalQueues.Length; int index = Interlocked.Increment(ref _stealIndex) & int.MaxValue; for (int i = 0; i < length; i++, index++) { var otherQueue = Volatile.Read(ref otherLocalQueues[index % length]); if (otherQueue != null && otherQueue != localQueue && otherQueue.TrySteal(out item)) { result = true; break; } } } return(result); }
protected override bool TryGetAssociationInner(T key, out LifetimeBase val) { TurboContract.Requires(key != null, conditionString: "key != null"); TurboContract.Ensures((TurboContract.Result <bool>() == true && TurboContract.ValueAtReturn <LifetimeBase>(out val) != null) || (TurboContract.Result <bool>() == false && TurboContract.ValueAtReturn <LifetimeBase>(out val) == null)); throw new NotImplementedException(); }
public bool TryTakeItem(ThreadPoolThreadLocals local, bool doLocalSearch, bool doWorkSteal, out ThreadPoolWorkItem item, int timeout, CancellationToken token, bool throwOnCancellation) { TurboContract.Ensures(TurboContract.Result <bool>() == false || TurboContract.ValueAtReturn(out item) != null); TurboContract.Assert(!_isDisposed, conditionString: "!_isDisposed"); if (local != null) { return(_queues.TryTake(local.LocalQueue, doLocalSearch, doWorkSteal, out item, timeout, token, throwOnCancellation)); } else { return(_queues.TryTake(null, doLocalSearch, doWorkSteal, out item, timeout, token, throwOnCancellation)); } }
public bool TryTakeItem(ThreadPoolThreadLocals local, out ThreadPoolWorkItem item) { TurboContract.Ensures(TurboContract.Result <bool>() == false || TurboContract.ValueAtReturn(out item) != null); TurboContract.Assert(!_isDisposed, conditionString: "!_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)); } }
/// <summary> /// Попробовать достать элемент из очереди /// </summary> /// <param name="item">Выбранный элемент</param> /// <returns>Удалось ли выбрать</returns> public bool TryTake(out ThreadPoolWorkItem item) { TurboContract.Ensures(TurboContract.Result <bool>() == false || TurboContract.ValueAtReturn(out item) != null); while (this.HasElements()) { Segment head = _head; if (head.TryTake(out item)) { return(true); } } item = null; return(false); }
/// <summary> /// Выборка элемента из хвоста (должно вызываться из потока-владельца) /// </summary> /// <param name="item">Выбранный элемент</param> /// <returns>Удалось ли сделать выборку</returns> public bool TryTakeLocal(out ThreadPoolWorkItem item) { TurboContract.Ensures(TurboContract.Result <bool>() == false || TurboContract.ValueAtReturn(out item) != null); int tail = _tail; if (HasElements(_head, tail)) { item = Interlocked.Exchange(ref _data[(tail - 1) % QueueSize], null); if (item != null) { //RemoveElementFromTail(); _tail = tail - 1; return(true); } } item = null; return(false); }
/// <summary> /// Попытаться выбрать элемент из сегмента /// </summary> /// <param name="item">Выбранный элемент</param> /// <returns>Удалось ли сделать выборку</returns> public bool TryTake(out ThreadPoolWorkItem item) { TurboContract.Ensures(TurboContract.Result <bool>() == false || TurboContract.ValueAtReturn(out item) != null); SpinWait sw = new SpinWait(); int head = _head; while (HasElements(head, _tail)) { if (Interlocked.CompareExchange(ref _head, head + 1, head) == head) { SpinWait itemSw = new SpinWait(); ThreadPoolWorkItem localItem = null; while ((localItem = Volatile.Read(ref _data[head])) == null) { itemSw.SpinOnce(); } item = localItem; Volatile.Write(ref _data[head], null); if (head + 1 >= SegmentSize) { SpinWait headSw = new SpinWait(); while (_next == null) { headSw.SpinOnce(); } _parent._head = _next; } return(true); } sw.SpinOnce(); head = _head; } item = null; return(false); }
/// <summary> /// Attempts to resolve the object held by the container. /// Resolution can fail when required injection objects not found /// </summary> /// <param name="resolver">Injection resolver to acquire parameters</param> /// <param name="val">Resolved instance of the object</param> /// <returns>True if the object was successfully resolved</returns> public bool TryGetInstance(IInjectionResolver resolver, out object val) { TurboContract.Requires(resolver != null, conditionString: "resolver != null"); TurboContract.Ensures((TurboContract.Result <bool>() == true && ((TurboContract.ValueAtReturn(out val) != null && TurboContract.ValueAtReturn(out val).GetType() == this.OutputType) || (TurboContract.ValueAtReturn(out val) == null && this.OutputType.IsAssignableFromNull()))) || (TurboContract.Result <bool>() == false && TurboContract.ValueAtReturn(out val) == null)); try { val = GetInstance(resolver); return(true); } catch (CommonIoCException) { } catch (KeyNotFoundException) { } val = null; return(false); }
/// <summary> /// Попытаться выбрать элемент /// </summary> /// <param name="localQueue">Локальная очередь (если есть)</param> /// <param name="doLocalSearch">Делать ли поиск в локальной очереди</param> /// <param name="doWorkSteal">Разрешено ли похищение работы</param> /// <param name="item">Выбранный элемент</param> /// <param name="timeout">Таймаут</param> /// <param name="token">Токен отмены</param> /// <param name="throwOnCancellation">Выбрасывать ли исключение при отмене по токену</param> /// <returns>Удалось ли выбрать</returns> public bool TryTake(ThreadPoolLocalQueue localQueue, bool doLocalSearch, bool doWorkSteal, out ThreadPoolWorkItem item, int timeout, CancellationToken token, bool throwOnCancellation) { TurboContract.Ensures(TurboContract.Result <bool>() == false || TurboContract.ValueAtReturn(out item) != null); TurboContract.Assert(!_isDisposed, conditionString: "!_isDisposed"); // Пробуем выбрать из локальной очереди if (doLocalSearch && localQueue != null) { bool taken = false; try { } finally { taken = localQueue.TryTakeLocal(out item); } if (taken) { return(true); } } // Если нельзя делать похищение, то сразу забираем из очереди if (!doWorkSteal) { return(_globalQueue.TryTake(out item, timeout, token, throwOnCancellation)); } // Пытаемся выбрать из общей очереди (если не удаётся, то нужно проверить возможность похищения) if (_globalQueue.TryTake(out item, 0, new CancellationToken(), false)) { return(true); } // Пытаемся похитить элемент if (TryTakeFromOtherLocalQueues(localQueue, _localQueues, out item)) { return(true); } if (timeout == 0) { // Попытки не дали результатов => выходим item = null; return(false); } // Если не нужно просыпаться для похищения, то просто выбриаем из общей очереди if (_stealAwakePeriod <= 0) { return(_globalQueue.TryTake(out item, timeout, token, throwOnCancellation)); } if (timeout < 0) { // Если таймаут не ограничен, то выбираем из основной осереди и периодически пытаемся похитить while (true) { if (token.IsCancellationRequested) { break; } if (_globalQueue.TryTake(out item, _stealAwakePeriod, token, throwOnCancellation)) { return(true); } if (token.IsCancellationRequested) { break; } if (TryTakeFromOtherLocalQueues(localQueue, _localQueues, out item)) { return(true); } } } else { // Делаем замеры таймаута uint startTime = GetTimestamp(); int restTime = timeout; while (restTime > 0) { if (token.IsCancellationRequested) { break; } if (_globalQueue.TryTake(out item, Math.Min(_stealAwakePeriod, restTime), token, throwOnCancellation)) { return(true); } if (token.IsCancellationRequested) { break; } if (TryTakeFromOtherLocalQueues(localQueue, _localQueues, out item)) { return(true); } restTime = UpdateTimeout(startTime, timeout); } } if (token.IsCancellationRequested && throwOnCancellation) { throw new OperationCanceledException(token); } item = null; return(false); }
public bool TryResolve(T key, out object val) { TurboContract.Requires(key != null, conditionString: "key != null"); TurboContract.Ensures(TurboContract.Result <bool>() == true || (TurboContract.Result <bool>() == false && TurboContract.ValueAtReturn <object>(out val) == null)); throw new NotImplementedException(); }
/// <summary> /// Попытаться получить элемент из главной очереди /// </summary> /// <param name="item">Полученный элемент</param> /// <param name="timeout">Таймаут</param> /// <param name="token">Токен отмены</param> /// <param name="throwOnCancellation">Выбрасывать ли исключение при отмене по токену</param> /// <returns>Удалось ли получить</returns> public bool TryTake(out ThreadPoolWorkItem item, int timeout, CancellationToken token, bool throwOnCancellation) { TurboContract.Ensures(TurboContract.Result <bool>() == false || TurboContract.ValueAtReturn(out item) != null); item = null; if (token.IsCancellationRequested) { if (throwOnCancellation) { throw new OperationCanceledException(token); } return(false); } bool occupiedNodesExist = _occupiedNodes.Wait(0); if (occupiedNodesExist == false && timeout != 0) { occupiedNodesExist = _occupiedNodes.Wait(timeout, token, throwOnCancellation); } if (occupiedNodesExist) { bool wasElementTaken = false; bool takePerformed = true; try { if (token.IsCancellationRequested) { if (throwOnCancellation) { throw new OperationCanceledException(token); } return(false); } wasElementTaken = _mainQueue.TryTake(out item); takePerformed = false; TurboContract.Assert(wasElementTaken, "Incorrect collection state. Can't take items from collection when they should be there"); } finally { if (wasElementTaken) { if (_freeNodes != null) { // Не освобождаем, если запрошен экстеншн if (Volatile.Read(ref _extendedCapacityRequest) <= 0 || Interlocked.Decrement(ref _extendedCapacityRequest) < 0) { _freeNodes.Release(); } } } else { if (takePerformed) { _occupiedNodes.Release(); } } } } return(occupiedNodesExist); }