public override long Receive(long ticket, T batch) { long time = nanoTime(); while (QueuedBatches.get() >= _maxQueueLength) { Park.park(_receiverThread = Thread.CurrentThread); } // It is of importance that all items in the queue at the same time agree on the number of processors. We take this lock in order to make sure that we // do not interfere with another thread trying to drain the queue in order to change the processor count. long @lock = ApplyProcessorCount(_stripingLock.readLock()); QueuedBatches.incrementAndGet(); Unit unit = new Unit(this, ticket, batch, _numberOfForkedProcessors); // [old head] [unit] // ^ // head Unit myHead = _head.getAndSet(unit); // [old head] -next-> [unit] myHead.Next = unit; _stripingLock.unlock(@lock); return(nanoTime() - time); }
private void DecrementQueue() { // Even though queuedBatches is built into AbstractStep, in that number of received batches // is number of done + queued batches, this is the only implementation changing queuedBatches // since it's the only implementation capable of such. That's why this code is here // and not in AbstractStep. int queueSizeAfterThisJobDone = QueuedBatches.decrementAndGet(); Debug.Assert(queueSizeAfterThisJobDone >= 0, "Negative queue size " + queueSizeAfterThisJobDone); if (queueSizeAfterThisJobDone == 0) { _lastBatchEndTime.set(currentTimeMillis()); } }