aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/os_plan9.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2016-07-18 21:40:02 -0400
committerAustin Clements <austin@google.com>2016-09-06 21:05:50 +0000
commit276a52de55fb48c4e56a778f1f7cac9292d8fad7 (patch)
tree7ead3e72e915bad7bcead853af4ba10b237188fe /src/runtime/os_plan9.go
parentd7de8b6d231289b7a6b205508c6f02a5a475cc84 (diff)
downloadgo-276a52de55fb48c4e56a778f1f7cac9292d8fad7.tar.gz
go-276a52de55fb48c4e56a778f1f7cac9292d8fad7.zip
runtime: fetch physical page size from the OS
Currently the physical page size assumed by the runtime is hard-coded. On Linux the runtime at least fetches the OS page size during init and sanity checks against the hard-coded value, but they may still differ. On other OSes we wouldn't even notice. Add support on all OSes to fetch the actual OS physical page size during runtime init and lift the sanity check of PhysPageSize from the Linux init code to general malloc init. Currently this is the only use of the retrieved page size, but we'll add more shortly. Updates #12480 and #10180. Change-Id: I065f2834bc97c71d3208edc17fd990ec9058b6da Reviewed-on: https://go-review.googlesource.com/25050 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
Diffstat (limited to 'src/runtime/os_plan9.go')
-rw-r--r--src/runtime/os_plan9.go50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go
index 2f3a0d1a19..333f2221a2 100644
--- a/src/runtime/os_plan9.go
+++ b/src/runtime/os_plan9.go
@@ -217,6 +217,55 @@ func getproccount() int32 {
return ncpu
}
+var devswap = []byte("/dev/swap\x00")
+var pagesize = []byte(" pagesize\n")
+
+func getPageSize() uintptr {
+ var buf [2048]byte
+ var pos int
+ fd := open(&devswap[0], _OREAD, 0)
+ if fd < 0 {
+ // There's not much we can do if /dev/swap doesn't
+ // exist. However, nothing in the memory manager uses
+ // this on Plan 9, so it also doesn't really matter.
+ return minPhysPageSize
+ }
+ for pos < len(buf) {
+ n := read(fd, unsafe.Pointer(&buf[pos]), int32(len(buf)-pos))
+ if n <= 0 {
+ break
+ }
+ pos += int(n)
+ }
+ closefd(fd)
+ text := buf[:pos]
+ // Find "<n> pagesize" line.
+ bol := 0
+ for i, c := range text {
+ if c == '\n' {
+ bol = i + 1
+ }
+ if bytesHasPrefix(text[i:], pagesize) {
+ // Parse number at the beginning of this line.
+ return uintptr(_atoi(text[bol:]))
+ }
+ }
+ // Again, the page size doesn't really matter, so use a fallback.
+ return minPhysPageSize
+}
+
+func bytesHasPrefix(s, prefix []byte) bool {
+ if len(s) < len(prefix) {
+ return false
+ }
+ for i, p := range prefix {
+ if s[i] != p {
+ return false
+ }
+ }
+ return true
+}
+
var pid = []byte("#c/pid\x00")
func getpid() uint64 {
@@ -236,6 +285,7 @@ func getpid() uint64 {
func osinit() {
initBloc()
ncpu = getproccount()
+ physPageSize = getPageSize()
getg().m.procid = getpid()
notify(unsafe.Pointer(funcPC(sigtramp)))
}