@Override
    public int fill(Supplier<E> s, int limit) {
        if (null == s)
            throw new IllegalArgumentException("supplier is null");
        if (limit < 0)
            throw new IllegalArgumentException("limit is negative:" + limit);
        if (limit == 0)
            return 0;
        LinkedQueueAtomicNode<E> tail = newNode(s.get());
        final LinkedQueueAtomicNode<E> head = tail;
        for (int i = 1; i < limit; i++) {
            final LinkedQueueAtomicNode<E> temp = newNode(s.get());
            // spNext : soProducerNode ensures correct construction
            tail.spNext(temp);
            tail = temp;
        }
        final LinkedQueueAtomicNode<E> oldPNode = lpProducerNode();
        soProducerNode(tail);
        // same bubble as offer, and for the same reasons.
        oldPNode.soNext(head);
        return limit;
    }
{@inheritDoc} <br>
<p>
IMPLEMENTATION NOTES:<br>
Offer is allowed from a SINGLE thread.<br>
Offer allocates a new node (holding the offered value) and:
<ol>
<li>Sets the new node as the producerNode
<li>Sets that node as the lastProducerNode.next
</ol>
From this follows that producerNode.next is always null and for all other nodes node.next is not null.

@see MessagePassingQueue#offer(Object)
@see java.util.Queue#offer(java.lang.Object)
jctools-core/src/main/java/org/jctools/queues/atomic/unpadded/SpscLinkedAtomicUnpaddedQueue.java