2014-04-11 Marc Glisse <marc.glisse@inria.fr>
[official-gcc.git] / libgo / go / runtime / lfstack_test.go
blob505aae605513ccd5fc7583556f513fb9f479c5ec
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.
5 package runtime_test
7 import (
8 "math/rand"
9 . "runtime"
10 "testing"
11 "unsafe"
14 type MyNode struct {
15 LFNode
16 data int
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) {
28 stack := new(uint64)
29 // Need to keep additional referenfces to nodes, the stack is not all that type-safe.
30 var nodes []*MyNode
32 // Check the stack is initially empty.
33 if LFStackPop(stack) != nil {
34 t.Fatalf("stack is not empty")
37 // Push one element.
38 node := &MyNode{data: 42}
39 nodes = append(nodes, node)
40 LFStackPush(stack, fromMyNode(node))
42 // Push another.
43 node = &MyNode{data: 43}
44 nodes = append(nodes, node)
45 LFStackPush(stack, fromMyNode(node))
47 // Pop one element.
48 node = toMyNode(LFStackPop(stack))
49 if node == nil {
50 t.Fatalf("stack is empty")
52 if node.data != 43 {
53 t.Fatalf("no lifo")
56 // Pop another.
57 node = toMyNode(LFStackPop(stack))
58 if node == nil {
59 t.Fatalf("stack is empty")
61 if node.data != 42 {
62 t.Fatalf("no lifo")
65 // Check the stack is empty again.
66 if LFStackPop(stack) != nil {
67 t.Fatalf("stack is not empty")
69 if *stack != 0 {
70 t.Fatalf("stack is not empty")
74 func TestLFStackStress(t *testing.T) {
75 const K = 100
76 P := 4 * GOMAXPROCS(-1)
77 N := 100000
78 if testing.Short() {
79 N /= 10
81 // Create 2 stacks.
82 stacks := [2]*uint64{new(uint64), new(uint64)}
83 // Need to keep additional referenfces to nodes, the stack is not all that type-safe.
84 var nodes []*MyNode
85 // Push K elements randomly onto the stacks.
86 sum := 0
87 for i := 0; i < K; i++ {
88 sum += i
89 node := &MyNode{data: i}
90 nodes = append(nodes, node)
91 LFStackPush(stacks[i%2], fromMyNode(node))
93 c := make(chan bool, P)
94 for p := 0; p < P; p++ {
95 go func() {
96 r := rand.New(rand.NewSource(rand.Int63()))
97 // Pop a node from a random stack, then push it onto a random stack.
98 for i := 0; i < N; i++ {
99 node := toMyNode(LFStackPop(stacks[r.Intn(2)]))
100 if node != nil {
101 LFStackPush(stacks[r.Intn(2)], fromMyNode(node))
104 c <- true
107 for i := 0; i < P; i++ {
110 // Pop all elements from both stacks, and verify that nothing lost.
111 sum2 := 0
112 cnt := 0
113 for i := 0; i < 2; i++ {
114 for {
115 node := toMyNode(LFStackPop(stacks[i]))
116 if node == nil {
117 break
119 cnt++
120 sum2 += node.data
121 node.Next = nil
124 if cnt != K {
125 t.Fatalf("Wrong number of nodes %d/%d", cnt, K)
127 if sum2 != sum {
128 t.Fatalf("Wrong sum %d/%d", sum2, sum)