summaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-08-28 20:39:32 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-08-28 20:39:32 +0000
commit32b1d51f16fe56b34e979fcfba4bc74dbd3592a9 (patch)
treecd54b1786061eb18e64ce26e6392df3096b5ba35 /libgo
parentc980510a5ab79614fcbaf5f411b1273dc9a8c7ca (diff)
runtime: move osinit to Go
This is a step toward updating libgo to 1.13. This adds the 1.13 version of the osinit function to Go code, and removes the corresponding code from the C runtime. This should simplify future updates. Some additional 1.13 code was brought in to simplify this change. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/191717 From-SVN: r275010
Diffstat (limited to 'libgo')
-rw-r--r--libgo/Makefile.am37
-rw-r--r--libgo/Makefile.in51
-rw-r--r--libgo/go/runtime/malloc.go17
-rw-r--r--libgo/go/runtime/netpoll_kqueue.go1
-rw-r--r--libgo/go/runtime/os3_solaris.go21
-rw-r--r--libgo/go/runtime/os_aix.go36
-rw-r--r--libgo/go/runtime/os_darwin.go73
-rw-r--r--libgo/go/runtime/os_dragonfly.go33
-rw-r--r--libgo/go/runtime/os_freebsd.go105
-rw-r--r--libgo/go/runtime/os_hurd.go21
-rw-r--r--libgo/go/runtime/os_linux.go63
-rw-r--r--libgo/go/runtime/os_netbsd.go40
-rw-r--r--libgo/go/runtime/os_openbsd.go60
-rw-r--r--libgo/go/runtime/stubs.go14
-rw-r--r--libgo/go/runtime/stubs2.go4
-rw-r--r--libgo/go/runtime/sys_darwin.go429
-rw-r--r--libgo/go/runtime/sys_darwin_32.go32
-rw-r--r--libgo/go/runtime/sys_darwin_64.go32
-rwxr-xr-xlibgo/mkrsysinfo.sh13
-rw-r--r--libgo/runtime/getncpu-aix.c15
-rw-r--r--libgo/runtime/getncpu-bsd.c24
-rw-r--r--libgo/runtime/getncpu-hurd.c16
-rw-r--r--libgo/runtime/getncpu-irix.c16
-rw-r--r--libgo/runtime/getncpu-linux.c36
-rw-r--r--libgo/runtime/getncpu-none.c12
-rw-r--r--libgo/runtime/getncpu-solaris.c16
-rw-r--r--libgo/runtime/go-libmain.c3
-rw-r--r--libgo/runtime/go-main.c3
-rw-r--r--libgo/runtime/runtime.h8
29 files changed, 493 insertions, 738 deletions
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index 9348af94863..341bac021ee 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -413,40 +413,6 @@ else
rtems_task_variable_add_file =
endif
-if LIBGO_IS_LINUX
-runtime_getncpu_file = runtime/getncpu-linux.c
-else
-if LIBGO_IS_DARWIN
-runtime_getncpu_file = runtime/getncpu-bsd.c
-else
-if LIBGO_IS_IRIX
-runtime_getncpu_file = runtime/getncpu-irix.c
-else
-if LIBGO_IS_SOLARIS
-runtime_getncpu_file = runtime/getncpu-solaris.c
-else
-if LIBGO_IS_FREEBSD
-runtime_getncpu_file = runtime/getncpu-bsd.c
-else
-if LIBGO_IS_NETBSD
-runtime_getncpu_file = runtime/getncpu-bsd.c
-else
-if LIBGO_IS_AIX
-runtime_getncpu_file = runtime/getncpu-aix.c
-else
-if LIBGO_IS_HURD
-runtime_getncpu_file = runtime/getncpu-hurd.c
-else
-runtime_getncpu_file = runtime/getncpu-none.c
-endif
-endif
-endif
-endif
-endif
-endif
-endif
-endif
-
runtime_files = \
runtime/aeshash.c \
runtime/go-assert.c \
@@ -479,8 +445,7 @@ runtime_files = \
runtime/stack.c \
runtime/yield.c \
runtime/go-context.S \
- $(rtems_task_variable_add_file) \
- $(runtime_getncpu_file)
+ $(rtems_task_variable_add_file)
version.go: s-version; @true
s-version: Makefile
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index 153bc95530e..f415ca60116 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -230,16 +230,7 @@ am__DEPENDENCIES_4 = $(am__DEPENDENCIES_2) \
libgo_llgo_la_DEPENDENCIES = $(am__DEPENDENCIES_4)
@LIBGO_IS_RTEMS_TRUE@am__objects_1 = \
@LIBGO_IS_RTEMS_TRUE@ runtime/rtems-task-variable-add.lo
-@LIBGO_IS_AIX_FALSE@@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_HURD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_2 = runtime/getncpu-none.lo
-@LIBGO_IS_AIX_FALSE@@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_HURD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_2 = runtime/getncpu-hurd.lo
-@LIBGO_IS_AIX_TRUE@@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_2 = runtime/getncpu-aix.lo
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@am__objects_2 = runtime/getncpu-bsd.lo
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_2 = runtime/getncpu-bsd.lo
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@am__objects_2 = runtime/getncpu-solaris.lo
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@am__objects_2 = runtime/getncpu-irix.lo
-@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@am__objects_2 = runtime/getncpu-bsd.lo
-@LIBGO_IS_LINUX_TRUE@am__objects_2 = runtime/getncpu-linux.lo
-am__objects_3 = runtime/aeshash.lo runtime/go-assert.lo \
+am__objects_2 = runtime/aeshash.lo runtime/go-assert.lo \
runtime/go-caller.lo runtime/go-callers.lo runtime/go-cdiv.lo \
runtime/go-cgo.lo runtime/go-construct-map.lo \
runtime/go-ffi.lo runtime/go-fieldtrack.lo \
@@ -252,9 +243,8 @@ am__objects_3 = runtime/aeshash.lo runtime/go-assert.lo \
runtime/go-unwind.lo runtime/go-varargs.lo \
runtime/env_posix.lo runtime/panic.lo runtime/print.lo \
runtime/proc.lo runtime/runtime_c.lo runtime/stack.lo \
- runtime/yield.lo runtime/go-context.lo $(am__objects_1) \
- $(am__objects_2)
-am_libgo_llgo_la_OBJECTS = $(am__objects_3)
+ runtime/yield.lo runtime/go-context.lo $(am__objects_1)
+am_libgo_llgo_la_OBJECTS = $(am__objects_2)
libgo_llgo_la_OBJECTS = $(am_libgo_llgo_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -265,7 +255,7 @@ libgo_llgo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(libgo_llgo_la_LDFLAGS) $(LDFLAGS) -o $@
@GOC_IS_LLGO_TRUE@am_libgo_llgo_la_rpath = -rpath $(toolexeclibdir)
libgo_la_DEPENDENCIES = $(am__DEPENDENCIES_4)
-am_libgo_la_OBJECTS = $(am__objects_3)
+am_libgo_la_OBJECTS = $(am__objects_2)
libgo_la_OBJECTS = $(am_libgo_la_OBJECTS)
libgo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -871,15 +861,6 @@ noinst_DATA = internal/x/net/internal/nettest.gox \
zdefaultcc.go
@LIBGO_IS_RTEMS_FALSE@rtems_task_variable_add_file =
@LIBGO_IS_RTEMS_TRUE@rtems_task_variable_add_file = runtime/rtems-task-variable-add.c
-@LIBGO_IS_AIX_FALSE@@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_HURD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@runtime_getncpu_file = runtime/getncpu-none.c
-@LIBGO_IS_AIX_FALSE@@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_HURD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@runtime_getncpu_file = runtime/getncpu-hurd.c
-@LIBGO_IS_AIX_TRUE@@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@runtime_getncpu_file = runtime/getncpu-aix.c
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@runtime_getncpu_file = runtime/getncpu-bsd.c
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@runtime_getncpu_file = runtime/getncpu-bsd.c
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@runtime_getncpu_file = runtime/getncpu-solaris.c
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@runtime_getncpu_file = runtime/getncpu-irix.c
-@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@runtime_getncpu_file = runtime/getncpu-bsd.c
-@LIBGO_IS_LINUX_TRUE@runtime_getncpu_file = runtime/getncpu-linux.c
runtime_files = \
runtime/aeshash.c \
runtime/go-assert.c \
@@ -912,8 +893,7 @@ runtime_files = \
runtime/stack.c \
runtime/yield.c \
runtime/go-context.S \
- $(rtems_task_variable_add_file) \
- $(runtime_getncpu_file)
+ $(rtems_task_variable_add_file)
GCCGO_INSTALL_NAME := $(shell echo gccgo|sed '$(program_transform_name)')
GCC_INSTALL_NAME := $(shell echo gcc|sed '$(program_transform_name)')
@@ -1385,20 +1365,6 @@ runtime/go-context.lo: runtime/$(am__dirstamp) \
runtime/$(DEPDIR)/$(am__dirstamp)
runtime/rtems-task-variable-add.lo: runtime/$(am__dirstamp) \
runtime/$(DEPDIR)/$(am__dirstamp)
-runtime/getncpu-none.lo: runtime/$(am__dirstamp) \
- runtime/$(DEPDIR)/$(am__dirstamp)
-runtime/getncpu-hurd.lo: runtime/$(am__dirstamp) \
- runtime/$(DEPDIR)/$(am__dirstamp)
-runtime/getncpu-aix.lo: runtime/$(am__dirstamp) \
- runtime/$(DEPDIR)/$(am__dirstamp)
-runtime/getncpu-bsd.lo: runtime/$(am__dirstamp) \
- runtime/$(DEPDIR)/$(am__dirstamp)
-runtime/getncpu-solaris.lo: runtime/$(am__dirstamp) \
- runtime/$(DEPDIR)/$(am__dirstamp)
-runtime/getncpu-irix.lo: runtime/$(am__dirstamp) \
- runtime/$(DEPDIR)/$(am__dirstamp)
-runtime/getncpu-linux.lo: runtime/$(am__dirstamp) \
- runtime/$(DEPDIR)/$(am__dirstamp)
libgo-llgo.la: $(libgo_llgo_la_OBJECTS) $(libgo_llgo_la_DEPENDENCIES) $(EXTRA_libgo_llgo_la_DEPENDENCIES)
$(AM_V_CCLD)$(libgo_llgo_la_LINK) $(am_libgo_llgo_la_rpath) $(libgo_llgo_la_OBJECTS) $(libgo_llgo_la_LIBADD) $(LIBS)
@@ -1416,13 +1382,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/aeshash.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/env_posix.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/getncpu-aix.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/getncpu-bsd.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/getncpu-hurd.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/getncpu-irix.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/getncpu-linux.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/getncpu-none.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/getncpu-solaris.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-assert.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-caller.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-callers.Plo@am__quote@
diff --git a/libgo/go/runtime/malloc.go b/libgo/go/runtime/malloc.go
index c0b4caab32a..68e54949350 100644
--- a/libgo/go/runtime/malloc.go
+++ b/libgo/go/runtime/malloc.go
@@ -335,6 +335,23 @@ const (
// mallocinit.
var physPageSize uintptr
+// physHugePageSize is the size in bytes of the OS's default physical huge
+// page size whose allocation is opaque to the application. It is assumed
+// and verified to be a power of two.
+//
+// If set, this must be set by the OS init code (typically in osinit) before
+// mallocinit. However, setting it at all is optional, and leaving the default
+// value is always safe (though potentially less efficient).
+//
+// Since physHugePageSize is always assumed to be a power of two,
+// physHugePageShift is defined as physHugePageSize == 1 << physHugePageShift.
+// The purpose of physHugePageShift is to avoid doing divisions in
+// performance critical functions.
+var (
+ physHugePageSize uintptr
+ physHugePageShift uint
+)
+
// OS-defined helpers:
//
// sysAlloc obtains a large chunk of zeroed memory from the
diff --git a/libgo/go/runtime/netpoll_kqueue.go b/libgo/go/runtime/netpoll_kqueue.go
index 3d6265092e6..4ea3ac9f27e 100644
--- a/libgo/go/runtime/netpoll_kqueue.go
+++ b/libgo/go/runtime/netpoll_kqueue.go
@@ -20,6 +20,7 @@ func kevent(kq int32, ch *keventt, nch uintptr, ev *keventt, nev uintptr, ts *ti
//extern __go_fcntl_uintptr
func fcntlUintptr(fd, cmd, arg uintptr) (uintptr, uintptr)
+//go:nosplit
func closeonexec(fd int32) {
fcntlUintptr(uintptr(fd), _F_SETFD, _FD_CLOEXEC)
}
diff --git a/libgo/go/runtime/os3_solaris.go b/libgo/go/runtime/os3_solaris.go
index e67d32c8054..d5fbccd36e7 100644
--- a/libgo/go/runtime/os3_solaris.go
+++ b/libgo/go/runtime/os3_solaris.go
@@ -12,10 +12,27 @@ var executablePath string
func getexecname() *byte
//extern getpagesize
-func getpagesize() int32
+func getPageSize() int32
+
+//extern sysconf
+func sysconf(int32) _C_long
+
+func getncpu() int32 {
+ n := int32(sysconf(__SC_NPROCESSORS_ONLN))
+ if n < 1 {
+ return 1
+ }
+ return n
+}
+
+func osinit() {
+ ncpu = getncpu()
+ if physPageSize == 0 {
+ physPageSize = uintptr(getPageSize())
+ }
+}
func sysargs(argc int32, argv **byte) {
- physPageSize = uintptr(getpagesize())
executablePath = gostringnocopy(getexecname())
}
diff --git a/libgo/go/runtime/os_aix.go b/libgo/go/runtime/os_aix.go
index 9211f21ab3d..b337330c8f2 100644
--- a/libgo/go/runtime/os_aix.go
+++ b/libgo/go/runtime/os_aix.go
@@ -6,7 +6,16 @@
package runtime
-import "unsafe"
+import (
+ "internal/cpu"
+ "unsafe"
+)
+
+//extern sysconf
+func sysconf(int32) _C_long
+
+//extern getsystemcfg
+func getsystemcfg(int32) uint64
type mOS struct {
waitsema uintptr // semaphore for parking on locks
@@ -106,7 +115,32 @@ func semawakeup(mp *m) {
}
}
+func osinit() {
+ ncpu = int32(sysconf(__SC_NPROCESSORS_ONLN))
+ physPageSize = uintptr(sysconf(__SC_PAGE_SIZE))
+ setupSystemConf()
+}
+
const (
_CLOCK_REALTIME = 9
_CLOCK_MONOTONIC = 10
)
+
+const (
+ // getsystemcfg constants
+ _SC_IMPL = 2
+ _IMPL_POWER8 = 0x10000
+ _IMPL_POWER9 = 0x20000
+)
+
+// setupSystemConf retrieves information about the CPU and updates
+// cpu.HWCap variables.
+func setupSystemConf() {
+ impl := getsystemcfg(_SC_IMPL)
+ if impl&_IMPL_POWER8 != 0 {
+ cpu.HWCap2 |= cpu.PPC_FEATURE2_ARCH_2_07
+ }
+ if impl&_IMPL_POWER9 != 0 {
+ cpu.HWCap2 |= cpu.PPC_FEATURE2_ARCH_3_00
+ }
+}
diff --git a/libgo/go/runtime/os_darwin.go b/libgo/go/runtime/os_darwin.go
index 235f7943f8d..deaa9e9d26d 100644
--- a/libgo/go/runtime/os_darwin.go
+++ b/libgo/go/runtime/os_darwin.go
@@ -6,6 +6,24 @@ package runtime
import "unsafe"
+//extern pipe
+func libcPipe([2]int32) int32
+
+func pipe() (r, w int32, e int32) {
+ var p [2]int32
+ r := libcPipe(noescape(unsafe.Pointer(&p)))
+ if r < 0 {
+ e = int32(errno())
+ }
+ return p[0], p[1], e
+}
+
+//go:nosplit
+func setNonblock(fd int32) {
+ flags := fcntlUintptr(uintptr(fd), _F_GETFL, 0)
+ fcntlUintptr(uintptr(fd), _F_SETFL, flags|_O_NONBLOCK)
+}
+
type mOS struct {
initialized bool
mutex pthreadmutex
@@ -74,3 +92,58 @@ func semawakeup(mp *m) {
}
pthread_mutex_unlock(&mp.mutex)
}
+
+// The read and write file descriptors used by the sigNote functions.
+var sigNoteRead, sigNoteWrite int32
+
+// sigNoteSetup initializes an async-signal-safe note.
+//
+// The current implementation of notes on Darwin is not async-signal-safe,
+// because the functions pthread_mutex_lock, pthread_cond_signal, and
+// pthread_mutex_unlock, called by semawakeup, are not async-signal-safe.
+// There is only one case where we need to wake up a note from a signal
+// handler: the sigsend function. The signal handler code does not require
+// all the features of notes: it does not need to do a timed wait.
+// This is a separate implementation of notes, based on a pipe, that does
+// not support timed waits but is async-signal-safe.
+func sigNoteSetup(*note) {
+ if sigNoteRead != 0 || sigNoteWrite != 0 {
+ throw("duplicate sigNoteSetup")
+ }
+ var errno int32
+ sigNoteRead, sigNoteWrite, errno = pipe()
+ if errno != 0 {
+ throw("pipe failed")
+ }
+ closeonexec(sigNoteRead)
+ closeonexec(sigNoteWrite)
+
+ // Make the write end of the pipe non-blocking, so that if the pipe
+ // buffer is somehow full we will not block in the signal handler.
+ // Leave the read end of the pipe blocking so that we will block
+ // in sigNoteSleep.
+ setNonblock(sigNoteWrite)
+}
+
+// sigNoteWakeup wakes up a thread sleeping on a note created by sigNoteSetup.
+func sigNoteWakeup(*note) {
+ var b byte
+ write(uintptr(sigNoteWrite), unsafe.Pointer(&b), 1)
+}
+
+// sigNoteSleep waits for a note created by sigNoteSetup to be woken.
+func sigNoteSleep(*note) {
+ entersyscallblock()
+ var b byte
+ read(sigNoteRead, unsafe.Pointer(&b), 1)
+ exitsyscall()
+}
+
+// BSD interface for threading.
+func osinit() {
+ // pthread_create delayed until end of goenvs so that we
+ // can look at the environment first.
+
+ ncpu = getncpu()
+ physPageSize = getPageSize()
+}
diff --git a/libgo/go/runtime/os_dragonfly.go b/libgo/go/runtime/os_dragonfly.go
index abcad725108..d214f7f537b 100644
--- a/libgo/go/runtime/os_dragonfly.go
+++ b/libgo/go/runtime/os_dragonfly.go
@@ -19,6 +19,32 @@ func sys_umtx_sleep(addr *uint32, val, timeout int32) int32
//extern umtx_wakeup
func sys_umtx_wakeup(addr *uint32, val int32) int32
+//go:noescape
+//extern sysctl
+func sysctl(*uint32, uint32, *byte, *uintptr, *byte, uintptr) int32
+
+func getncpu() int32 {
+ mib := [2]uint32{_CTL_HW, _HW_NCPU}
+ out := uint32(0)
+ nout := uintptr(unsafe.Sizeof(out))
+ ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+ if ret >= 0 {
+ return int32(out)
+ }
+ return 1
+}
+
+func getPageSize() uintptr {
+ mib := [2]uint32{_CTL_HW, _HW_PAGESIZE}
+ out := uint32(0)
+ nout := uintptr(unsafe.Sizeof(out))
+ ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+ if ret >= 0 {
+ return uintptr(out)
+ }
+ return 0
+}
+
//go:nosplit
func futexsleep(addr *uint32, val uint32, ns int64) {
systemstack(func() {
@@ -61,3 +87,10 @@ func futexwakeup(addr *uint32, cnt uint32) {
*(*int32)(unsafe.Pointer(uintptr(0x1006))) = 0x1006
})
}
+
+func osinit() {
+ ncpu = getncpu()
+ if physPageSize == 0 {
+ physPageSize = getPageSize()
+ }
+}
diff --git a/libgo/go/runtime/os_freebsd.go b/libgo/go/runtime/os_freebsd.go
index 4cce6fdb7f4..f8577e4226e 100644
--- a/libgo/go/runtime/os_freebsd.go
+++ b/libgo/go/runtime/os_freebsd.go
@@ -14,6 +14,104 @@ type mOS struct{}
//extern _umtx_op
func sys_umtx_op(addr *uint32, mode int32, val uint32, uaddr1 uinptr, ts *umtx_time) int32
+//go:noescape
+//extern sysctl
+func sysctl(*uint32, uint32, *byte, *uintptr, *byte, uintptr) int32
+
+const (
+ _CTL_MAXNAME = 24
+ _CPU_LEVEL_WHICH = 3
+ _CPU_WHICH_PID = 2
+)
+
+// From FreeBSD's <sys/sysctl.h>
+const (
+ _CTL_HW = 6
+ _HW_PAGESIZE = 7
+)
+
+// Undocumented numbers from FreeBSD's lib/libc/gen/sysctlnametomib.c.
+const (
+ _CTL_QUERY = 0
+ _CTL_QUERY_MIB = 3
+)
+
+// sysctlnametomib fill mib with dynamically assigned sysctl entries of name,
+// return count of effected mib slots, return 0 on error.
+func sysctlnametomib(name []byte, mib *[_CTL_MAXNAME]uint32) uint32 {
+ oid := [2]uint32{_CTL_QUERY, _CTL_QUERY_MIB}
+ miblen := uintptr(_CTL_MAXNAME)
+ if sysctl(&oid[0], 2, (*byte)(unsafe.Pointer(mib)), &miblen, (*byte)(unsafe.Pointer(&name[0])), (uintptr)(len(name))) < 0 {
+ return 0
+ }
+ miblen /= unsafe.Sizeof(uint32(0))
+ if miblen <= 0 {
+ return 0
+ }
+ return uint32(miblen)
+}
+
+const (
+ _CPU_CURRENT_PID = -1 // Current process ID.
+)
+
+//go:noescape
+//extern cpuset_getaffinity
+func cpuset_getaffinity(level int32, which int32, id int64, size uintptr, mask *byte) int32
+
+//go:systemstack
+func getncpu() int32 {
+ // Use a large buffer for the CPU mask. We're on the system
+ // stack, so this is fine, and we can't allocate memory for a
+ // dynamically-sized buffer at this point.
+ const maxCPUs = 64 * 1024
+ var mask [maxCPUs / 8]byte
+ var mib [_CTL_MAXNAME]uint32
+
+ // According to FreeBSD's /usr/src/sys/kern/kern_cpuset.c,
+ // cpuset_getaffinity return ERANGE when provided buffer size exceed the limits in kernel.
+ // Querying kern.smp.maxcpus to calculate maximum buffer size.
+ // See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=200802
+
+ // Variable kern.smp.maxcpus introduced at Dec 23 2003, revision 123766,
+ // with dynamically assigned sysctl entries.
+ miblen := sysctlnametomib([]byte("kern.smp.maxcpus"), &mib)
+ if miblen == 0 {
+ return 1
+ }
+
+ // Query kern.smp.maxcpus.
+ dstsize := uintptr(4)
+ maxcpus := uint32(0)
+ if sysctl(&mib[0], miblen, (*byte)(unsafe.Pointer(&maxcpus)), &dstsize, nil, 0) != 0 {
+ return 1
+ }
+
+ maskSize := uintptr(int(maxcpus+7) / 8)
+ if maskSize < sys.PtrSize {
+ maskSize = sys.PtrSize
+ }
+ if maskSize > uintptr(len(mask)) {
+ maskSize = uintptr(len(mask))
+ }
+
+ if cpuset_getaffinity(_CPU_LEVEL_WHICH, _CPU_WHICH_PID, _CPU_CURRENT_PID,
+ maskSize, (*byte)(unsafe.Pointer(&mask[0]))) != 0 {
+ return 1
+ }
+ n := int32(0)
+ for _, v := range mask[:maskSize] {
+ for v != 0 {
+ n += int32(v & 1)
+ v >>= 1
+ }
+ }
+ if n == 0 {
+ return 1
+ }
+ return n
+}
+
func getPageSize() uintptr {
mib := [2]uint32{_CTL_HW, _HW_PAGESIZE}
out := uint32(0)
@@ -64,6 +162,13 @@ func futexwakeup(addr *uint32, cnt uint32) {
})
}
+func osinit() {
+ ncpu = getncpu()
+ if physPageSize == 0 {
+ physPageSize = getPageSize()
+ }
+}
+
func sysargs(argc int32, argv **byte) {
n := argc + 1
diff --git a/libgo/go/runtime/os_hurd.go b/libgo/go/runtime/os_hurd.go
index 12825532a26..3a545d0768d 100644
--- a/libgo/go/runtime/os_hurd.go
+++ b/libgo/go/runtime/os_hurd.go
@@ -8,6 +8,12 @@ package runtime
import "unsafe"
+//extern sysconf
+func sysconf(int32) _C_long
+
+//extern getpagesize
+func getPageSize() int32
+
type mOS struct {
waitsema uintptr // semaphore for parking on locks
}
@@ -85,3 +91,18 @@ func semawakeup(mp *m) {
throw("sem_post")
}
}
+
+func getncpu() int32 {
+ n := int32(sysconf(_SC_NPROCESSORS_ONLN))
+ if n < 1 {
+ return 1
+ }
+ return n
+}
+
+func osinit() {
+ ncpu = getncpu()
+ if physPageSize == 0 {
+ physPageSize = uintptr(getPageSize())
+ }
+}
diff --git a/libgo/go/runtime/os_linux.go b/libgo/go/runtime/os_linux.go
index 04314bdf9e4..b72872f1822 100644
--- a/libgo/go/runtime/os_linux.go
+++ b/libgo/go/runtime/os_linux.go
@@ -17,6 +17,12 @@ func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer,
return int32(syscall(_SYS_futex, uintptr(addr), uintptr(op), uintptr(val), uintptr(ts), uintptr(addr2), uintptr(val3)))
}
+// For sched_getaffinity use the system call rather than the libc call,
+// because the system call returns the number of entries set by the kernel.
+func sched_getaffinity(pid _pid_t, cpusetsize uintptr, mask *byte) int32 {
+ return int32(syscall(_SYS_sched_getaffinity, uintptr(pid), cpusetsize, uintptr(unsafe.Pointer(mask)), 0, 0, 0))
+}
+
// Linux futex.
//
// futexsleep(uint32 *addr, uint32 val)
@@ -84,6 +90,33 @@ func futexwakeup(addr *uint32, cnt uint32) {
*(*int32)(unsafe.Pointer(uintptr(0x1006))) = 0x1006
}
+func getproccount() int32 {
+ // This buffer is huge (8 kB) but we are on the system stack
+ // and there should be plenty of space (64 kB).
+ // Also this is a leaf, so we're not holding up the memory for long.
+ // See golang.org/issue/11823.
+ // The suggested behavior here is to keep trying with ever-larger
+ // buffers, but we don't have a dynamic memory allocator at the
+ // moment, so that's a bit tricky and seems like overkill.
+ const maxCPUs = 64 * 1024
+ var buf [maxCPUs / 8]byte
+ r := sched_getaffinity(0, unsafe.Sizeof(buf), &buf[0])
+ if r < 0 {
+ return 1
+ }
+ n := int32(0)
+ for _, v := range buf[:r] {
+ for v != 0 {
+ n += int32(v & 1)
+ v >>= 1
+ }
+ }
+ if n == 0 {
+ n = 1
+ }
+ return n
+}
+
const (
_AT_NULL = 0 // End of vector
_AT_PAGESZ = 6 // System physical page size
@@ -178,3 +211,33 @@ func sysauxv(auxv []uintptr) int {
}
return i / 2
}
+
+var sysTHPSizePath = []byte("/sys/kernel/mm/transparent_hugepage/hpage_pmd_size\x00")
+
+func getHugePageSize() uintptr {
+ var numbuf [20]byte
+ fd := open(&sysTHPSizePath[0], 0 /* O_RDONLY */, 0)
+ if fd < 0 {
+ return 0
+ }
+ n := read(fd, noescape(unsafe.Pointer(&numbuf[0])), int32(len(numbuf)))
+ closefd(fd)
+ if n <= 0 {
+ return 0
+ }
+ l := n - 1 // remove trailing newline
+ v, ok := atoi(slicebytetostringtmp(numbuf[:l]))
+ if !ok || v < 0 {
+ v = 0
+ }
+ if v&(v-1) != 0 {
+ // v is not a power of 2
+ return 0
+ }
+ return uintptr(v)
+}
+
+func osinit() {
+ ncpu = getproccount()
+ physHugePageSize = getHugePageSize()
+}
diff --git a/libgo/go/runtime/os_netbsd.go b/libgo/go/runtime/os_netbsd.go
index 16a11926dda..b7aa9535df3 100644
--- a/libgo/go/runtime/os_netbsd.go
+++ b/libgo/go/runtime/os_netbsd.go
@@ -22,6 +22,39 @@ func lwp_park(ts int32, rel int32, abstime *timespec, unpark int32, hint, unpark
//extern lwp_unpark
func lwp_unpark(lwp int32, hint unsafe.Pointer) int32
+//go:noescape
+//extern sysctl
+func sysctl(*uint32, uint32, *byte, *uintptr, *byte, uintptr) int32
+
+// From NetBSD's <sys/sysctl.h>
+const (
+ _CTL_HW = 6
+ _HW_NCPU = 3
+ _HW_PAGESIZE = 7
+)
+
+func getncpu() int32 {
+ mib := [2]uint32{_CTL_HW, _HW_NCPU}
+ out := uint32(0)
+ nout := unsafe.Sizeof(out)
+ ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+ if ret >= 0 {
+ return int32(out)
+ }
+ return 1
+}
+
+func getPageSize() uintptr {
+ mib := [2]uint32{_CTL_HW, _HW_PAGESIZE}
+ out := uint32(0)
+ nout := unsafe.Sizeof(out)
+ ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+ if ret >= 0 {
+ return uintptr(out)
+ }
+ return 0
+}
+
//go:nosplit
func semacreate(mp *m) {
}
@@ -77,3 +110,10 @@ func semawakeup(mp *m) {
})
}
}
+
+func osinit() {
+ ncpu = getncpu()
+ if physPageSize == 0 {
+ physPageSize = getPageSize()
+ }
+}
diff --git a/libgo/go/runtime/os_openbsd.go b/libgo/go/runtime/os_openbsd.go
index 4f05665f6ee..4298172b054 100644
--- a/libgo/go/runtime/os_openbsd.go
+++ b/libgo/go/runtime/os_openbsd.go
@@ -22,6 +22,58 @@ func thrsleep(ident uintptr, clock_id int32, tsp *timespec, lock uintptr, abort
//extern thrwakeup
func thrwakeup(ident uintptr, n int32) int32
+//go:noescape
+//extern sysctl
+func sysctl(*uint32, uint32, *byte, *uintptr, *byte, uintptr) int32
+
+// From OpenBSD's <sys/sysctl.h>
+const (
+ _CTL_KERN = 1
+ _KERN_OSREV = 3
+
+ _CTL_HW = 6
+ _HW_NCPU = 3
+ _HW_PAGESIZE = 7
+ _HW_NCPUONLINE = 25
+)
+
+func sysctlInt(mib []uint32) (int32, bool) {
+ var out int32
+ nout := unsafe.Sizeof(out)
+ ret := sysctl(&mib[0], uint32(len(mib)), (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+ if ret < 0 {
+ return 0, false
+ }
+ return out, true
+}
+
+func getncpu() int32 {
+ // Try hw.ncpuonline first because hw.ncpu would report a number twice as
+ // high as the actual CPUs running on OpenBSD 6.4 with hyperthreading
+ // disabled (hw.smt=0). See https://golang.org/issue/30127
+ if n, ok := sysctlInt([]uint32{_CTL_HW, _HW_NCPUONLINE}); ok {
+ return int32(n)
+ }
+ if n, ok := sysctlInt([]uint32{_CTL_HW, _HW_NCPU}); ok {
+ return int32(n)
+ }
+ return 1
+}
+
+func getPageSize() uintptr {
+ if ps, ok := sysctlInt([]uint32{_CTL_HW, _HW_PAGESIZE}); ok {
+ return uintptr(ps)
+ }
+ return 0
+}
+
+func getOSRev() int {
+ if osrev, ok := sysctlInt([]uint32{_CTL_KERN, _KERN_OSREV}); ok {
+ return int(osrev)
+ }
+ return 0
+}
+
//go:nosplit
func semacreate(mp *m) {
}
@@ -75,3 +127,11 @@ func semawakeup(mp *m) {
})
}
}
+
+func osinit() {
+ ncpu = getncpu()
+ physPageSize = getPageSize()
+ haveMapStack = getOSRev() >= 201805 // OpenBSD 6.3
+}
+
+var haveMapStack = false
diff --git a/libgo/go/runtime/stubs.go b/libgo/go/runtime/stubs.go
index e00d759b706..a81bf92ad4f 100644
--- a/libgo/go/runtime/stubs.go
+++ b/libgo/go/runtime/stubs.go
@@ -333,20 +333,6 @@ func rethrowException()
// used by the stack unwinder.
func unwindExceptionSize() uintptr
-// Called by C code to set the number of CPUs.
-//go:linkname setncpu runtime.setncpu
-func setncpu(n int32) {
- ncpu = n
-}
-
-// Called by C code to set the page size.
-//go:linkname setpagesize runtime.setpagesize
-func setpagesize(s uintptr) {
- if physPageSize == 0 {
- physPageSize = s
- }
-}
-
const uintptrMask = 1<<(8*sys.PtrSize) - 1
type bitvector struct {
diff --git a/libgo/go/runtime/stubs2.go b/libgo/go/runtime/stubs2.go
index 1cb910cd111..dcbbffa9180 100644
--- a/libgo/go/runtime/stubs2.go
+++ b/libgo/go/runtime/stubs2.go
@@ -6,7 +6,6 @@
// +build !windows
// +build !nacl
// +build !js
-// +build !darwin
package runtime
@@ -32,3 +31,6 @@ func exitThread(wait *uint32) {
// This is never used by gccgo.
throw("exitThread")
}
+
+// So that the C initialization code can call osinit.
+//go:linkname osinit runtime.osinit
diff --git a/libgo/go/runtime/sys_darwin.go b/libgo/go/runtime/sys_darwin.go
deleted file mode 100644
index f34ac883524..00000000000
--- a/libgo/go/runtime/sys_darwin.go
+++ /dev/null
@@ -1,429 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-import "unsafe"
-
-// Call fn with arg as its argument. Return what fn returns.
-// fn is the raw pc value of the entry point of the desired function.
-// Switches to the system stack, if not already there.
-// Preserves the calling point as the location where a profiler traceback will begin.
-//go:nosplit
-func libcCall(fn, arg unsafe.Pointer) int32 {
- // Leave caller's PC/SP/G around for traceback.
- gp := getg()
- var mp *m
- if gp != nil {
- mp = gp.m
- }
- if mp != nil && mp.libcallsp == 0 {
- mp.libcallg.set(gp)
- mp.libcallpc = getcallerpc()
- // sp must be the last, because once async cpu profiler finds
- // all three values to be non-zero, it will use them
- mp.libcallsp = getcallersp()
- } else {
- // Make sure we don't reset libcallsp. This makes
- // libcCall reentrant; We remember the g/pc/sp for the
- // first call on an M, until that libcCall instance
- // returns. Reentrance only matters for signals, as
- // libc never calls back into Go. The tricky case is
- // where we call libcX from an M and record g/pc/sp.
- // Before that call returns, a signal arrives on the
- // same M and the signal handling code calls another
- // libc function. We don't want that second libcCall
- // from within the handler to be recorded, and we
- // don't want that call's completion to zero
- // libcallsp.
- // We don't need to set libcall* while we're in a sighandler
- // (even if we're not currently in libc) because we block all
- // signals while we're handling a signal. That includes the
- // profile signal, which is the one that uses the libcall* info.
- mp = nil
- }
- res := asmcgocall(fn, arg)
- if mp != nil {
- mp.libcallsp = 0
- }
- return res
-}
-
-// The X versions of syscall expect the libc call to return a 64-bit result.
-// Otherwise (the non-X version) expects a 32-bit result.
-// This distinction is required because an error is indicated by returning -1,
-// and we need to know whether to check 32 or 64 bits of the result.
-// (Some libc functions that return 32 bits put junk in the upper 32 bits of AX.)
-
-//go:linkname syscall_syscall syscall.syscall
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- entersyscallblock()
- libcCall(unsafe.Pointer(funcPC(syscall)), unsafe.Pointer(&fn))
- exitsyscall()
- return
-}
-func syscall()
-
-//go:linkname syscall_syscall6 syscall.syscall6
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
- entersyscallblock()
- libcCall(unsafe.Pointer(funcPC(syscall6)), unsafe.Pointer(&fn))
- exitsyscall()
- return
-}
-func syscall6()
-
-//go:linkname syscall_syscall6X syscall.syscall6X
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
- entersyscallblock()
- libcCall(unsafe.Pointer(funcPC(syscall6X)), unsafe.Pointer(&fn))
- exitsyscall()
- return
-}
-func syscall6X()
-
-//go:linkname syscall_rawSyscall syscall.rawSyscall
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- libcCall(unsafe.Pointer(funcPC(syscall)), unsafe.Pointer(&fn))
- return
-}
-
-//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
- libcCall(unsafe.Pointer(funcPC(syscall6)), unsafe.Pointer(&fn))
- return
-}
-
-// The *_trampoline functions convert from the Go calling convention to the C calling convention
-// and then call the underlying libc function. They are defined in sys_darwin_$ARCH.s.
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_attr_init(attr *pthreadattr) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
-}
-func pthread_attr_init_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_attr_setstacksize(attr *pthreadattr, size uintptr) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_attr_setstacksize_trampoline)), unsafe.Pointer(&attr))
-}
-func pthread_attr_setstacksize_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_attr_setdetachstate(attr *pthreadattr, state int) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
-}
-func pthread_attr_setdetachstate_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_create(attr *pthreadattr, start uintptr, arg unsafe.Pointer) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_create_trampoline)), unsafe.Pointer(&attr))
-}
-func pthread_create_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func raise(sig uint32) {
- libcCall(unsafe.Pointer(funcPC(raise_trampoline)), unsafe.Pointer(&sig))
-}
-func raise_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_self() (t pthread) {
- libcCall(unsafe.Pointer(funcPC(pthread_self_trampoline)), unsafe.Pointer(&t))
- return
-}
-func pthread_self_trampoline()
-
-func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
- args := struct {
- addr unsafe.Pointer
- n uintptr
- prot, flags, fd int32
- off uint32
- ret1 unsafe.Pointer
- ret2 int
- }{addr, n, prot, flags, fd, off, nil, 0}
- libcCall(unsafe.Pointer(funcPC(mmap_trampoline)), unsafe.Pointer(&args))
- return args.ret1, args.ret2
-}
-func mmap_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func munmap(addr unsafe.Pointer, n uintptr) {
- libcCall(unsafe.Pointer(funcPC(munmap_trampoline)), unsafe.Pointer(&addr))
-}
-func munmap_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
- libcCall(unsafe.Pointer(funcPC(madvise_trampoline)), unsafe.Pointer(&addr))
-}
-func madvise_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func read(fd int32, p unsafe.Pointer, n int32) int32 {
- return libcCall(unsafe.Pointer(funcPC(read_trampoline)), unsafe.Pointer(&fd))
-}
-func read_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func closefd(fd int32) int32 {
- return libcCall(unsafe.Pointer(funcPC(close_trampoline)), unsafe.Pointer(&fd))
-}
-func close_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func exit(code int32) {
- libcCall(unsafe.Pointer(funcPC(exit_trampoline)), unsafe.Pointer(&code))
-}
-func exit_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func usleep(usec uint32) {
- libcCall(unsafe.Pointer(funcPC(usleep_trampoline)), unsafe.Pointer(&usec))
-}
-func usleep_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func write(fd uintptr, p unsafe.Pointer, n int32) int32 {
- return libcCall(unsafe.Pointer(funcPC(write_trampoline)), unsafe.Pointer(&fd))
-}
-func write_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func open(name *byte, mode, perm int32) (ret int32) {
- return libcCall(unsafe.Pointer(funcPC(open_trampoline)), unsafe.Pointer(&name))
-}
-func open_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func nanotime() int64 {
- var r struct {
- t int64 // raw timer
- numer, denom uint32 // conversion factors. nanoseconds = t * numer / denom.
- }
- libcCall(unsafe.Pointer(funcPC(nanotime_trampoline)), unsafe.Pointer(&r))
- // Note: Apple seems unconcerned about overflow here. See
- // https://developer.apple.com/library/content/qa/qa1398/_index.html
- // Note also, numer == denom == 1 is common.
- t := r.t
- if r.numer != 1 {
- t *= int64(r.numer)
- }
- if r.denom != 1 {
- t /= int64(r.denom)
- }
- return t
-}
-func nanotime_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func walltime() (int64, int32) {
- var t timeval
- libcCall(unsafe.Pointer(funcPC(walltime_trampoline)), unsafe.Pointer(&t))
- return int64(t.tv_sec), 1000 * t.tv_usec
-}
-func walltime_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func sigaction(sig uint32, new *usigactiont, old *usigactiont) {
- libcCall(unsafe.Pointer(funcPC(sigaction_trampoline)), unsafe.Pointer(&sig))
-}
-func sigaction_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func sigprocmask(how uint32, new *sigset, old *sigset) {
- libcCall(unsafe.Pointer(funcPC(sigprocmask_trampoline)), unsafe.Pointer(&how))
-}
-func sigprocmask_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func sigaltstack(new *stackt, old *stackt) {
- if new != nil && new.ss_flags&_SS_DISABLE != 0 && new.ss_size == 0 {
- // Despite the fact that Darwin's sigaltstack man page says it ignores the size
- // when SS_DISABLE is set, it doesn't. sigaltstack returns ENOMEM
- // if we don't give it a reasonable size.
- // ref: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20140421/214296.html
- new.ss_size = 32768
- }
- libcCall(unsafe.Pointer(funcPC(sigaltstack_trampoline)), unsafe.Pointer(&new))
-}
-func sigaltstack_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func raiseproc(sig uint32) {
- libcCall(unsafe.Pointer(funcPC(raiseproc_trampoline)), unsafe.Pointer(&sig))
-}
-func raiseproc_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func setitimer(mode int32, new, old *itimerval) {
- libcCall(unsafe.Pointer(funcPC(setitimer_trampoline)), unsafe.Pointer(&mode))
-}
-func setitimer_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 {
- return libcCall(unsafe.Pointer(funcPC(sysctl_trampoline)), unsafe.Pointer(&mib))
-}
-func sysctl_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func fcntl(fd, cmd, arg int32) int32 {
- return libcCall(unsafe.Pointer(funcPC(fcntl_trampoline)), unsafe.Pointer(&fd))
-}
-func fcntl_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func kqueue() int32 {
- v := libcCall(unsafe.Pointer(funcPC(kqueue_trampoline)), nil)
- return v
-}
-func kqueue_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 {
- return libcCall(unsafe.Pointer(funcPC(kevent_trampoline)), unsafe.Pointer(&kq))
-}
-func kevent_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_mutex_init(m *pthreadmutex, attr *pthreadmutexattr) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_mutex_init_trampoline)), unsafe.Pointer(&m))
-}
-func pthread_mutex_init_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_mutex_lock(m *pthreadmutex) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_mutex_lock_trampoline)), unsafe.Pointer(&m))
-}
-func pthread_mutex_lock_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_mutex_unlock(m *pthreadmutex) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_mutex_unlock_trampoline)), unsafe.Pointer(&m))
-}
-func pthread_mutex_unlock_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_cond_init(c *pthreadcond, attr *pthreadcondattr) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_cond_init_trampoline)), unsafe.Pointer(&c))
-}
-func pthread_cond_init_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_cond_wait(c *pthreadcond, m *pthreadmutex) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_cond_wait_trampoline)), unsafe.Pointer(&c))
-}
-func pthread_cond_wait_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_cond_timedwait_relative_np(c *pthreadcond, m *pthreadmutex, t *timespec) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_cond_timedwait_relative_np_trampoline)), unsafe.Pointer(&c))
-}
-func pthread_cond_timedwait_relative_np_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_cond_signal(c *pthreadcond) int32 {
- return libcCall(unsafe.Pointer(funcPC(pthread_cond_signal_trampoline)), unsafe.Pointer(&c))
-}
-func pthread_cond_signal_trampoline()
-
-// Not used on Darwin, but must be defined.
-func exitThread(wait *uint32) {
-}
-
-//go:nosplit
-func closeonexec(fd int32) {
- fcntl(fd, _F_SETFD, _FD_CLOEXEC)
-}
-
-// Tell the linker that the libc_* functions are to be found
-// in a system library, with the libc_ prefix missing.
-
-//go:cgo_import_dynamic libc_pthread_attr_init pthread_attr_init "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_attr_setstacksize pthread_attr_setstacksize "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_attr_setdetachstate pthread_attr_setdetachstate "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_create pthread_create "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_raise raise "/usr/lib/libSystem.B.dylib"
-
-//go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib"
-
-//go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_error __error "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_usleep usleep "/usr/lib/libSystem.B.dylib"
-
-//go:cgo_import_dynamic libc_mach_timebase_info mach_timebase_info "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_mach_absolute_time mach_absolute_time "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_sigaction sigaction "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_sigmask pthread_sigmask "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_sigaltstack sigaltstack "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_setitimer setitimer "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib"
-
-//go:cgo_import_dynamic libc_pthread_mutex_init pthread_mutex_init "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_mutex_lock pthread_mutex_lock "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_mutex_unlock pthread_mutex_unlock "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_cond_init pthread_cond_init "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_cond_wait pthread_cond_wait "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_cond_timedwait_relative_np pthread_cond_timedwait_relative_np "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_cond_signal pthread_cond_signal "/usr/lib/libSystem.B.dylib"
-
-// Magic incantation to get libSystem actually dynamically linked.
-// TODO: Why does the code require this? See cmd/link/internal/ld/go.go
-//go:cgo_import_dynamic _ _ "/usr/lib/libSystem.B.dylib"
diff --git a/libgo/go/runtime/sys_darwin_32.go b/libgo/go/runtime/sys_darwin_32.go
deleted file mode 100644
index 2f17091327d..00000000000
--- a/libgo/go/runtime/sys_darwin_32.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin
-// +build 386 arm
-
-package runtime
-
-import "unsafe"
-
-//go:linkname syscall_syscall9 syscall.syscall9
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
- entersyscallblock()
- libcCall(unsafe.Pointer(funcPC(syscall9)), unsafe.Pointer(&fn))
- exitsyscall()
- return
-}
-func syscall9()
-
-//go:linkname syscall_syscallPtr syscall.syscallPtr
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- entersyscallblock()
- libcCall(unsafe.Pointer(funcPC(syscallPtr)), unsafe.Pointer(&fn))
- exitsyscall()
- return
-}
-func syscallPtr()
diff --git a/libgo/go/runtime/sys_darwin_64.go b/libgo/go/runtime/sys_darwin_64.go
deleted file mode 100644
index 8c128811b9f..00000000000
--- a/libgo/go/runtime/sys_darwin_64.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin
-// +build amd64 arm64
-
-package runtime
-
-import "unsafe"
-
-//go:linkname syscall_syscallX syscall.syscallX
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- entersyscallblock()
- libcCall(unsafe.Pointer(funcPC(syscallX)), unsafe.Pointer(&fn))
- exitsyscall()
- return
-}
-func syscallX()
-
-//go:linkname syscall_syscallXPtr syscall.syscallXPtr
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_syscallXPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- entersyscallblock()
- libcCall(unsafe.Pointer(funcPC(syscallXPtr)), unsafe.Pointer(&fn))
- exitsyscall()
- return
-}
-func syscallXPtr()
diff --git a/libgo/mkrsysinfo.sh b/libgo/mkrsysinfo.sh
index 40bc34bbe4e..f1aa7241cd6 100755
--- a/libgo/mkrsysinfo.sh
+++ b/libgo/mkrsysinfo.sh
@@ -31,6 +31,19 @@ grep -v '^// ' gen-sysinfo.go | \
-e 's/\([^a-zA-Z0-9_]\)_timespec\([^a-zA-Z0-9_]\)/\1timespec\2/g' \
>> ${OUT}
+# The C long type, needed because that is the type that ptrace returns.
+sizeof_long=`grep '^const ___SIZEOF_LONG__ = ' gen-sysinfo.go | sed -e 's/.*= //'`
+if test "$sizeof_long" = "4"; then
+ echo "type _C_long int32" >> ${OUT}
+ echo "type _C_ulong uint32" >> ${OUT}
+elif test "$sizeof_long" = "8"; then
+ echo "type _C_long int64" >> ${OUT}
+ echo "type _C_ulong uint64" >> ${OUT}
+else
+ echo 1>&2 "mkrsysinfo.sh: could not determine size of long (got $sizeof_long)"
+ exit 1
+fi
+
# On AIX, the _arpcom struct, is filtered by the above grep sequence, as it as
# a field of type _in6_addr, but other types depend on _arpcom, so we need to
# put it back.
diff --git a/libgo/runtime/getncpu-aix.c b/libgo/runtime/getncpu-aix.c
deleted file mode 100644
index 064eed8570c..00000000000
--- a/libgo/runtime/getncpu-aix.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <sys/types.h>
-#include <sys/systemcfg.h>
-
-#include "runtime.h"
-#include "defs.h"
-
-int32_t
-getproccount(void)
-{
- return _system_configuration.ncpus;
-}
diff --git a/libgo/runtime/getncpu-bsd.c b/libgo/runtime/getncpu-bsd.c
deleted file mode 100644
index 00a81d1ddae..00000000000
--- a/libgo/runtime/getncpu-bsd.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <sys/types.h>
-#include <sys/sysctl.h>
-
-#include "runtime.h"
-#include "defs.h"
-
-int32
-getproccount(void)
-{
- int mib[2], out;
- size_t len;
-
- mib[0] = CTL_HW;
- mib[1] = HW_NCPU;
- len = sizeof(out);
- if(sysctl(mib, 2, &out, &len, NULL, 0) >= 0)
- return (int32)out;
- else
- return 0;
-}
diff --git a/libgo/runtime/getncpu-hurd.c b/libgo/runtime/getncpu-hurd.c
deleted file mode 100644
index 5d5d7025dfe..00000000000
--- a/libgo/runtime/getncpu-hurd.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <unistd.h>
-
-#include "runtime.h"
-#include "defs.h"
-
-int32
-getproccount(void)
-{
- int32 n;
- n = (int32)sysconf(_SC_NPROCESSORS_ONLN);
- return n > 1 ? n : 1;
-}
diff --git a/libgo/runtime/getncpu-irix.c b/libgo/runtime/getncpu-irix.c
deleted file mode 100644
index a65ca63d2ae..00000000000
--- a/libgo/runtime/getncpu-irix.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <unistd.h>
-
-#include "runtime.h"
-#include "defs.h"
-
-int32
-getproccount(void)
-{
- int32 n;
- n = (int32)sysconf(_SC_NPROC_ONLN);
- return n > 1 ? n : 1;
-}
diff --git a/libgo/runtime/getncpu-linux.c b/libgo/runtime/getncpu-linux.c
deleted file mode 100644
index de6606ff47c..00000000000
--- a/libgo/runtime/getncpu-linux.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <features.h>
-#include <sched.h>
-
-// CPU_COUNT is only provided by glibc 2.6 or higher
-#ifndef CPU_COUNT
-#define CPU_COUNT(set) _CPU_COUNT((unsigned int *)(set), sizeof(*(set))/sizeof(unsigned int))
-static int _CPU_COUNT(unsigned int *set, size_t len) {
- int cnt;
-
- cnt = 0;
- while (len--)
- cnt += __builtin_popcount(*set++);
- return cnt;
-}
-#endif
-
-#include "runtime.h"
-#include "defs.h"
-
-int32
-getproccount(void)
-{
- cpu_set_t set;
- int32 r, cnt;
-
- cnt = 0;
- r = sched_getaffinity(0, sizeof(set), &set);
- if(r == 0)
- cnt += CPU_COUNT(&set);
-
- return cnt ? cnt : 1;
-}
diff --git a/libgo/runtime/getncpu-none.c b/libgo/runtime/getncpu-none.c
deleted file mode 100644
index ba6fd4e689d..00000000000
--- a/libgo/runtime/getncpu-none.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs.h"
-
-int32
-getproccount(void)
-{
- return 0;
-}
diff --git a/libgo/runtime/getncpu-solaris.c b/libgo/runtime/getncpu-solaris.c
deleted file mode 100644
index 5d5d7025dfe..00000000000
--- a/libgo/runtime/getncpu-solaris.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <unistd.h>
-
-#include "runtime.h"
-#include "defs.h"
-
-int32
-getproccount(void)
-{
- int32 n;
- n = (int32)sysconf(_SC_NPROCESSORS_ONLN);
- return n > 1 ? n : 1;
-}
diff --git a/libgo/runtime/go-libmain.c b/libgo/runtime/go-libmain.c
index f3795690e04..10b202bf8f8 100644
--- a/libgo/runtime/go-libmain.c
+++ b/libgo/runtime/go-libmain.c
@@ -228,8 +228,7 @@ gostart (void *arg)
runtime_ginit ();
runtime_check ();
runtime_args (a->argc, (byte **) a->argv);
- setncpu (getproccount ());
- setpagesize (getpagesize ());
+ runtime_osinit ();
runtime_schedinit ();
__go_go ((uintptr)(runtime_main), NULL);
runtime_mstart (runtime_m ());
diff --git a/libgo/runtime/go-main.c b/libgo/runtime/go-main.c
index 51ce15fdbc1..dcf763af8c8 100644
--- a/libgo/runtime/go-main.c
+++ b/libgo/runtime/go-main.c
@@ -52,8 +52,7 @@ main (int argc, char **argv)
runtime_cpuinit ();
runtime_check ();
runtime_args (argc, (byte **) argv);
- setncpu (getproccount ());
- setpagesize (getpagesize ());
+ runtime_osinit ();
runtime_schedinit ();
__go_go ((uintptr)(runtime_main), NULL);
runtime_mstart (runtime_m ());
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
index 6da7bdf497f..4102f5da0a0 100644
--- a/libgo/runtime/runtime.h
+++ b/libgo/runtime/runtime.h
@@ -211,6 +211,8 @@ void runtime_gogo(G*)
struct __go_func_type;
void runtime_args(int32, byte**)
__asm__ (GOSYM_PREFIX "runtime.args");
+void runtime_osinit(void)
+ __asm__ (GOSYM_PREFIX "runtime.osinit");
void runtime_alginit(void)
__asm__ (GOSYM_PREFIX "runtime.alginit");
void runtime_goargs(void)
@@ -429,8 +431,6 @@ extern void __go_syminfo_fnname_callback(void*, uintptr_t, const char*,
extern void runtime_main(void*)
__asm__(GOSYM_PREFIX "runtime.main");
-int32 getproccount(void);
-
#define PREFETCH(p) __builtin_prefetch(p)
void runtime_badsignal(int);
@@ -456,12 +456,8 @@ extern void setSupportAES(bool)
__asm__ (GOSYM_PREFIX "runtime.setSupportAES");
extern void typedmemmove(const Type *, void *, const void *)
__asm__ (GOSYM_PREFIX "runtime.typedmemmove");
-extern void setncpu(int32)
- __asm__(GOSYM_PREFIX "runtime.setncpu");
extern Sched* runtime_getsched(void)
__asm__ (GOSYM_PREFIX "runtime.getsched");
-extern void setpagesize(uintptr_t)
- __asm__(GOSYM_PREFIX "runtime.setpagesize");
struct funcfileline_return
{