]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: do not allocate on every time.Sleep
authorRuss Cox <rsc@golang.org>
Fri, 17 Feb 2017 15:17:42 +0000 (10:17 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 24 Feb 2017 15:34:01 +0000 (15:34 +0000)
It's common for some goroutines to loop calling time.Sleep.
Allocate once per goroutine, not every time.
This comes up in runtime/pprof's background reader.

Change-Id: I89d17dc7379dca266d2c9cd3aefc2382f5bdbade
Reviewed-on: https://go-review.googlesource.com/37162
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
src/runtime/proc.go
src/runtime/runtime2.go
src/runtime/time.go

index 89244cfa7dbf18e00ae28ca8eb27c0e29584a395..bf1466b9de24e1315624b19a5d5cda235b72affb 100644 (file)
@@ -2330,6 +2330,7 @@ func goexit0(gp *g) {
        gp.waitreason = ""
        gp.param = nil
        gp.labels = nil
+       gp.timer = nil
 
        // Note that gp's stack scan is now "valid" because it has no
        // stack.
index 86176fd2acee7c9fcf0dc253f454eedbfc900af3..5c05c20d940462a8d0402f33696a67373545ed56 100644 (file)
@@ -376,6 +376,7 @@ type g struct {
        waiting        *sudog         // sudog structures this g is waiting on (that have a valid elem ptr); in lock order
        cgoCtxt        []uintptr      // cgo traceback context
        labels         unsafe.Pointer // profiler labels
+       timer          *timer         // cached timer for time.Sleep
 
        // Per-G GC state
 
index c296338e9ba89c2931e4bb34a7d6d6407010005f..88ab8b9c02fa397b513dec15552bf1b835cce395 100644 (file)
@@ -50,7 +50,12 @@ func timeSleep(ns int64) {
                return
        }
 
-       t := new(timer)
+       t := getg().timer
+       if t == nil {
+               t = new(timer)
+               getg().timer = t
+       }
+       *t = timer{}
        t.when = nanotime() + ns
        t.f = goroutineReady
        t.arg = getg()