]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: don't try to shrink address space with brk in Plan 9
authorRichard Miller <miller.research@gmail.com>
Wed, 28 Feb 2018 09:35:55 +0000 (09:35 +0000)
committerDavid du Colombier <0intro@gmail.com>
Wed, 28 Feb 2018 15:57:10 +0000 (15:57 +0000)
Plan 9 won't let brk shrink the data segment if it's shared with
other processes (which it is in the go runtime).  So we keep track
of the notional end of the segment as it moves up and down, and
call brk only when it grows.

Corrects CL 94776.

Updates #23860.
Fixes #24013.

Change-Id: I754232decab81dfd71d690f77ee6097a17d9be11
Reviewed-on: https://go-review.googlesource.com/97595
Reviewed-by: David du Colombier <0intro@gmail.com>
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: David du Colombier <0intro@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/mem_plan9.go

index b80d030b240745b649411186b03a5015fa106431..2359f138bc208d14f0ea095a0e72788303645d0a 100644 (file)
@@ -9,6 +9,7 @@ import "unsafe"
 const memDebug = false
 
 var bloc uintptr
+var blocMax uintptr
 var memlock mutex
 
 type memHdr struct {
@@ -122,14 +123,18 @@ func memRound(p uintptr) uintptr {
 
 func initBloc() {
        bloc = memRound(firstmoduledata.end)
+       blocMax = bloc
 }
 
 func sbrk(n uintptr) unsafe.Pointer {
        // Plan 9 sbrk from /sys/src/libc/9sys/sbrk.c
        bl := bloc
        n = memRound(n)
-       if brk_(unsafe.Pointer(bl+n)) < 0 {
-               return nil
+       if bl+n > blocMax {
+               if brk_(unsafe.Pointer(bl+n)) < 0 {
+                       return nil
+               }
+               blocMax = bl + n
        }
        bloc += n
        return unsafe.Pointer(bl)
@@ -150,10 +155,11 @@ func sysFree(v unsafe.Pointer, n uintptr, sysStat *uint64) {
        mSysStatDec(sysStat, n)
        lock(&memlock)
        if uintptr(v)+n == bloc {
-               // address range being freed is at the end of memory,
-               // so shrink the address space
+               // Address range being freed is at the end of memory,
+               // so record a new lower value for end of memory.
+               // Can't actually shrink address space because segment is shared.
+               memclrNoHeapPointers(v, n)
                bloc -= n
-               brk_(unsafe.Pointer(bloc))
        } else {
                memFree(v, n)
                memCheck()
@@ -180,8 +186,8 @@ func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer {
        lock(&memlock)
        var p unsafe.Pointer
        if uintptr(v) == bloc {
-               // address hint is the current end of memory,
-               // so try to extend the address space
+               // Address hint is the current end of memory,
+               // so try to extend the address space.
                p = sbrk(n)
        }
        if p == nil {