runtime: scan register backing store on ia64
[official-gcc.git] / libgo / go / runtime / profbuf_test.go
blobd9c5264b732d6857c44b2eb35ce10ab0324c0025
1 // Copyright 2017 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 "reflect"
9 . "runtime"
10 "testing"
11 "time"
12 "unsafe"
15 func TestProfBuf(t *testing.T) {
16 const hdrSize = 2
18 write := func(t *testing.T, b *ProfBuf, tag unsafe.Pointer, now int64, hdr []uint64, stk []uintptr) {
19 b.Write(&tag, now, hdr, stk)
21 read := func(t *testing.T, b *ProfBuf, data []uint64, tags []unsafe.Pointer) {
22 rdata, rtags, eof := b.Read(ProfBufNonBlocking)
23 if !reflect.DeepEqual(rdata, data) || !reflect.DeepEqual(rtags, tags) {
24 t.Fatalf("unexpected profile read:\nhave data %#x\nwant data %#x\nhave tags %#x\nwant tags %#x", rdata, data, rtags, tags)
26 if eof {
27 t.Fatalf("unexpected eof")
30 readBlock := func(t *testing.T, b *ProfBuf, data []uint64, tags []unsafe.Pointer) func() {
31 c := make(chan int)
32 go func() {
33 eof := data == nil
34 rdata, rtags, reof := b.Read(ProfBufBlocking)
35 if !reflect.DeepEqual(rdata, data) || !reflect.DeepEqual(rtags, tags) || reof != eof {
36 // Errorf, not Fatalf, because called in goroutine.
37 t.Errorf("unexpected profile read:\nhave data %#x\nwant data %#x\nhave tags %#x\nwant tags %#x\nhave eof=%v, want %v", rdata, data, rtags, tags, reof, eof)
39 c <- 1
40 }()
41 time.Sleep(10 * time.Millisecond) // let goroutine run and block
42 return func() {
43 select {
44 case <-c:
45 case <-time.After(1 * time.Second):
46 t.Fatalf("timeout waiting for blocked read")
50 readEOF := func(t *testing.T, b *ProfBuf) {
51 rdata, rtags, eof := b.Read(ProfBufBlocking)
52 if rdata != nil || rtags != nil || !eof {
53 t.Errorf("unexpected profile read: %#x, %#x, eof=%v; want nil, nil, eof=true", rdata, rtags, eof)
55 rdata, rtags, eof = b.Read(ProfBufNonBlocking)
56 if rdata != nil || rtags != nil || !eof {
57 t.Errorf("unexpected profile read (non-blocking): %#x, %#x, eof=%v; want nil, nil, eof=true", rdata, rtags, eof)
61 myTags := make([]byte, 100)
62 t.Logf("myTags is %p", &myTags[0])
64 t.Run("BasicWriteRead", func(t *testing.T) {
65 b := NewProfBuf(2, 11, 1)
66 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
67 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
68 read(t, b, nil, nil) // release data returned by previous read
69 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
70 read(t, b, []uint64{8, 99, 101, 102, 201, 202, 203, 204}, []unsafe.Pointer{unsafe.Pointer(&myTags[2])})
73 t.Run("ReadMany", func(t *testing.T) {
74 b := NewProfBuf(2, 50, 50)
75 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
76 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
77 write(t, b, unsafe.Pointer(&myTags[1]), 500, []uint64{502, 504}, []uintptr{506})
78 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 99, 101, 102, 201, 202, 203, 204, 5, 500, 502, 504, 506}, []unsafe.Pointer{unsafe.Pointer(&myTags[0]), unsafe.Pointer(&myTags[2]), unsafe.Pointer(&myTags[1])})
81 t.Run("ReadManyShortData", func(t *testing.T) {
82 b := NewProfBuf(2, 50, 50)
83 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
84 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
85 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 99, 101, 102, 201, 202, 203, 204}, []unsafe.Pointer{unsafe.Pointer(&myTags[0]), unsafe.Pointer(&myTags[2])})
88 t.Run("ReadManyShortTags", func(t *testing.T) {
89 b := NewProfBuf(2, 50, 50)
90 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
91 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
92 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 99, 101, 102, 201, 202, 203, 204}, []unsafe.Pointer{unsafe.Pointer(&myTags[0]), unsafe.Pointer(&myTags[2])})
95 t.Run("ReadAfterOverflow1", func(t *testing.T) {
96 // overflow record synthesized by write
97 b := NewProfBuf(2, 16, 5)
98 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9}) // uses 10
99 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])}) // reads 10 but still in use until next read
100 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5}) // uses 6
101 read(t, b, []uint64{6, 1, 2, 3, 4, 5}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])}) // reads 6 but still in use until next read
102 // now 10 available
103 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204, 205, 206, 207, 208, 209}) // no room
104 for i := 0; i < 299; i++ {
105 write(t, b, unsafe.Pointer(&myTags[3]), int64(100+i), []uint64{101, 102}, []uintptr{201, 202, 203, 204}) // no room for overflow+this record
107 write(t, b, unsafe.Pointer(&myTags[1]), 500, []uint64{502, 504}, []uintptr{506}) // room for overflow+this record
108 read(t, b, []uint64{5, 99, 0, 0, 300, 5, 500, 502, 504, 506}, []unsafe.Pointer{nil, unsafe.Pointer(&myTags[1])})
111 t.Run("ReadAfterOverflow2", func(t *testing.T) {
112 // overflow record synthesized by read
113 b := NewProfBuf(2, 16, 5)
114 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
115 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213})
116 for i := 0; i < 299; i++ {
117 write(t, b, unsafe.Pointer(&myTags[3]), 100, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
119 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])}) // reads 10 but still in use until next read
120 write(t, b, unsafe.Pointer(&myTags[1]), 500, []uint64{502, 504}, []uintptr{}) // still overflow
121 read(t, b, []uint64{5, 99, 0, 0, 301}, []unsafe.Pointer{nil}) // overflow synthesized by read
122 write(t, b, unsafe.Pointer(&myTags[1]), 500, []uint64{502, 505}, []uintptr{506}) // written
123 read(t, b, []uint64{5, 500, 502, 505, 506}, []unsafe.Pointer{unsafe.Pointer(&myTags[1])})
126 t.Run("ReadAtEndAfterOverflow", func(t *testing.T) {
127 b := NewProfBuf(2, 12, 5)
128 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
129 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
130 for i := 0; i < 299; i++ {
131 write(t, b, unsafe.Pointer(&myTags[3]), 100, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
133 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
134 read(t, b, []uint64{5, 99, 0, 0, 300}, []unsafe.Pointer{nil})
135 write(t, b, unsafe.Pointer(&myTags[1]), 500, []uint64{502, 504}, []uintptr{506})
136 read(t, b, []uint64{5, 500, 502, 504, 506}, []unsafe.Pointer{unsafe.Pointer(&myTags[1])})
139 t.Run("BlockingWriteRead", func(t *testing.T) {
140 b := NewProfBuf(2, 11, 1)
141 wait := readBlock(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
142 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
143 wait()
144 wait = readBlock(t, b, []uint64{8, 99, 101, 102, 201, 202, 203, 204}, []unsafe.Pointer{unsafe.Pointer(&myTags[2])})
145 time.Sleep(10 * time.Millisecond)
146 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
147 wait()
148 wait = readBlock(t, b, nil, nil)
149 b.Close()
150 wait()
151 wait = readBlock(t, b, nil, nil)
152 wait()
153 readEOF(t, b)
156 t.Run("DataWraparound", func(t *testing.T) {
157 b := NewProfBuf(2, 16, 1024)
158 for i := 0; i < 10; i++ {
159 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
160 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
161 read(t, b, nil, nil) // release data returned by previous read
165 t.Run("TagWraparound", func(t *testing.T) {
166 b := NewProfBuf(2, 1024, 2)
167 for i := 0; i < 10; i++ {
168 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
169 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
170 read(t, b, nil, nil) // release data returned by previous read
174 t.Run("BothWraparound", func(t *testing.T) {
175 b := NewProfBuf(2, 16, 2)
176 for i := 0; i < 10; i++ {
177 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
178 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
179 read(t, b, nil, nil) // release data returned by previous read