github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/queues/zlifo.go (about)

     1  package goqueuestest
     2  
     3  import (
     4  	"sync/atomic"
     5  	"unsafe"
     6  )
     7  
     8  // Simplistic lock-free stack, suffers from ABA
     9  
    10  type ZLifo struct {
    11  	head unsafe.Pointer
    12  }
    13  
    14  func NewZLifo() *ZLifo {
    15  	return &ZLifo{nil}
    16  }
    17  
    18  func (q *ZLifo) Enqueue(value interface{}) {
    19  	node := unsafe.Pointer(&lfNode{value, nil})
    20  	for {
    21  		(*lfNode)(node).next = q.head
    22  		if atomic.CompareAndSwapPointer(&q.head, (*lfNode)(node).next, node) {
    23  			break
    24  		}
    25  	}
    26  }
    27  
    28  func (q *ZLifo) Dequeue() (value interface{}, ok bool) {
    29  	current := q.head
    30  	for current != nil {
    31  		if atomic.CompareAndSwapPointer(&q.head, current, (*lfNode)(current).next) {
    32  			value = (*lfNode)(current).value
    33  			return value, true
    34  		}
    35  		current = q.head
    36  	}
    37  	return nil, false
    38  }