Source file
src/runtime/futex_test.go
Documentation: runtime
1
2
3
4
5
6
7
8
9
10
11
12
13 package runtime_test
14
15 import (
16 "runtime"
17 "sync"
18 "sync/atomic"
19 "testing"
20 "time"
21 )
22
23 type futexsleepTest struct {
24 mtx uint32
25 ns int64
26 msg string
27 ch chan *futexsleepTest
28 }
29
30 var futexsleepTests = []futexsleepTest{
31 beforeY2038: {mtx: 0, ns: 86400 * 1e9, msg: "before the year 2038"},
32 afterY2038: {mtx: 0, ns: (1<<31 + 100) * 1e9, msg: "after the year 2038"},
33 }
34
35 const (
36 beforeY2038 = iota
37 afterY2038
38 )
39
40 func TestFutexsleep(t *testing.T) {
41 if runtime.GOMAXPROCS(0) > 1 {
42
43
44 t.Skip("skipping; GOMAXPROCS>1")
45 }
46
47 start := time.Now()
48 var wg sync.WaitGroup
49 for i := range futexsleepTests {
50 tt := &futexsleepTests[i]
51 tt.mtx = 0
52 tt.ch = make(chan *futexsleepTest, 1)
53 wg.Add(1)
54 go func(tt *futexsleepTest) {
55 runtime.Entersyscall()
56 runtime.Futexsleep(&tt.mtx, 0, tt.ns)
57 runtime.Exitsyscall()
58 tt.ch <- tt
59 wg.Done()
60 }(tt)
61 }
62 loop:
63 for {
64 select {
65 case tt := <-futexsleepTests[beforeY2038].ch:
66 t.Errorf("futexsleep test %q finished early after %s", tt.msg, time.Since(start))
67 break loop
68 case tt := <-futexsleepTests[afterY2038].ch:
69
70
71
72 switch {
73 case runtime.GOOS == "freebsd" && runtime.GOARCH == "386":
74 t.Log("freebsd/386 may not work correctly after the year 2038, see golang.org/issue/7194")
75 default:
76 t.Errorf("futexsleep test %q finished early after %s", tt.msg, time.Since(start))
77 break loop
78 }
79 case <-time.After(time.Second):
80 break loop
81 }
82 }
83 for i := range futexsleepTests {
84 tt := &futexsleepTests[i]
85 atomic.StoreUint32(&tt.mtx, 1)
86 runtime.Futexwakeup(&tt.mtx, 1)
87 }
88 wg.Wait()
89 }
90
View as plain text