LEFT | RIGHT |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package runtime_test | 5 package runtime_test |
6 | 6 |
7 import ( | 7 import ( |
8 "math" | 8 "math" |
9 "runtime" | 9 "runtime" |
10 "sync/atomic" | 10 "sync/atomic" |
| 11 "syscall" |
11 "testing" | 12 "testing" |
12 "time" | 13 "time" |
13 ) | 14 ) |
14 | 15 |
15 var stop = make(chan bool, 1) | 16 var stop = make(chan bool, 1) |
16 | 17 |
17 func perpetuumMobile() { | 18 func perpetuumMobile() { |
18 select { | 19 select { |
19 case <-stop: | 20 case <-stop: |
20 default: | 21 default: |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 for i := 0; i < N; i++ { | 101 for i := 0; i < N; i++ { |
101 c <- true | 102 c <- true |
102 } | 103 } |
103 runtime.UnlockOSThread() | 104 runtime.UnlockOSThread() |
104 }() | 105 }() |
105 for i := 0; i < N; i++ { | 106 for i := 0; i < N; i++ { |
106 <-c | 107 <-c |
107 } | 108 } |
108 } | 109 } |
109 | 110 |
| 111 func TestTimerFairness(t *testing.T) { |
| 112 done := make(chan bool) |
| 113 c := make(chan bool) |
| 114 for i := 0; i < 2; i++ { |
| 115 go func() { |
| 116 for { |
| 117 select { |
| 118 case c <- true: |
| 119 case <-done: |
| 120 return |
| 121 } |
| 122 } |
| 123 }() |
| 124 } |
| 125 |
| 126 timer := time.After(20 * time.Millisecond) |
| 127 for { |
| 128 select { |
| 129 case <-c: |
| 130 case <-timer: |
| 131 close(done) |
| 132 return |
| 133 } |
| 134 } |
| 135 } |
| 136 |
| 137 func TestTimerFairness2(t *testing.T) { |
| 138 done := make(chan bool) |
| 139 c := make(chan bool) |
| 140 for i := 0; i < 2; i++ { |
| 141 go func() { |
| 142 timer := time.After(20 * time.Millisecond) |
| 143 var buf [1]byte |
| 144 for { |
| 145 syscall.Read(0, buf[0:0]) |
| 146 select { |
| 147 case c <- true: |
| 148 case <-c: |
| 149 case <-timer: |
| 150 done <- true |
| 151 return |
| 152 } |
| 153 } |
| 154 }() |
| 155 } |
| 156 <-done |
| 157 <-done |
| 158 } |
| 159 |
110 // The function is used to test preemption at split stack checks. | 160 // The function is used to test preemption at split stack checks. |
| 161 // Declaring a var avoids inlining at the call site. |
111 var preempt = func() int { | 162 var preempt = func() int { |
112 var a [128]int | 163 var a [128]int |
113 sum := 0 | 164 sum := 0 |
114 for _, v := range a { | 165 for _, v := range a { |
115 sum += v | 166 sum += v |
116 } | 167 } |
117 return sum | 168 return sum |
118 } | 169 } |
119 | 170 |
120 func TestPreemptionGC(t *testing.T) { | 171 func TestPreemptionGC(t *testing.T) { |
121 // Test that pending GC preempts running goroutines. | 172 // Test that pending GC preempts running goroutines. |
| 173 const P = 5 |
| 174 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(P + 1)) |
122 var stop uint32 | 175 var stop uint32 |
123 » for i := 0; i < 5; i++ { | 176 » for i := 0; i < P; i++ { |
124 go func() { | 177 go func() { |
125 for atomic.LoadUint32(&stop) == 0 { | 178 for atomic.LoadUint32(&stop) == 0 { |
126 preempt() | 179 preempt() |
127 } | 180 } |
128 }() | 181 }() |
129 } | 182 } |
130 for i := 0; i < 10; i++ { | 183 for i := 0; i < 10; i++ { |
131 runtime.Gosched() | 184 runtime.Gosched() |
132 runtime.GC() | 185 runtime.GC() |
133 } | 186 } |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 for k := k0; k < k1; k++ { | 356 for k := k0; k < k1; k++ { |
304 C[i][j] += A[i][k] * B[k][j] | 357 C[i][j] += A[i][k] * B[k][j] |
305 } | 358 } |
306 } | 359 } |
307 } | 360 } |
308 } | 361 } |
309 if done != nil { | 362 if done != nil { |
310 done <- struct{}{} | 363 done <- struct{}{} |
311 } | 364 } |
312 } | 365 } |
LEFT | RIGHT |