github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/debug.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package runtime 6 7 import ( 8 "runtime/internal/atomic" 9 "unsafe" 10 ) 11 12 // GOMAXPROCS sets the maximum number of CPUs that can be executing 13 // simultaneously and returns the previous setting. It defaults to 14 // the value of runtime.NumCPU. If n < 1, it does not change the current setting. 15 // This call will go away when the scheduler improves. 16 func GOMAXPROCS(n int) int { 17 if GOARCH == "wasm" && n > 1 { 18 n = 1 // WebAssembly has no threads yet, so only one CPU is possible. 19 } 20 21 lock(&sched.lock) 22 ret := int(gomaxprocs) 23 unlock(&sched.lock) 24 if n <= 0 || n == ret { 25 return ret 26 } 27 28 stopTheWorldGC("GOMAXPROCS") 29 30 // newprocs will be processed by startTheWorld 31 newprocs = int32(n) 32 33 startTheWorldGC() 34 return ret 35 } 36 37 // NumCPU returns the number of logical CPUs usable by the current process. 38 // 39 // The set of available CPUs is checked by querying the operating system 40 // at process startup. Changes to operating system CPU allocation after 41 // process startup are not reflected. 42 func NumCPU() int { 43 return int(ncpu) 44 } 45 46 // NumCgoCall returns the number of cgo calls made by the current process. 47 func NumCgoCall() int64 { 48 var n = int64(atomic.Load64(&ncgocall)) 49 for mp := (*m)(atomic.Loadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink { 50 n += int64(mp.ncgocall) 51 } 52 return n 53 } 54 55 // NumGoroutine returns the number of goroutines that currently exist. 56 func NumGoroutine() int { 57 return int(gcount()) 58 } 59 60 //go:linkname debug_modinfo runtime/debug.modinfo 61 func debug_modinfo() string { 62 return modinfo 63 } 64 65 // mayMoreStackPreempt is a maymorestack hook that forces a preemption 66 // at every possible cooperative preemption point. 67 // 68 // This is valuable to apply to the runtime, which can be sensitive to 69 // preemption points. To apply this to all preemption points in the 70 // runtime and runtime-like code, use the following in bash or zsh: 71 // 72 // X=(-{gc,asm}flags={runtime/...,reflect,sync}=-d=maymorestack=runtime.mayMoreStackPreempt) GOFLAGS=${X[@]} 73 // 74 // This must be deeply nosplit because it is called from a function 75 // prologue before the stack is set up and because the compiler will 76 // call it from any splittable prologue (leading to infinite 77 // recursion). 78 // 79 // Ideally it should also use very little stack because the linker 80 // doesn't currently account for this in nosplit stack depth checking. 81 // 82 // Ensure mayMoreStackPreempt can be called for all ABIs. 83 // 84 //go:nosplit 85 //go:linkname mayMoreStackPreempt 86 func mayMoreStackPreempt() { 87 // Don't do anything on the g0 or gsignal stack. 88 gp := getg() 89 if gp == gp.m.g0 || gp == gp.m.gsignal { 90 return 91 } 92 // Force a preemption, unless the stack is already poisoned. 93 if gp.stackguard0 < stackPoisonMin { 94 gp.stackguard0 = stackPreempt 95 } 96 } 97 98 // mayMoreStackMove is a maymorestack hook that forces stack movement 99 // at every possible point. 100 // 101 // See mayMoreStackPreempt. 102 // 103 //go:nosplit 104 //go:linkname mayMoreStackMove 105 func mayMoreStackMove() { 106 // Don't do anything on the g0 or gsignal stack. 107 gp := getg() 108 if gp == gp.m.g0 || gp == gp.m.gsignal { 109 return 110 } 111 // Force stack movement, unless the stack is already poisoned. 112 if gp.stackguard0 < stackPoisonMin { 113 gp.stackguard0 = stackForceMove 114 } 115 }