123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- // Copyright 2014 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"
- // Declarations for runtime services implemented in C or assembly.
- const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
- const regSize = 4 << (^uintreg(0) >> 63) // unsafe.Sizeof(uintreg(0)) but an ideal const
- // Should be a built-in for unsafe.Pointer?
- //go:nosplit
- func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
- return unsafe.Pointer(uintptr(p) + x)
- }
- // n must be a power of 2
- func roundup(p unsafe.Pointer, n uintptr) unsafe.Pointer {
- delta := -uintptr(p) & (n - 1)
- return unsafe.Pointer(uintptr(p) + delta)
- }
- // in runtime.c
- func getg() *g
- func acquirem() *m
- func releasem(mp *m)
- func gomcache() *mcache
- func readgstatus(*g) uint32 // proc.c
- // mcall switches from the g to the g0 stack and invokes fn(g),
- // where g is the goroutine that made the call.
- // mcall saves g's current PC/SP in g->sched so that it can be restored later.
- // It is up to fn to arrange for that later execution, typically by recording
- // g in a data structure, causing something to call ready(g) later.
- // mcall returns to the original goroutine g later, when g has been rescheduled.
- // fn must not return at all; typically it ends by calling schedule, to let the m
- // run other goroutines.
- //
- // mcall can only be called from g stacks (not g0, not gsignal).
- //go:noescape
- func mcall(fn func(*g))
- // onM switches from the g to the g0 stack and invokes fn().
- // When fn returns, onM switches back to the g and returns,
- // continuing execution on the g stack.
- // If arguments must be passed to fn, they can be written to
- // g->m->ptrarg (pointers) and g->m->scalararg (non-pointers)
- // before the call and then consulted during fn.
- // Similarly, fn can pass return values back in those locations.
- // If fn is written in Go, it can be a closure, which avoids the need for
- // ptrarg and scalararg entirely.
- // After reading values out of ptrarg and scalararg it is conventional
- // to zero them to avoid (memory or information) leaks.
- //
- // If onM is called from a g0 stack, it invokes fn and returns,
- // without any stack switches.
- //
- // If onM is called from a gsignal stack, it crashes the program.
- // The implication is that functions used in signal handlers must
- // not use onM.
- //
- // NOTE(rsc): We could introduce a separate onMsignal that is
- // like onM but if called from a gsignal stack would just run fn on
- // that stack. The caller of onMsignal would be required to save the
- // old values of ptrarg/scalararg and restore them when the call
- // was finished, in case the signal interrupted an onM sequence
- // in progress on the g or g0 stacks. Until there is a clear need for this,
- // we just reject onM in signal handling contexts entirely.
- //
- //go:noescape
- func onM(fn func())
- // onMsignal is like onM but is allowed to be used in code that
- // might run on the gsignal stack. Code running on a signal stack
- // may be interrupting an onM sequence on the main stack, so
- // if the onMsignal calling sequence writes to ptrarg/scalararg,
- // it must first save the old values and then restore them when
- // finished. As an exception to the rule, it is fine not to save and
- // restore the values if the program is trying to crash rather than
- // return from the signal handler.
- // Once all the runtime is written in Go, there will be no ptrarg/scalararg
- // and the distinction between onM and onMsignal (and perhaps mcall)
- // can go away.
- //
- // If onMsignal is called from a gsignal stack, it invokes fn directly,
- // without a stack switch. Otherwise onMsignal behaves like onM.
- //
- //go:noescape
- func onM_signalok(fn func())
- func badonm() {
- gothrow("onM called from signal goroutine")
- }
- // C functions that run on the M stack.
- // Call using mcall.
- func gosched_m(*g)
- func park_m(*g)
- func recovery_m(*g)
- // More C functions that run on the M stack.
- // Call using onM.
- func mcacheRefill_m()
- func largeAlloc_m()
- func gc_m()
- func scavenge_m()
- func setFinalizer_m()
- func removeFinalizer_m()
- func markallocated_m()
- func unrollgcprog_m()
- func unrollgcproginplace_m()
- func setgcpercent_m()
- func setmaxthreads_m()
- func ready_m()
- func deferproc_m()
- func goexit_m()
- func startpanic_m()
- func dopanic_m()
- func readmemstats_m()
- func writeheapdump_m()
- // memclr clears n bytes starting at ptr.
- // in memclr_*.s
- //go:noescape
- func memclr(ptr unsafe.Pointer, n uintptr)
- // memmove copies n bytes from "from" to "to".
- // in memmove_*.s
- //go:noescape
- func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
- func starttheworld()
- func stoptheworld()
- func newextram()
- func lockOSThread()
- func unlockOSThread()
- // exported value for testing
- var hashLoad = loadFactor
- // in asm_*.s
- func fastrand1() uint32
- // in asm_*.s
- //go:noescape
- func memeq(a, b unsafe.Pointer, size uintptr) bool
- // noescape hides a pointer from escape analysis. noescape is
- // the identity function but escape analysis doesn't think the
- // output depends on the input. noescape is inlined and currently
- // compiles down to a single xor instruction.
- // USE CAREFULLY!
- //go:nosplit
- func noescape(p unsafe.Pointer) unsafe.Pointer {
- x := uintptr(p)
- return unsafe.Pointer(x ^ 0)
- }
- func entersyscall()
- func reentersyscall(pc uintptr, sp unsafe.Pointer)
- func entersyscallblock()
- func exitsyscall()
- func cgocallback(fn, frame unsafe.Pointer, framesize uintptr)
- func gogo(buf *gobuf)
- func gosave(buf *gobuf)
- func read(fd int32, p unsafe.Pointer, n int32) int32
- func close(fd int32) int32
- func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
- //go:noescape
- func jmpdefer(fv *funcval, argp uintptr)
- func exit1(code int32)
- func asminit()
- func setg(gg *g)
- func exit(code int32)
- func breakpoint()
- func nanotime() int64
- func usleep(usec uint32)
- // careful: cputicks is not guaranteed to be monotonic! In particular, we have
- // noticed drift between cpus on certain os/arch combinations. See issue 8976.
- func cputicks() int64
- func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
- func munmap(addr unsafe.Pointer, n uintptr)
- func madvise(addr unsafe.Pointer, n uintptr, flags int32)
- func reflectcall(fn, arg unsafe.Pointer, n uint32, retoffset uint32)
- func osyield()
- func procyield(cycles uint32)
- func cgocallback_gofunc(fv *funcval, frame unsafe.Pointer, framesize uintptr)
- func readgogc() int32
- func purgecachedstats(c *mcache)
- func gostringnocopy(b *byte) string
- func goexit()
- //go:noescape
- func write(fd uintptr, p unsafe.Pointer, n int32) int32
- //go:noescape
- func cas(ptr *uint32, old, new uint32) bool
- //go:noescape
- func casp(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool
- //go:noescape
- func casuintptr(ptr *uintptr, old, new uintptr) bool
- //go:noescape
- func atomicstoreuintptr(ptr *uintptr, new uintptr)
- //go:noescape
- func atomicloaduintptr(ptr *uintptr) uintptr
- //go:noescape
- func atomicloaduint(ptr *uint) uint
- //go:noescape
- func setcallerpc(argp unsafe.Pointer, pc uintptr)
- // getcallerpc returns the program counter (PC) of its caller's caller.
- // getcallersp returns the stack pointer (SP) of its caller's caller.
- // For both, the argp must be a pointer to the caller's first function argument.
- // The implementation may or may not use argp, depending on
- // the architecture.
- //
- // For example:
- //
- // func f(arg1, arg2, arg3 int) {
- // pc := getcallerpc(unsafe.Pointer(&arg1))
- // sp := getcallerpc(unsafe.Pointer(&arg2))
- // }
- //
- // These two lines find the PC and SP immediately following
- // the call to f (where f will return).
- //
- // The call to getcallerpc and getcallersp must be done in the
- // frame being asked about. It would not be correct for f to pass &arg1
- // to another function g and let g call getcallerpc/getcallersp.
- // The call inside g might return information about g's caller or
- // information about f's caller or complete garbage.
- //
- // The result of getcallersp is correct at the time of the return,
- // but it may be invalidated by any subsequent call to a function
- // that might relocate the stack in order to grow or shrink it.
- // A general rule is that the result of getcallersp should be used
- // immediately and can only be passed to nosplit functions.
- //go:noescape
- func getcallerpc(argp unsafe.Pointer) uintptr
- //go:noescape
- func getcallersp(argp unsafe.Pointer) uintptr
- //go:noescape
- func asmcgocall(fn, arg unsafe.Pointer)
- //go:noescape
- func asmcgocall_errno(fn, arg unsafe.Pointer) int32
- //go:noescape
- func open(name *byte, mode, perm int32) int32
- //go:noescape
- func gotraceback(*bool) int32
- const _NoArgs = ^uintptr(0)
- func newstack()
- func newproc()
- func morestack()
- func mstart()
- func rt0_go()
- // return0 is a stub used to return 0 from deferproc.
- // It is called at the very end of deferproc to signal
- // the calling Go function that it should not jump
- // to deferreturn.
- // in asm_*.s
- func return0()
- // thunk to call time.now.
- func timenow() (sec int64, nsec int32)
- // in asm_*.s
- // not called directly; definitions here supply type information for traceback.
- func call16(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call32(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call64(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call128(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call256(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call512(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call1024(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call2048(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call4096(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call8192(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call16384(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call32768(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call65536(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call131072(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call262144(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call524288(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call1048576(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call2097152(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call4194304(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call8388608(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call16777216(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call33554432(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call67108864(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call134217728(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call268435456(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call536870912(fn, arg unsafe.Pointer, n, retoffset uint32)
- func call1073741824(fn, arg unsafe.Pointer, n, retoffset uint32)
|