Browse Source

unix: fix Getpagesize to return actual system value on Solaris

In preparation for issues such as #10180, Getpagesize() needs to be
fixed to return the actual system's page size instead of assuming it's
always 4096.

This is particularly important for future platform support on Solaris.

Fixes #12076

Change-Id: I78205165909529215fe93ed6ba56e9c3ee1c2abb
Reviewed-on: https://go-review.googlesource.com/14483
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Shawn Walker-Salas 10 years ago
parent
commit
131454b560

+ 16 - 0
unix/syscall_solaris.go

@@ -13,6 +13,7 @@
 package unix
 package unix
 
 
 import (
 import (
+	"sync/atomic"
 	"syscall"
 	"syscall"
 	"unsafe"
 	"unsafe"
 )
 )
@@ -548,3 +549,18 @@ func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, e
 func Munmap(b []byte) (err error) {
 func Munmap(b []byte) (err error) {
 	return mapper.Munmap(b)
 	return mapper.Munmap(b)
 }
 }
+
+//sys	sysconf(name int) (n int64, err error)
+
+// pageSize caches the value of Getpagesize, since it can't change
+// once the system is booted.
+var pageSize int64 // accessed atomically
+
+func Getpagesize() int {
+	n := atomic.LoadInt64(&pageSize)
+	if n == 0 {
+		n, _ = sysconf(_SC_PAGESIZE)
+		atomic.StoreInt64(&pageSize, n)
+	}
+	return int(n)
+}

+ 0 - 2
unix/syscall_solaris_amd64.go

@@ -6,8 +6,6 @@
 
 
 package unix
 package unix
 
 
-func Getpagesize() int { return 4096 }
-
 func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
 func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
 
 
 func NsecToTimespec(nsec int64) (ts Timespec) {
 func NsecToTimespec(nsec int64) (ts Timespec) {

+ 4 - 0
unix/types_solaris.go

@@ -217,6 +217,10 @@ type BpfTimeval C.struct_bpf_timeval
 
 
 type BpfHdr C.struct_bpf_hdr
 type BpfHdr C.struct_bpf_hdr
 
 
+// sysconf information
+
+const _SC_PAGESIZE = C._SC_PAGESIZE
+
 // Terminal handling
 // Terminal handling
 
 
 type Termios C.struct_termios
 type Termios C.struct_termios

+ 13 - 1
unix/zsyscall_solaris_amd64.go

@@ -91,6 +91,7 @@ import (
 //go:cgo_import_dynamic libsocket_setsockopt setsockopt "libsocket.so"
 //go:cgo_import_dynamic libsocket_setsockopt setsockopt "libsocket.so"
 //go:cgo_import_dynamic libsocket_recvfrom recvfrom "libsocket.so"
 //go:cgo_import_dynamic libsocket_recvfrom recvfrom "libsocket.so"
 //go:cgo_import_dynamic libsocket_recvmsg recvmsg "libsocket.so"
 //go:cgo_import_dynamic libsocket_recvmsg recvmsg "libsocket.so"
+//go:cgo_import_dynamic libc_sysconf sysconf "libc.so"
 
 
 //go:linkname procgetgroups libc_getgroups
 //go:linkname procgetgroups libc_getgroups
 //go:linkname procsetgroups libc_setgroups
 //go:linkname procsetgroups libc_setgroups
@@ -173,6 +174,7 @@ import (
 //go:linkname procsetsockopt libsocket_setsockopt
 //go:linkname procsetsockopt libsocket_setsockopt
 //go:linkname procrecvfrom libsocket_recvfrom
 //go:linkname procrecvfrom libsocket_recvfrom
 //go:linkname procrecvmsg libsocket_recvmsg
 //go:linkname procrecvmsg libsocket_recvmsg
+//go:linkname procsysconf libc_sysconf
 
 
 var (
 var (
 	procgetgroups,
 	procgetgroups,
@@ -255,7 +257,8 @@ var (
 	procgetsockname,
 	procgetsockname,
 	procsetsockopt,
 	procsetsockopt,
 	procrecvfrom,
 	procrecvfrom,
-	procrecvmsg syscallFunc
+	procrecvmsg,
+	procsysconf syscallFunc
 )
 )
 
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
@@ -1083,3 +1086,12 @@ func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
 	}
 	}
 	return
 	return
 }
 }
+
+func sysconf(name int) (n int64, err error) {
+	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procsysconf)), 1, uintptr(name), 0, 0, 0, 0, 0)
+	n = int64(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}

+ 2 - 0
unix/ztypes_solaris_amd64.go

@@ -357,6 +357,8 @@ type BpfHdr struct {
 	Pad_cgo_0 [2]byte
 	Pad_cgo_0 [2]byte
 }
 }
 
 
+const _SC_PAGESIZE = 0xb
+
 type Termios struct {
 type Termios struct {
 	Iflag     uint32
 	Iflag     uint32
 	Oflag     uint32
 	Oflag     uint32