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 func TestLFStack(t
*testing
.T
) {
29 // Need to keep additional referenfces to nodes, the stack is not all that type-safe.
32 // Check the stack is initially empty.
33 if LFStackPop(stack
) != nil {
34 t
.Fatalf("stack is not empty")
38 node
:= &MyNode
{data
: 42}
39 nodes
= append(nodes
, node
)
40 LFStackPush(stack
, fromMyNode(node
))
43 node
= &MyNode
{data
: 43}
44 nodes
= append(nodes
, node
)
45 LFStackPush(stack
, fromMyNode(node
))
48 node
= toMyNode(LFStackPop(stack
))
50 t
.Fatalf("stack is empty")
57 node
= toMyNode(LFStackPop(stack
))
59 t
.Fatalf("stack is empty")
65 // Check the stack is empty again.
66 if LFStackPop(stack
) != nil {
67 t
.Fatalf("stack is not empty")
70 t
.Fatalf("stack is not empty")
76 func TestLFStackStress(t
*testing
.T
) {
78 P
:= 4 * GOMAXPROCS(-1)
84 stacks
:= [2]*uint64{new(uint64), new(uint64)}
85 // Need to keep additional references to nodes,
86 // the lock-free stack is not type-safe.
88 // Push K elements randomly onto the stacks.
90 for i
:= 0; i
< K
; i
++ {
92 node
:= &MyNode
{data
: i
}
93 stress
= append(stress
, node
)
94 LFStackPush(stacks
[i%2
], fromMyNode(node
))
96 c
:= make(chan bool, P
)
97 for p
:= 0; p
< P
; p
++ {
99 r
:= rand
.New(rand
.NewSource(rand
.Int63()))
100 // Pop a node from a random stack, then push it onto a random stack.
101 for i
:= 0; i
< N
; i
++ {
102 node
:= toMyNode(LFStackPop(stacks
[r
.Intn(2)]))
104 LFStackPush(stacks
[r
.Intn(2)], fromMyNode(node
))
110 for i
:= 0; i
< P
; i
++ {
113 // Pop all elements from both stacks, and verify that nothing lost.
116 for i
:= 0; i
< 2; i
++ {
118 node
:= toMyNode(LFStackPop(stacks
[i
]))
128 t
.Fatalf("Wrong number of nodes %d/%d", cnt
, K
)
131 t
.Fatalf("Wrong sum %d/%d", sum2
, sum
)
134 // Let nodes be collected now.