go / expert
Snippet
Lock-Free Stack Implementation via Atomic Pointers
High-throughput concurrent data structures often eliminate mutex contention by leveraging Compare-And-Swap (CAS) instructions. Go 1.19 introduced generic `atomic.Pointer[T]`, allowing lock-free data structures like Treiber stacks to be written without unsafe pointer casting. The CAS loop repeatedly attempts atomic pointer replacement until no race occurs.
snippet.go
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package mainimport ("fmt""sync/atomic")type Node[T any] struct {value Tnext *Node[T]}type LockFreeStack[T any] struct {head atomic.Pointer[Node[T]]}func (s *LockFreeStack[T]) Push(val T) {n := &Node[T]{value: val}for {currHead := s.head.Load()n.next = currHeadif s.head.CompareAndSwap(currHead, n) {return}}}func (s *LockFreeStack[T]) Pop() (T, bool) {var zero Tfor {currHead := s.head.Load()if currHead == nil {return zero, false}nextHead := currHead.nextif s.head.CompareAndSwap(currHead, nextHead) {return currHead.value, true}}}func main() {stack := &LockFreeStack[int]{}stack.Push(42)val, _ := stack.Pop()fmt.Println(val)}
Breakdown
1
head atomic.Pointer[Node[T]]
Uses Go's type-safe atomic pointer container to track the top of the stack atomically.
2
if s.head.CompareAndSwap(currHead, n) {
Executes a atomic CAS instruction that updates the head pointer only if another thread has not mutated it concurrently.