aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/proc.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/proc.go')
-rw-r--r--src/runtime/proc.go40
1 files changed, 32 insertions, 8 deletions
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 887063638b..38299d82c0 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -517,7 +517,7 @@ func acquireSudog() *sudog {
s := pp.sudogcache[n-1]
pp.sudogcache[n-1] = nil
pp.sudogcache = pp.sudogcache[:n-1]
- if s.elem != nil {
+ if s.elem.get() != nil {
throw("acquireSudog: found s.elem != nil in cache")
}
releasem(mp)
@@ -526,7 +526,7 @@ func acquireSudog() *sudog {
//go:nosplit
func releaseSudog(s *sudog) {
- if s.elem != nil {
+ if s.elem.get() != nil {
throw("runtime: sudog with non-nil elem")
}
if s.isSelect {
@@ -541,7 +541,7 @@ func releaseSudog(s *sudog) {
if s.waitlink != nil {
throw("runtime: sudog with non-nil waitlink")
}
- if s.c != nil {
+ if s.c.get() != nil {
throw("runtime: sudog with non-nil c")
}
gp := getg()
@@ -790,7 +790,9 @@ func cpuinit(env string) {
// getGodebugEarly extracts the environment variable GODEBUG from the environment on
// Unix-like operating systems and returns it. This function exists to extract GODEBUG
// early before much of the runtime is initialized.
-func getGodebugEarly() string {
+//
+// Returns nil, false if OS doesn't provide env vars early in the init sequence.
+func getGodebugEarly() (string, bool) {
const prefix = "GODEBUG="
var env string
switch GOOS {
@@ -808,12 +810,16 @@ func getGodebugEarly() string {
s := unsafe.String(p, findnull(p))
if stringslite.HasPrefix(s, prefix) {
- env = gostring(p)[len(prefix):]
+ env = gostringnocopy(p)[len(prefix):]
break
}
}
+ break
+
+ default:
+ return "", false
}
- return env
+ return env, true
}
// The bootstrap sequence is:
@@ -860,12 +866,15 @@ func schedinit() {
// The world starts stopped.
worldStopped()
+ godebug, parsedGodebug := getGodebugEarly()
+ if parsedGodebug {
+ parseRuntimeDebugVars(godebug)
+ }
ticks.init() // run as early as possible
moduledataverify()
stackinit()
randinit() // must run before mallocinit, alginit, mcommoninit
mallocinit()
- godebug := getGodebugEarly()
cpuinit(godebug) // must run before alginit
alginit() // maps, hash, rand must not be used before this call
mcommoninit(gp.m, -1)
@@ -881,7 +890,12 @@ func schedinit() {
goenvs()
secure()
checkfds()
- parsedebugvars()
+ if !parsedGodebug {
+ // Some platforms, e.g., Windows, didn't make env vars available "early",
+ // so try again now.
+ parseRuntimeDebugVars(gogetenv("GODEBUG"))
+ }
+ finishDebugVarsSetup()
gcinit()
// Allocate stack space that can be used when crashing due to bad stack
@@ -1209,6 +1223,7 @@ func casfrom_Gscanstatus(gp *g, oldval, newval uint32) {
_Gscanwaiting,
_Gscanrunning,
_Gscansyscall,
+ _Gscanleaked,
_Gscanpreempted:
if newval == oldval&^_Gscan {
success = gp.atomicstatus.CompareAndSwap(oldval, newval)
@@ -1229,6 +1244,7 @@ func castogscanstatus(gp *g, oldval, newval uint32) bool {
case _Grunnable,
_Grunning,
_Gwaiting,
+ _Gleaked,
_Gsyscall:
if newval == oldval|_Gscan {
r := gp.atomicstatus.CompareAndSwap(oldval, newval)
@@ -5552,6 +5568,14 @@ func gcount(includeSys bool) int32 {
return n
}
+// goroutineleakcount returns the number of leaked goroutines last reported by
+// the runtime.
+//
+//go:linkname goroutineleakcount runtime/pprof.runtime_goroutineleakcount
+func goroutineleakcount() int {
+ return work.goroutineLeak.count
+}
+
func mcount() int32 {
return int32(sched.mnext - sched.nmfreed)
}