Commit c2cdfbd1 authored by Richard Miller's avatar Richard Miller Committed by David du Colombier

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/97595Reviewed-by: 's avatarDavid du Colombier <0intro@gmail.com>
Reviewed-by: 's avatarAustin Clements <austin@google.com>
Run-TryBot: David du Colombier <0intro@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 1be58dcd
...@@ -9,6 +9,7 @@ import "unsafe" ...@@ -9,6 +9,7 @@ import "unsafe"
const memDebug = false const memDebug = false
var bloc uintptr var bloc uintptr
var blocMax uintptr
var memlock mutex var memlock mutex
type memHdr struct { type memHdr struct {
...@@ -122,14 +123,18 @@ func memRound(p uintptr) uintptr { ...@@ -122,14 +123,18 @@ func memRound(p uintptr) uintptr {
func initBloc() { func initBloc() {
bloc = memRound(firstmoduledata.end) bloc = memRound(firstmoduledata.end)
blocMax = bloc
} }
func sbrk(n uintptr) unsafe.Pointer { func sbrk(n uintptr) unsafe.Pointer {
// Plan 9 sbrk from /sys/src/libc/9sys/sbrk.c // Plan 9 sbrk from /sys/src/libc/9sys/sbrk.c
bl := bloc bl := bloc
n = memRound(n) n = memRound(n)
if brk_(unsafe.Pointer(bl+n)) < 0 { if bl+n > blocMax {
return nil if brk_(unsafe.Pointer(bl+n)) < 0 {
return nil
}
blocMax = bl + n
} }
bloc += n bloc += n
return unsafe.Pointer(bl) return unsafe.Pointer(bl)
...@@ -150,10 +155,11 @@ func sysFree(v unsafe.Pointer, n uintptr, sysStat *uint64) { ...@@ -150,10 +155,11 @@ func sysFree(v unsafe.Pointer, n uintptr, sysStat *uint64) {
mSysStatDec(sysStat, n) mSysStatDec(sysStat, n)
lock(&memlock) lock(&memlock)
if uintptr(v)+n == bloc { if uintptr(v)+n == bloc {
// address range being freed is at the end of memory, // Address range being freed is at the end of memory,
// so shrink the address space // 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 bloc -= n
brk_(unsafe.Pointer(bloc))
} else { } else {
memFree(v, n) memFree(v, n)
memCheck() memCheck()
...@@ -180,8 +186,8 @@ func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer { ...@@ -180,8 +186,8 @@ func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer {
lock(&memlock) lock(&memlock)
var p unsafe.Pointer var p unsafe.Pointer
if uintptr(v) == bloc { if uintptr(v) == bloc {
// address hint is the current end of memory, // Address hint is the current end of memory,
// so try to extend the address space // so try to extend the address space.
p = sbrk(n) p = sbrk(n)
} }
if p == nil { if p == nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment