Source file
src/runtime/lfstack_test.go
1
2
3
4
5 package runtime_test
6
7 import (
8 "math/rand"
9 . "runtime"
10 "testing"
11 "unsafe"
12 )
13
14 type MyNode struct {
15 LFNode
16 data int
17 }
18
19
20
21
22
23 func allocMyNode(data int) *MyNode {
24 n := (*MyNode)(PersistentAlloc(unsafe.Sizeof(MyNode{})))
25 LFNodeValidate(&n.LFNode)
26 n.data = data
27 return n
28 }
29
30 func fromMyNode(node *MyNode) *LFNode {
31 return (*LFNode)(unsafe.Pointer(node))
32 }
33
34 func toMyNode(node *LFNode) *MyNode {
35 return (*MyNode)(unsafe.Pointer(node))
36 }
37
38 var global any
39
40 func TestLFStack(t *testing.T) {
41 stack := new(uint64)
42 global = stack
43
44
45 if LFStackPop(stack) != nil {
46 t.Fatalf("stack is not empty")
47 }
48
49
50 node := allocMyNode(42)
51 LFStackPush(stack, fromMyNode(node))
52
53
54 node = allocMyNode(43)
55 LFStackPush(stack, fromMyNode(node))
56
57
58 node = toMyNode(LFStackPop(stack))
59 if node == nil {
60 t.Fatalf("stack is empty")
61 }
62 if node.data != 43 {
63 t.Fatalf("no lifo")
64 }
65
66
67 node = toMyNode(LFStackPop(stack))
68 if node == nil {
69 t.Fatalf("stack is empty")
70 }
71 if node.data != 42 {
72 t.Fatalf("no lifo")
73 }
74
75
76 if LFStackPop(stack) != nil {
77 t.Fatalf("stack is not empty")
78 }
79 if *stack != 0 {
80 t.Fatalf("stack is not empty")
81 }
82 }
83
84 func TestLFStackStress(t *testing.T) {
85 const K = 100
86 P := 4 * GOMAXPROCS(-1)
87 N := 100000
88 if testing.Short() {
89 N /= 10
90 }
91
92 stacks := [2]*uint64{new(uint64), new(uint64)}
93
94 sum := 0
95 for i := 0; i < K; i++ {
96 sum += i
97 node := allocMyNode(i)
98 LFStackPush(stacks[i%2], fromMyNode(node))
99 }
100 c := make(chan bool, P)
101 for p := 0; p < P; p++ {
102 go func() {
103 r := rand.New(rand.NewSource(rand.Int63()))
104
105 for i := 0; i < N; i++ {
106 node := toMyNode(LFStackPop(stacks[r.Intn(2)]))
107 if node != nil {
108 LFStackPush(stacks[r.Intn(2)], fromMyNode(node))
109 }
110 }
111 c <- true
112 }()
113 }
114 for i := 0; i < P; i++ {
115 <-c
116 }
117
118 sum2 := 0
119 cnt := 0
120 for i := 0; i < 2; i++ {
121 for {
122 node := toMyNode(LFStackPop(stacks[i]))
123 if node == nil {
124 break
125 }
126 cnt++
127 sum2 += node.data
128 node.Next = 0
129 }
130 }
131 if cnt != K {
132 t.Fatalf("Wrong number of nodes %d/%d", cnt, K)
133 }
134 if sum2 != sum {
135 t.Fatalf("Wrong sum %d/%d", sum2, sum)
136 }
137 }
138
View as plain text