1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
19 func fromMyNode(node
*MyNode
) *LFNode
{
20 return (*LFNode
)(unsafe
.Pointer(node
))
23 func toMyNode(node
*LFNode
) *MyNode
{
24 return (*MyNode
)(unsafe
.Pointer(node
))
27 var global
interface{}
29 func TestLFStack(t
*testing
.T
) {
31 global
= stack
// force heap allocation
33 // Need to keep additional references to nodes, the stack is not all that type-safe.
36 // Check the stack is initially empty.
37 if LFStackPop(stack
) != nil {
38 t
.Fatalf("stack is not empty")
42 node
:= &MyNode
{data
: 42}
43 nodes
= append(nodes
, node
)
44 LFStackPush(stack
, fromMyNode(node
))
47 node
= &MyNode
{data
: 43}
48 nodes
= append(nodes
, node
)
49 LFStackPush(stack
, fromMyNode(node
))
52 node
= toMyNode(LFStackPop(stack
))
54 t
.Fatalf("stack is empty")
61 node
= toMyNode(LFStackPop(stack
))
63 t
.Fatalf("stack is empty")
69 // Check the stack is empty again.
70 if LFStackPop(stack
) != nil {
71 t
.Fatalf("stack is not empty")
74 t
.Fatalf("stack is not empty")
80 func TestLFStackStress(t
*testing
.T
) {
82 P
:= 4 * GOMAXPROCS(-1)
88 stacks
:= [2]*uint64{new(uint64), new(uint64)}
89 // Need to keep additional references to nodes,
90 // the lock-free stack is not type-safe.
92 // Push K elements randomly onto the stacks.
94 for i
:= 0; i
< K
; i
++ {
96 node
:= &MyNode
{data
: i
}
97 stress
= append(stress
, node
)
98 LFStackPush(stacks
[i%2
], fromMyNode(node
))
100 c
:= make(chan bool, P
)
101 for p
:= 0; p
< P
; p
++ {
103 r
:= rand
.New(rand
.NewSource(rand
.Int63()))
104 // Pop a node from a random stack, then push it onto a random stack.
105 for i
:= 0; i
< N
; i
++ {
106 node
:= toMyNode(LFStackPop(stacks
[r
.Intn(2)]))
108 LFStackPush(stacks
[r
.Intn(2)], fromMyNode(node
))
114 for i
:= 0; i
< P
; i
++ {
117 // Pop all elements from both stacks, and verify that nothing lost.
120 for i
:= 0; i
< 2; i
++ {
122 node
:= toMyNode(LFStackPop(stacks
[i
]))
132 t
.Fatalf("Wrong number of nodes %d/%d", cnt
, K
)
135 t
.Fatalf("Wrong sum %d/%d", sum2
, sum
)
138 // Let nodes be collected now.