github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/runtime.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 //go:generate go run wincallback.go 13 //go:generate go run mkduff.go 14 //go:generate go run mkfastlog2table.go 15 //go:generate go run mklockrank.go -o lockrank.go 16 17 var ticks ticksType 18 19 type ticksType struct { 20 lock mutex 21 val atomic.Int64 22 } 23 24 // Note: Called by runtime/pprof in addition to runtime code. 25 func tickspersecond() int64 { 26 r := ticks.val.Load() 27 if r != 0 { 28 return r 29 } 30 lock(&ticks.lock) 31 r = ticks.val.Load() 32 if r == 0 { 33 t0 := nanotime() 34 c0 := cputicks() 35 usleep(100 * 1000) 36 t1 := nanotime() 37 c1 := cputicks() 38 if t1 == t0 { 39 t1++ 40 } 41 r = (c1 - c0) * 1000 * 1000 * 1000 / (t1 - t0) 42 if r == 0 { 43 r++ 44 } 45 ticks.val.Store(r) 46 } 47 unlock(&ticks.lock) 48 return r 49 } 50 51 var envs []string 52 var argslice []string 53 54 //go:linkname syscall_runtime_envs syscall.runtime_envs 55 func syscall_runtime_envs() []string { return append([]string{}, envs...) } 56 57 //go:linkname syscall_Getpagesize syscall.Getpagesize 58 func syscall_Getpagesize() int { return int(physPageSize) } 59 60 //go:linkname os_runtime_args os.runtime_args 61 func os_runtime_args() []string { return append([]string{}, argslice...) } 62 63 //go:linkname syscall_Exit syscall.Exit 64 //go:nosplit 65 func syscall_Exit(code int) { 66 exit(int32(code)) 67 } 68 69 var godebugDefault string 70 var godebugUpdate atomic.Pointer[func(string, string)] 71 var godebugEnv atomic.Pointer[string] // set by parsedebugvars 72 var godebugNewIncNonDefault atomic.Pointer[func(string) func()] 73 74 //go:linkname godebug_setUpdate internal/godebug.setUpdate 75 func godebug_setUpdate(update func(string, string)) { 76 p := new(func(string, string)) 77 *p = update 78 godebugUpdate.Store(p) 79 godebugNotify(false) 80 } 81 82 //go:linkname godebug_setNewIncNonDefault internal/godebug.setNewIncNonDefault 83 func godebug_setNewIncNonDefault(newIncNonDefault func(string) func()) { 84 p := new(func(string) func()) 85 *p = newIncNonDefault 86 godebugNewIncNonDefault.Store(p) 87 } 88 89 // A godebugInc provides access to internal/godebug's IncNonDefault function 90 // for a given GODEBUG setting. 91 // Calls before internal/godebug registers itself are dropped on the floor. 92 type godebugInc struct { 93 name string 94 inc atomic.Pointer[func()] 95 } 96 97 func (g *godebugInc) IncNonDefault() { 98 inc := g.inc.Load() 99 if inc == nil { 100 newInc := godebugNewIncNonDefault.Load() 101 if newInc == nil { 102 return 103 } 104 // If other goroutines are racing here, no big deal. One will win, 105 // and all the inc functions will be using the same underlying 106 // *godebug.Setting. 107 inc = new(func()) 108 *inc = (*newInc)(g.name) 109 g.inc.Store(inc) 110 } 111 (*inc)() 112 } 113 114 func godebugNotify(envChanged bool) { 115 update := godebugUpdate.Load() 116 var env string 117 if p := godebugEnv.Load(); p != nil { 118 env = *p 119 } 120 if envChanged { 121 reparsedebugvars(env) 122 } 123 if update != nil { 124 (*update)(godebugDefault, env) 125 } 126 } 127 128 //go:linkname syscall_runtimeSetenv syscall.runtimeSetenv 129 func syscall_runtimeSetenv(key, value string) { 130 setenv_c(key, value) 131 if key == "GODEBUG" { 132 p := new(string) 133 *p = value 134 godebugEnv.Store(p) 135 godebugNotify(true) 136 } 137 } 138 139 //go:linkname syscall_runtimeUnsetenv syscall.runtimeUnsetenv 140 func syscall_runtimeUnsetenv(key string) { 141 unsetenv_c(key) 142 if key == "GODEBUG" { 143 godebugEnv.Store(nil) 144 godebugNotify(true) 145 } 146 } 147 148 // writeErrStr writes a string to descriptor 2. 149 // 150 //go:nosplit 151 func writeErrStr(s string) { 152 write(2, unsafe.Pointer(unsafe.StringData(s)), int32(len(s))) 153 } 154 155 // auxv is populated on relevant platforms but defined here for all platforms 156 // so x/sys/cpu can assume the getAuxv symbol exists without keeping its list 157 // of auxv-using GOOS build tags in sync. 158 // 159 // It contains an even number of elements, (tag, value) pairs. 160 var auxv []uintptr 161 162 func getAuxv() []uintptr { return auxv } // accessed from x/sys/cpu; see issue 57336