From c2cdfbd1a75b74bf7b960f6904fcfaaad9edb708 Mon Sep 17 00:00:00 2001 From: Richard Miller Date: Wed, 28 Feb 2018 09:35:55 +0000 Subject: [PATCH] runtime: don't try to shrink address space with brk in Plan 9 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 Run-TryBot: David du Colombier <0intro@gmail.com> TryBot-Result: Gobot Gobot --- src/runtime/mem_plan9.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/runtime/mem_plan9.go b/src/runtime/mem_plan9.go index b80d030b24..2359f138bc 100644 --- a/src/runtime/mem_plan9.go +++ b/src/runtime/mem_plan9.go @@ -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 { -- 2.50.0