protected T RelaxedPeek() { LinkedQueueNode <T> currConsumerNode = this.ConsumerNode; // don't load twice, it's alright LinkedQueueNode <T> nextNode = currConsumerNode.LvNext(); return(nextNode?.LpValue()); }
protected T RelaxedPoll() { LinkedQueueNode <T> currConsumerNode = this.LpConsumerNode(); // don't load twice, it's alright LinkedQueueNode <T> nextNode = currConsumerNode.LvNext(); return(nextNode != null ? this.GetSingleConsumerNodeValue(currConsumerNode, nextNode) : null); }
public override bool Offer(T e) { Contract.Requires(e != null); var nextNode = new LinkedQueueNode <T>(e); LinkedQueueNode <T> producerNode = this.LpProducerNode(); producerNode.SoNext(nextNode); this.SpProducerNode(nextNode); return(true); }
protected T GetSingleConsumerNodeValue(LinkedQueueNode <T> currConsumerNode, LinkedQueueNode <T> nextNode) { // we have to null out the value because we are going to hang on to the node T nextValue = nextNode.GetAndNullValue(); // Fix up the next ref of currConsumerNode to prevent promoted nodes from keep new ones alive. // We use a reference to self instead of null because null is already a meaningful value (the next of // producer node is null). currConsumerNode.SoNext(currConsumerNode); this.SpConsumerNode(nextNode); // currConsumerNode is now no longer referenced and can be collected return(nextValue); }
public override bool Offer(T e) { if (e is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.e); } var nextNode = new LinkedQueueNode <T>(e); LinkedQueueNode <T> producerNode = this.LpProducerNode(); producerNode.SoNext(nextNode); this.SpProducerNode(nextNode); return(true); }
public void SoNext(LinkedQueueNode <T> n) => Volatile.Write(ref this.next, n);
protected void SpProducerNode(LinkedQueueNode <T> node) => this.ProducerNode = node;
protected void SpConsumerNode(LinkedQueueNode <T> node) => this.ConsumerNode = node;