forked from robaho/go-trader
/
spsc.go
44 lines (36 loc) · 915 Bytes
/
spsc.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
package exchange
import (
"bytes"
"sync/atomic"
"unsafe"
)
type node struct {
data *bytes.Buffer
next *node
}
// SPSC is a lock-free queue for []byte (single producer, single consumer), used to recycle marketdata multicast packets
type SPSC struct {
head *node
}
func (q *SPSC) put(data *bytes.Buffer) {
n := &node{}
n.data = data
for {
n.next = (*node)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&q.head))))
if atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(&q.head)), unsafe.Pointer(n.next), unsafe.Pointer(n)) {
return
}
}
}
func (q *SPSC) get() *bytes.Buffer {
for {
head := (*node)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&q.head))))
if head == nil {
return nil
}
next := head.next
if atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(&q.head)), unsafe.Pointer(head), unsafe.Pointer(next)) {
return head.data
}
}
}