2016-03-01 22:57:46 +00:00
|
|
|
// Copyright 2014 The Go Authors. All rights reserved.
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 11:32:17 -04:00
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package runtime
|
|
|
|
|
|
2016-04-06 04:38:00 +00:00
|
|
|
import (
|
|
|
|
|
"runtime/internal/atomic"
|
2018-03-27 13:33:32 +00:00
|
|
|
"runtime/internal/sys"
|
2016-04-06 04:38:00 +00:00
|
|
|
"unsafe"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
_SS_DISABLE = 4
|
|
|
|
|
_SIG_BLOCK = 1
|
|
|
|
|
_SIG_UNBLOCK = 2
|
|
|
|
|
_SIG_SETMASK = 3
|
|
|
|
|
_NSIG = 33
|
|
|
|
|
_SI_USER = 0
|
|
|
|
|
|
|
|
|
|
// From NetBSD's <sys/ucontext.h>
|
|
|
|
|
_UC_SIGMASK = 0x01
|
|
|
|
|
_UC_CPU = 0x04
|
2016-06-28 17:06:59 -07:00
|
|
|
|
runtime: make it possible to exit Go-created threads
Currently, threads created by the runtime exist until the whole
program exits. For #14592 and #20395, we want to be able to exit and
clean up threads created by the runtime. This commit implements that
mechanism.
The main difficulty is how to clean up the g0 stack. In cgo mode and
on Solaris and Windows where the OS manages thread stacks, we simply
arrange to return from mstart and let the system clean up the thread.
If the runtime allocated the g0 stack, then we use a new exitThread
syscall wrapper that arranges to clear a flag in the M once the stack
can safely be reaped and call the thread termination syscall.
exitThread is based on the existing exit1 wrapper, which was always
meant to terminate the calling thread. However, exit1 has never been
used since it was introduced 9 years ago, so it was broken on several
platforms. exitThread also has the additional complication of having
to flag that the stack is unused, which requires some tricks on
platforms that use the stack for syscalls.
This still leaves the problem of how to reap the unused g0 stacks. For
this, we move the M from allm to a new freem list as part of the M
exiting. Later, allocm scans the freem list, finds Ms that are marked
as done with their stack, removes these from the list and frees their
g0 stacks. This also allows these Ms to be garbage collected.
This CL does not yet use any of this functionality. Follow-up CLs
will. Likewise, there are no new tests in this CL because we'll need
follow-up functionality to test it.
Change-Id: Ic851ee74227b6d39c6fc1219fc71b45d3004bc63
Reviewed-on: https://go-review.googlesource.com/46037
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2017-06-16 15:54:21 -04:00
|
|
|
// From <sys/lwp.h>
|
|
|
|
|
_LWP_DETACHED = 0x00000040
|
2016-04-06 04:38:00 +00:00
|
|
|
)
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 11:32:17 -04:00
|
|
|
|
2015-10-21 18:36:05 -07:00
|
|
|
type mOS struct {
|
|
|
|
|
waitsemacount uint32
|
|
|
|
|
}
|
2015-10-21 12:48:53 -07:00
|
|
|
|
2014-11-22 16:05:31 +11:00
|
|
|
//go:noescape
|
|
|
|
|
func setitimer(mode int32, new, old *itimerval)
|
|
|
|
|
|
|
|
|
|
//go:noescape
|
runtime: minor simplifications to signal code
Change setsig, setsigstack, getsig, raise, raiseproc to take uint32 for
signal number parameter, as that is the type mostly used for signal
numbers. Same for dieFromSignal, sigInstallGoHandler, raisebadsignal.
Remove setsig restart parameter, as it is always either true or
irrelevant.
Don't check the handler in setsigstack, as the only caller does that
anyhow.
Don't bother to convert the handler from sigtramp to sighandler in
getsig, as it will never be called when the handler is sigtramp or
sighandler.
Don't check the return value from rt_sigaction in the GNU/Linux version
of setsigstack; no other setsigstack checks it, and it never fails.
Change-Id: I6bbd677e048a77eddf974dd3d017bc3c560fbd48
Reviewed-on: https://go-review.googlesource.com/29953
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-27 22:24:51 -07:00
|
|
|
func sigaction(sig uint32, new, old *sigactiont)
|
2014-11-22 16:05:31 +11:00
|
|
|
|
|
|
|
|
//go:noescape
|
2016-09-25 13:38:54 -07:00
|
|
|
func sigaltstack(new, old *stackt)
|
2014-11-22 16:05:31 +11:00
|
|
|
|
|
|
|
|
//go:noescape
|
2016-09-23 17:54:51 -07:00
|
|
|
func sigprocmask(how int32, new, old *sigset)
|
2014-11-22 16:05:31 +11:00
|
|
|
|
|
|
|
|
//go:noescape
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 11:32:17 -04:00
|
|
|
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
|
2014-11-22 16:05:31 +11:00
|
|
|
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 11:32:17 -04:00
|
|
|
func lwp_tramp()
|
2014-11-22 16:05:31 +11:00
|
|
|
|
runtime: minor simplifications to signal code
Change setsig, setsigstack, getsig, raise, raiseproc to take uint32 for
signal number parameter, as that is the type mostly used for signal
numbers. Same for dieFromSignal, sigInstallGoHandler, raisebadsignal.
Remove setsig restart parameter, as it is always either true or
irrelevant.
Don't check the handler in setsigstack, as the only caller does that
anyhow.
Don't bother to convert the handler from sigtramp to sighandler in
getsig, as it will never be called when the handler is sigtramp or
sighandler.
Don't check the return value from rt_sigaction in the GNU/Linux version
of setsigstack; no other setsigstack checks it, and it never fails.
Change-Id: I6bbd677e048a77eddf974dd3d017bc3c560fbd48
Reviewed-on: https://go-review.googlesource.com/29953
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-27 22:24:51 -07:00
|
|
|
func raiseproc(sig uint32)
|
2014-11-22 16:05:31 +11:00
|
|
|
|
2019-10-14 17:05:56 -04:00
|
|
|
func lwp_kill(tid int32, sig int)
|
|
|
|
|
|
2014-11-22 16:05:31 +11:00
|
|
|
//go:noescape
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 11:32:17 -04:00
|
|
|
func getcontext(ctxt unsafe.Pointer)
|
2014-11-22 16:05:31 +11:00
|
|
|
|
|
|
|
|
//go:noescape
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 11:32:17 -04:00
|
|
|
func lwp_create(ctxt unsafe.Pointer, flags uintptr, lwpid unsafe.Pointer) int32
|
2014-11-22 16:05:31 +11:00
|
|
|
|
|
|
|
|
//go:noescape
|
2017-12-04 01:48:45 +00:00
|
|
|
func lwp_park(clockid, flags int32, ts *timespec, unpark int32, hint, unparkhint unsafe.Pointer) int32
|
2014-11-22 16:05:31 +11:00
|
|
|
|
|
|
|
|
//go:noescape
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 11:32:17 -04:00
|
|
|
func lwp_unpark(lwp int32, hint unsafe.Pointer) int32
|
2014-11-22 16:05:31 +11:00
|
|
|
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 11:32:17 -04:00
|
|
|
func lwp_self() int32
|
2014-11-22 16:05:31 +11:00
|
|
|
|
|
|
|
|
func osyield()
|
2016-04-06 04:38:00 +00:00
|
|
|
|
runtime: clean up system calls during cgo callback init
During a cgocallback, the runtime calls needm to get an m.
The calls made during needm cannot themselves assume that
there is an m or a g (which is attached to the m).
In the old days of making direct system calls, the only thing
you had to do for such functions was mark them //go:nosplit,
to avoid the use of g in the stack split prologue.
But now, on operating systems that make system calls through
shared libraries and use code that saves state in the g or m
before doing so, it's not safe to assume g exists. In fact, it is
not even safe to call getg(), because it might fault deferencing
the TLS storage to find the g pointer (that storage may not be
initialized yet, at least on Windows, and perhaps on other systems
in the future).
The specific routines that are problematic are usleep and osyield,
which are called during lock contention in lockextra, called
from needm.
All this is rather subtle and hidden, so in addition to fixing the
problem on Windows, this CL makes the fact of not running on
a g much clearer by introducing variants usleep_no_g and
osyield_no_g whose names should make clear that there is no g.
And then we can remove the various sketchy getg() == nil checks
in the existing routines.
As part of this cleanup, this CL also deletes onosstack on Windows.
onosstack is from back when the runtime was implemented in C.
It predates systemstack but does essentially the same thing.
Instead of having two different copies of this code, we can use
systemstack consistently. This way we need not port onosstack
to each architecture.
This CL is part of a stack adding windows/arm64
support (#36439), intended to land in the Go 1.17 cycle.
This CL is, however, not windows/arm64-specific.
It is cleanup meant to make the port (and future ports) easier.
Change-Id: I3352de1fd0a3c26267c6e209063e6e86abd26187
Reviewed-on: https://go-review.googlesource.com/c/go/+/288793
Trust: Russ Cox <rsc@golang.org>
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-30 07:07:42 -05:00
|
|
|
//go:nosplit
|
|
|
|
|
func osyield_no_g() {
|
|
|
|
|
osyield()
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-13 08:20:23 -07:00
|
|
|
func kqueue() int32
|
|
|
|
|
|
|
|
|
|
//go:noescape
|
|
|
|
|
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
|
2019-11-07 21:04:53 -08:00
|
|
|
|
|
|
|
|
func pipe() (r, w int32, errno int32)
|
|
|
|
|
func pipe2(flags int32) (r, w int32, errno int32)
|
2018-06-13 08:20:23 -07:00
|
|
|
func closeonexec(fd int32)
|
2019-04-03 16:31:13 -07:00
|
|
|
func setNonblock(fd int32)
|
2018-06-13 08:20:23 -07:00
|
|
|
|
2016-04-06 04:38:00 +00:00
|
|
|
const (
|
|
|
|
|
_ESRCH = 3
|
|
|
|
|
_ETIMEDOUT = 60
|
|
|
|
|
|
|
|
|
|
// From NetBSD's <sys/time.h>
|
|
|
|
|
_CLOCK_REALTIME = 0
|
|
|
|
|
_CLOCK_VIRTUAL = 1
|
|
|
|
|
_CLOCK_PROF = 2
|
|
|
|
|
_CLOCK_MONOTONIC = 3
|
2017-12-04 01:48:45 +00:00
|
|
|
|
|
|
|
|
_TIMER_RELTIME = 0
|
|
|
|
|
_TIMER_ABSTIME = 1
|
2016-04-06 04:38:00 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var sigset_all = sigset{[4]uint32{^uint32(0), ^uint32(0), ^uint32(0), ^uint32(0)}}
|
|
|
|
|
|
|
|
|
|
// From NetBSD's <sys/sysctl.h>
|
|
|
|
|
const (
|
2020-05-04 18:36:31 +02:00
|
|
|
_CTL_HW = 6
|
|
|
|
|
_HW_NCPU = 3
|
|
|
|
|
_HW_PAGESIZE = 7
|
|
|
|
|
_HW_NCPUONLINE = 16
|
2016-04-06 04:38:00 +00:00
|
|
|
)
|
|
|
|
|
|
2020-05-04 18:36:31 +02:00
|
|
|
func sysctlInt(mib []uint32) (int32, bool) {
|
|
|
|
|
var out int32
|
2016-04-06 04:38:00 +00:00
|
|
|
nout := unsafe.Sizeof(out)
|
2020-05-04 18:36:31 +02:00
|
|
|
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 {
|
|
|
|
|
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)
|
2016-04-06 04:38:00 +00:00
|
|
|
}
|
|
|
|
|
return 1
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-18 21:40:02 -04:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-06 04:38:00 +00:00
|
|
|
//go:nosplit
|
|
|
|
|
func semacreate(mp *m) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//go:nosplit
|
|
|
|
|
func semasleep(ns int64) int32 {
|
|
|
|
|
_g_ := getg()
|
2018-09-05 14:36:20 -07:00
|
|
|
var deadline int64
|
2016-04-06 04:38:00 +00:00
|
|
|
if ns >= 0 {
|
2018-09-05 14:36:20 -07:00
|
|
|
deadline = nanotime() + ns
|
2016-04-06 04:38:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
v := atomic.Load(&_g_.m.waitsemacount)
|
|
|
|
|
if v > 0 {
|
|
|
|
|
if atomic.Cas(&_g_.m.waitsemacount, v, v-1) {
|
|
|
|
|
return 0 // semaphore acquired
|
|
|
|
|
}
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sleep until unparked by semawakeup or timeout.
|
2018-09-05 14:36:20 -07:00
|
|
|
var tsp *timespec
|
|
|
|
|
var ts timespec
|
|
|
|
|
if ns >= 0 {
|
|
|
|
|
wait := deadline - nanotime()
|
|
|
|
|
if wait <= 0 {
|
|
|
|
|
return -1
|
|
|
|
|
}
|
2019-03-13 18:56:37 -07:00
|
|
|
ts.setNsec(wait)
|
2018-09-05 14:36:20 -07:00
|
|
|
tsp = &ts
|
|
|
|
|
}
|
2017-12-04 01:48:45 +00:00
|
|
|
ret := lwp_park(_CLOCK_MONOTONIC, _TIMER_RELTIME, tsp, 0, unsafe.Pointer(&_g_.m.waitsemacount), nil)
|
2016-04-06 04:38:00 +00:00
|
|
|
if ret == _ETIMEDOUT {
|
|
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//go:nosplit
|
|
|
|
|
func semawakeup(mp *m) {
|
|
|
|
|
atomic.Xadd(&mp.waitsemacount, 1)
|
|
|
|
|
// From NetBSD's _lwp_unpark(2) manual:
|
|
|
|
|
// "If the target LWP is not currently waiting, it will return
|
|
|
|
|
// immediately upon the next call to _lwp_park()."
|
|
|
|
|
ret := lwp_unpark(int32(mp.procid), unsafe.Pointer(&mp.waitsemacount))
|
|
|
|
|
if ret != 0 && ret != _ESRCH {
|
|
|
|
|
// semawakeup can be called on signal stack.
|
|
|
|
|
systemstack(func() {
|
|
|
|
|
print("thrwakeup addr=", &mp.waitsemacount, " sem=", mp.waitsemacount, " ret=", ret, "\n")
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// May run with m.p==nil, so write barriers are not allowed.
|
|
|
|
|
//go:nowritebarrier
|
2018-04-23 07:30:32 -07:00
|
|
|
func newosproc(mp *m) {
|
|
|
|
|
stk := unsafe.Pointer(mp.g0.stack.hi)
|
2016-04-06 04:38:00 +00:00
|
|
|
if false {
|
|
|
|
|
print("newosproc stk=", stk, " m=", mp, " g=", mp.g0, " id=", mp.id, " ostk=", &mp, "\n")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var uc ucontextt
|
|
|
|
|
getcontext(unsafe.Pointer(&uc))
|
|
|
|
|
|
2017-04-21 08:48:57 +00:00
|
|
|
// _UC_SIGMASK does not seem to work here.
|
|
|
|
|
// It would be nice if _UC_SIGMASK and _UC_STACK
|
|
|
|
|
// worked so that we could do all the work setting
|
|
|
|
|
// the sigmask and the stack here, instead of setting
|
|
|
|
|
// the mask here and the stack in netbsdMstart.
|
|
|
|
|
// For now do the blocking manually.
|
2016-04-06 04:38:00 +00:00
|
|
|
uc.uc_flags = _UC_SIGMASK | _UC_CPU
|
|
|
|
|
uc.uc_link = nil
|
|
|
|
|
uc.uc_sigmask = sigset_all
|
|
|
|
|
|
2017-04-21 08:48:57 +00:00
|
|
|
var oset sigset
|
|
|
|
|
sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
|
|
|
|
|
|
2016-04-06 04:38:00 +00:00
|
|
|
lwp_mcontext_init(&uc.uc_mcontext, stk, mp, mp.g0, funcPC(netbsdMstart))
|
|
|
|
|
|
runtime: make it possible to exit Go-created threads
Currently, threads created by the runtime exist until the whole
program exits. For #14592 and #20395, we want to be able to exit and
clean up threads created by the runtime. This commit implements that
mechanism.
The main difficulty is how to clean up the g0 stack. In cgo mode and
on Solaris and Windows where the OS manages thread stacks, we simply
arrange to return from mstart and let the system clean up the thread.
If the runtime allocated the g0 stack, then we use a new exitThread
syscall wrapper that arranges to clear a flag in the M once the stack
can safely be reaped and call the thread termination syscall.
exitThread is based on the existing exit1 wrapper, which was always
meant to terminate the calling thread. However, exit1 has never been
used since it was introduced 9 years ago, so it was broken on several
platforms. exitThread also has the additional complication of having
to flag that the stack is unused, which requires some tricks on
platforms that use the stack for syscalls.
This still leaves the problem of how to reap the unused g0 stacks. For
this, we move the M from allm to a new freem list as part of the M
exiting. Later, allocm scans the freem list, finds Ms that are marked
as done with their stack, removes these from the list and frees their
g0 stacks. This also allows these Ms to be garbage collected.
This CL does not yet use any of this functionality. Follow-up CLs
will. Likewise, there are no new tests in this CL because we'll need
follow-up functionality to test it.
Change-Id: Ic851ee74227b6d39c6fc1219fc71b45d3004bc63
Reviewed-on: https://go-review.googlesource.com/46037
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2017-06-16 15:54:21 -04:00
|
|
|
ret := lwp_create(unsafe.Pointer(&uc), _LWP_DETACHED, unsafe.Pointer(&mp.procid))
|
2017-04-21 08:48:57 +00:00
|
|
|
sigprocmask(_SIG_SETMASK, &oset, nil)
|
2016-04-06 04:38:00 +00:00
|
|
|
if ret < 0 {
|
|
|
|
|
print("runtime: failed to create new OS thread (have ", mcount()-1, " already; errno=", -ret, ")\n")
|
2016-06-28 17:06:59 -07:00
|
|
|
if ret == -_EAGAIN {
|
|
|
|
|
println("runtime: may need to increase max user processes (ulimit -p)")
|
|
|
|
|
}
|
2016-04-06 04:38:00 +00:00
|
|
|
throw("runtime.newosproc")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-29 17:38:20 -04:00
|
|
|
// mstart is the entry-point for new Ms.
|
|
|
|
|
// It is written in assembly, uses ABI0, is marked TOPFRAME, and calls netbsdMstart0.
|
|
|
|
|
func netbsdMstart()
|
|
|
|
|
|
|
|
|
|
// netbsdMStart0 is the function call that starts executing a newly
|
2016-04-06 04:38:00 +00:00
|
|
|
// created thread. On NetBSD, a new thread inherits the signal stack
|
|
|
|
|
// of the creating thread. That confuses minit, so we remove that
|
|
|
|
|
// signal stack here before calling the regular mstart. It's a bit
|
|
|
|
|
// baroque to remove a signal stack here only to add one in minit, but
|
|
|
|
|
// it's a simple change that keeps NetBSD working like other OS's.
|
|
|
|
|
// At this point all signals are blocked, so there is no race.
|
|
|
|
|
//go:nosplit
|
2021-03-29 17:38:20 -04:00
|
|
|
func netbsdMstart0() {
|
2016-09-27 07:20:10 -07:00
|
|
|
st := stackt{ss_flags: _SS_DISABLE}
|
|
|
|
|
sigaltstack(&st, nil)
|
2021-03-29 17:38:20 -04:00
|
|
|
mstart0()
|
2016-04-06 04:38:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func osinit() {
|
|
|
|
|
ncpu = getncpu()
|
2018-03-27 13:33:32 +00:00
|
|
|
if physPageSize == 0 {
|
|
|
|
|
physPageSize = getPageSize()
|
|
|
|
|
}
|
2016-04-06 04:38:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var urandom_dev = []byte("/dev/urandom\x00")
|
|
|
|
|
|
|
|
|
|
//go:nosplit
|
|
|
|
|
func getRandomData(r []byte) {
|
|
|
|
|
fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
|
|
|
|
|
n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
|
|
|
|
|
closefd(fd)
|
|
|
|
|
extendRandom(r, int(n))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func goenvs() {
|
|
|
|
|
goenvs_unix()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Called to initialize a new m (including the bootstrap m).
|
|
|
|
|
// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
|
|
|
|
|
func mpreinit(mp *m) {
|
|
|
|
|
mp.gsignal = malg(32 * 1024)
|
|
|
|
|
mp.gsignal.m = mp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Called to initialize a new m (including the bootstrap m).
|
|
|
|
|
// Called on the new thread, cannot allocate memory.
|
|
|
|
|
func minit() {
|
|
|
|
|
_g_ := getg()
|
|
|
|
|
_g_.m.procid = uint64(lwp_self())
|
|
|
|
|
|
|
|
|
|
// On NetBSD a thread created by pthread_create inherits the
|
|
|
|
|
// signal stack of the creating thread. We always create a
|
|
|
|
|
// new signal stack here, to avoid having two Go threads using
|
|
|
|
|
// the same signal stack. This breaks the case of a thread
|
|
|
|
|
// created in C that calls sigaltstack and then calls a Go
|
|
|
|
|
// function, because we will lose track of the C code's
|
|
|
|
|
// sigaltstack, but it's the best we can do.
|
|
|
|
|
signalstack(&_g_.m.gsignal.stack)
|
|
|
|
|
_g_.m.newSigstack = true
|
|
|
|
|
|
2016-09-26 11:14:41 -07:00
|
|
|
minitSignalMask()
|
2016-04-06 04:38:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Called from dropm to undo the effect of an minit.
|
|
|
|
|
//go:nosplit
|
|
|
|
|
func unminit() {
|
2016-09-26 11:35:55 -07:00
|
|
|
unminitSignals()
|
2016-04-06 04:38:00 +00:00
|
|
|
}
|
|
|
|
|
|
2021-01-15 13:01:37 +01:00
|
|
|
// Called from exitm, but not from drop, to undo the effect of thread-owned
|
|
|
|
|
// resources in minit, semacreate, or elsewhere. Do not take locks after calling this.
|
|
|
|
|
func mdestroy(mp *m) {
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-06 04:38:00 +00:00
|
|
|
func sigtramp()
|
|
|
|
|
|
|
|
|
|
type sigactiont struct {
|
|
|
|
|
sa_sigaction uintptr
|
|
|
|
|
sa_mask sigset
|
|
|
|
|
sa_flags int32
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//go:nosplit
|
|
|
|
|
//go:nowritebarrierrec
|
runtime: minor simplifications to signal code
Change setsig, setsigstack, getsig, raise, raiseproc to take uint32 for
signal number parameter, as that is the type mostly used for signal
numbers. Same for dieFromSignal, sigInstallGoHandler, raisebadsignal.
Remove setsig restart parameter, as it is always either true or
irrelevant.
Don't check the handler in setsigstack, as the only caller does that
anyhow.
Don't bother to convert the handler from sigtramp to sighandler in
getsig, as it will never be called when the handler is sigtramp or
sighandler.
Don't check the return value from rt_sigaction in the GNU/Linux version
of setsigstack; no other setsigstack checks it, and it never fails.
Change-Id: I6bbd677e048a77eddf974dd3d017bc3c560fbd48
Reviewed-on: https://go-review.googlesource.com/29953
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-27 22:24:51 -07:00
|
|
|
func setsig(i uint32, fn uintptr) {
|
2016-04-06 04:38:00 +00:00
|
|
|
var sa sigactiont
|
runtime: minor simplifications to signal code
Change setsig, setsigstack, getsig, raise, raiseproc to take uint32 for
signal number parameter, as that is the type mostly used for signal
numbers. Same for dieFromSignal, sigInstallGoHandler, raisebadsignal.
Remove setsig restart parameter, as it is always either true or
irrelevant.
Don't check the handler in setsigstack, as the only caller does that
anyhow.
Don't bother to convert the handler from sigtramp to sighandler in
getsig, as it will never be called when the handler is sigtramp or
sighandler.
Don't check the return value from rt_sigaction in the GNU/Linux version
of setsigstack; no other setsigstack checks it, and it never fails.
Change-Id: I6bbd677e048a77eddf974dd3d017bc3c560fbd48
Reviewed-on: https://go-review.googlesource.com/29953
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-27 22:24:51 -07:00
|
|
|
sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
|
2016-04-06 04:38:00 +00:00
|
|
|
sa.sa_mask = sigset_all
|
|
|
|
|
if fn == funcPC(sighandler) {
|
|
|
|
|
fn = funcPC(sigtramp)
|
|
|
|
|
}
|
|
|
|
|
sa.sa_sigaction = fn
|
|
|
|
|
sigaction(i, &sa, nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//go:nosplit
|
|
|
|
|
//go:nowritebarrierrec
|
runtime: minor simplifications to signal code
Change setsig, setsigstack, getsig, raise, raiseproc to take uint32 for
signal number parameter, as that is the type mostly used for signal
numbers. Same for dieFromSignal, sigInstallGoHandler, raisebadsignal.
Remove setsig restart parameter, as it is always either true or
irrelevant.
Don't check the handler in setsigstack, as the only caller does that
anyhow.
Don't bother to convert the handler from sigtramp to sighandler in
getsig, as it will never be called when the handler is sigtramp or
sighandler.
Don't check the return value from rt_sigaction in the GNU/Linux version
of setsigstack; no other setsigstack checks it, and it never fails.
Change-Id: I6bbd677e048a77eddf974dd3d017bc3c560fbd48
Reviewed-on: https://go-review.googlesource.com/29953
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-27 22:24:51 -07:00
|
|
|
func setsigstack(i uint32) {
|
2016-04-06 04:38:00 +00:00
|
|
|
throw("setsigstack")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//go:nosplit
|
|
|
|
|
//go:nowritebarrierrec
|
runtime: minor simplifications to signal code
Change setsig, setsigstack, getsig, raise, raiseproc to take uint32 for
signal number parameter, as that is the type mostly used for signal
numbers. Same for dieFromSignal, sigInstallGoHandler, raisebadsignal.
Remove setsig restart parameter, as it is always either true or
irrelevant.
Don't check the handler in setsigstack, as the only caller does that
anyhow.
Don't bother to convert the handler from sigtramp to sighandler in
getsig, as it will never be called when the handler is sigtramp or
sighandler.
Don't check the return value from rt_sigaction in the GNU/Linux version
of setsigstack; no other setsigstack checks it, and it never fails.
Change-Id: I6bbd677e048a77eddf974dd3d017bc3c560fbd48
Reviewed-on: https://go-review.googlesource.com/29953
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-09-27 22:24:51 -07:00
|
|
|
func getsig(i uint32) uintptr {
|
2016-04-06 04:38:00 +00:00
|
|
|
var sa sigactiont
|
|
|
|
|
sigaction(i, nil, &sa)
|
|
|
|
|
return sa.sa_sigaction
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-25 13:38:54 -07:00
|
|
|
// setSignaltstackSP sets the ss_sp field of a stackt.
|
2016-04-06 04:38:00 +00:00
|
|
|
//go:nosplit
|
2016-09-25 13:38:54 -07:00
|
|
|
func setSignalstackSP(s *stackt, sp uintptr) {
|
|
|
|
|
s.ss_sp = sp
|
2016-04-06 04:38:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//go:nosplit
|
|
|
|
|
//go:nowritebarrierrec
|
2016-09-27 13:42:28 -07:00
|
|
|
func sigaddset(mask *sigset, i int) {
|
|
|
|
|
mask.__bits[(i-1)/32] |= 1 << ((uint32(i) - 1) & 31)
|
2016-04-06 04:38:00 +00:00
|
|
|
}
|
2016-09-25 21:33:27 -07:00
|
|
|
|
2016-09-26 11:14:41 -07:00
|
|
|
func sigdelset(mask *sigset, i int) {
|
|
|
|
|
mask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-25 10:34:57 +01:00
|
|
|
//go:nosplit
|
2016-09-25 21:33:27 -07:00
|
|
|
func (c *sigctxt) fixsigcode(sig uint32) {
|
|
|
|
|
}
|
2018-03-27 13:33:32 +00:00
|
|
|
|
|
|
|
|
func sysargs(argc int32, argv **byte) {
|
|
|
|
|
n := argc + 1
|
|
|
|
|
|
|
|
|
|
// skip over argv, envp to get to auxv
|
|
|
|
|
for argv_index(argv, n) != nil {
|
|
|
|
|
n++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// skip NULL separator
|
|
|
|
|
n++
|
|
|
|
|
|
|
|
|
|
// now argv+n is auxv
|
|
|
|
|
auxv := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize))
|
|
|
|
|
sysauxv(auxv[:])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
_AT_NULL = 0 // Terminates the vector
|
|
|
|
|
_AT_PAGESZ = 6 // Page size in bytes
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func sysauxv(auxv []uintptr) {
|
|
|
|
|
for i := 0; auxv[i] != _AT_NULL; i += 2 {
|
|
|
|
|
tag, val := auxv[i], auxv[i+1]
|
|
|
|
|
switch tag {
|
|
|
|
|
case _AT_PAGESZ:
|
|
|
|
|
physPageSize = val
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-10-14 17:05:56 -04:00
|
|
|
|
|
|
|
|
// raise sends signal to the calling thread.
|
|
|
|
|
//
|
|
|
|
|
// It must be nosplit because it is used by the signal handler before
|
|
|
|
|
// it definitely has a Go stack.
|
|
|
|
|
//
|
|
|
|
|
//go:nosplit
|
|
|
|
|
func raise(sig uint32) {
|
|
|
|
|
lwp_kill(lwp_self(), int(sig))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func signalM(mp *m, sig int) {
|
|
|
|
|
lwp_kill(int32(mp.procid), sig)
|
|
|
|
|
}
|