]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: allocate fewer bytes during TestEINTR
authorBryan C. Mills <bcmills@google.com>
Tue, 19 May 2020 05:29:11 +0000 (01:29 -0400)
committerBryan C. Mills <bcmills@google.com>
Wed, 20 May 2020 15:57:15 +0000 (15:57 +0000)
This will hopefully address the occasional "runtime: out of memory"
failures observed on the openbsd-arm-jsing builder:
https://build.golang.org/log/c296d866e5d99ba401b18c1a2ff3e4d480e5238c

Also make the "spin" and "winch" loops concurrent instead of
sequential to cut down the test's running time.

Finally, change Block to coordinate by closing stdin instead of
sending SIGINT. The SIGINT handler wasn't necessarily registered by
the time the signal was sent.

Updates #20400
Updates #39043

Change-Id: Ie12fc75b87e33847dc25a12edb4126db27492da6
Reviewed-on: https://go-review.googlesource.com/c/go/+/234538
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/runtime/testdata/testprogcgo/eintr.go

index 58f0dd2ca3dc3cac3211c06687e012476bdb66b7..9d9435d9a6c698f6d7cdd67d20345071af034931 100644 (file)
@@ -32,11 +32,11 @@ import (
        "errors"
        "fmt"
        "io"
+       "io/ioutil"
        "log"
        "net"
        "os"
        "os/exec"
-       "os/signal"
        "sync"
        "syscall"
        "time"
@@ -71,14 +71,15 @@ func EINTR() {
 // spin does CPU bound spinning and allocating for a millisecond,
 // to get a SIGURG.
 //go:noinline
-func spin() (float64, [][]byte) {
+func spin() (float64, []byte) {
        stop := time.Now().Add(time.Millisecond)
        r1 := 0.0
-       var r2 [][]byte
+       r2 := make([]byte, 200)
        for time.Now().Before(stop) {
                for i := 1; i < 1e6; i++ {
                        r1 += r1 / float64(i)
-                       r2 = append(r2, bytes.Repeat([]byte{byte(i)}, 100))
+                       r2 = append(r2, bytes.Repeat([]byte{byte(i)}, 100)...)
+                       r2 = r2[100:]
                }
        }
        return r1, r2
@@ -96,8 +97,13 @@ func winch() {
 
 // sendSomeSignals triggers a few SIGURG and SIGWINCH signals.
 func sendSomeSignals() {
-       spin()
+       done := make(chan struct{})
+       go func() {
+               spin()
+               close(done)
+       }()
        winch()
+       <-done
 }
 
 // testPipe tests pipe operations.
@@ -212,6 +218,10 @@ func testExec(wg *sync.WaitGroup) {
        go func() {
                defer wg.Done()
                cmd := exec.Command(os.Args[0], "Block")
+               stdin, err := cmd.StdinPipe()
+               if err != nil {
+                       log.Fatal(err)
+               }
                cmd.Stderr = new(bytes.Buffer)
                cmd.Stdout = cmd.Stderr
                if err := cmd.Start(); err != nil {
@@ -220,9 +230,7 @@ func testExec(wg *sync.WaitGroup) {
 
                go func() {
                        sendSomeSignals()
-                       if err := cmd.Process.Signal(os.Interrupt); err != nil {
-                               panic(err)
-                       }
+                       stdin.Close()
                }()
 
                if err := cmd.Wait(); err != nil {
@@ -231,10 +239,7 @@ func testExec(wg *sync.WaitGroup) {
        }()
 }
 
-// Block blocks until the process receives os.Interrupt.
+// Block blocks until stdin is closed.
 func Block() {
-       c := make(chan os.Signal, 1)
-       signal.Notify(c, os.Interrupt)
-       defer signal.Stop(c)
-       <-c
+       io.Copy(ioutil.Discard, os.Stdin)
 }