diff options
Diffstat (limited to 'src/pkg/runtime/runtime.h')
-rw-r--r-- | src/pkg/runtime/runtime.h | 257 |
1 files changed, 157 insertions, 100 deletions
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index cb72b92d6..f7c2adb12 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -53,7 +53,6 @@ typedef struct Gobuf Gobuf; typedef struct Lock Lock; typedef struct M M; typedef struct P P; -typedef struct Mem Mem; typedef struct Note Note; typedef struct Slice Slice; typedef struct Stktop Stktop; @@ -78,6 +77,7 @@ typedef struct Complex64 Complex64; typedef struct Complex128 Complex128; typedef struct WinCall WinCall; typedef struct SEH SEH; +typedef struct WinCallbackContext WinCallbackContext; typedef struct Timers Timers; typedef struct Timer Timer; typedef struct GCStats GCStats; @@ -86,6 +86,7 @@ typedef struct ParFor ParFor; typedef struct ParForThread ParForThread; typedef struct CgoMal CgoMal; typedef struct PollDesc PollDesc; +typedef struct DebugVars DebugVars; /* * Per-CPU declaration. @@ -147,12 +148,6 @@ enum // Global <-> per-M stack segment cache transfer batch size. StackCacheBatch = 16, }; -enum -{ - // This value is generated by the linker and should be kept in - // sync with cmd/ld/lib.h - ArgsSizeUnknown = 0x80000000, -}; /* * structures */ @@ -209,10 +204,13 @@ struct Slice }; struct Gobuf { - // The offsets of these fields are known to (hard-coded in) libmach. + // The offsets of sp, pc, and g are known to (hard-coded in) libmach. uintptr sp; - byte* pc; + uintptr pc; G* g; + uintptr ret; + void* ctxt; + uintptr lr; }; struct GCStats { @@ -224,50 +222,74 @@ struct GCStats uint64 nosyield; uint64 nsleep; }; + +struct WinCall +{ + void (*fn)(void*); + uintptr n; // number of parameters + void* args; // parameters + uintptr r1; // return values + uintptr r2; + uintptr err; // error number +}; +struct SEH +{ + void* prev; + void* handler; +}; +// describes how to handle callback +struct WinCallbackContext +{ + void* gobody; // Go function to call + uintptr argsize; // callback arguments size (in bytes) + uintptr restorestack; // adjust stack on return by (in bytes) (386 only) +}; + struct G { - uintptr stackguard; // cannot move - also known to linker, libmach, runtime/cgo + // stackguard0 can be set to StackPreempt as opposed to stackguard + uintptr stackguard0; // cannot move - also known to linker, libmach, runtime/cgo uintptr stackbase; // cannot move - also known to libmach, runtime/cgo + uint32 panicwrap; // cannot move - also known to linker + uint32 selgen; // valid sudog pointer Defer* defer; Panic* panic; Gobuf sched; - uintptr gcstack; // if status==Gsyscall, gcstack = stackbase to use during gc - uintptr gcsp; // if status==Gsyscall, gcsp = sched.sp to use during gc - byte* gcpc; // if status==Gsyscall, gcpc = sched.pc to use during gc - uintptr gcguard; // if status==Gsyscall, gcguard = stackguard to use during gc + uintptr syscallstack; // if status==Gsyscall, syscallstack = stackbase to use during gc + uintptr syscallsp; // if status==Gsyscall, syscallsp = sched.sp to use during gc + uintptr syscallpc; // if status==Gsyscall, syscallpc = sched.pc to use during gc + uintptr syscallguard; // if status==Gsyscall, syscallguard = stackguard to use during gc + uintptr stackguard; // same as stackguard0, but not set to StackPreempt uintptr stack0; - FuncVal* fnstart; // initial function + uintptr stacksize; G* alllink; // on allg void* param; // passed parameter on wakeup int16 status; int64 goid; - uint32 selgen; // valid sudog pointer int8* waitreason; // if status==Gwaiting G* schedlink; bool ispanic; bool issystem; // do not output in stack dump bool isbackground; // ignore in deadlock detector - bool blockingsyscall; // hint that the next syscall will block + bool preempt; // preemption signal, duplicates stackguard0 = StackPreempt int8 raceignore; // ignore race detection events M* m; // for debuggers, but offset not hard-coded M* lockedm; int32 sig; int32 writenbuf; byte* writebuf; - DeferChunk *dchunk; - DeferChunk *dchunknext; + DeferChunk* dchunk; + DeferChunk* dchunknext; uintptr sigcode0; uintptr sigcode1; uintptr sigpc; - uintptr gopc; // pc of go statement that created this goroutine + uintptr gopc; // pc of go statement that created this goroutine uintptr racectx; uintptr end[]; }; struct M { - // The offsets of these fields are known to (hard-coded in) libmach. G* g0; // goroutine with scheduling stack - void (*morepc)(void); void* moreargp; // argument pointer for more stack Gobuf morebuf; // gobuf arg to morestack @@ -280,6 +302,7 @@ struct M uintptr tls[4]; // thread-local storage (for x86 extern register) void (*mstartfn)(void); G* curg; // current running goroutine + G* caughtsig; // goroutine running during fatal signal P* p; // attached P for executing Go code (nil if not executing Go code) P* nextp; int32 id; @@ -287,11 +310,9 @@ struct M int32 throwing; int32 gcing; int32 locks; - int32 nomemprof; int32 dying; int32 profilehz; int32 helpgc; - bool blockingsyscall; bool spinning; uint32 fastrand; uint64 ncgocall; // number of cgo calls in total @@ -301,17 +322,17 @@ struct M M* alllink; // on allm M* schedlink; uint32 machport; // Return address for Mach IPC (OS X) - MCache *mcache; + MCache* mcache; int32 stackinuse; uint32 stackcachepos; uint32 stackcachecnt; void* stackcache[StackCacheSize]; G* lockedg; - uintptr createstack[32]; // Stack that created this thread. + uintptr createstack[32];// Stack that created this thread. uint32 freglo[16]; // D[i] lsb and F[i] uint32 freghi[16]; // D[i] msb and F[i+16] uint32 fflag; // floating point compare flags - uint32 locked; // tracking for LockOSThread + uint32 locked; // tracking for LockOSThread M* nextwaitm; // next M waiting for lock uintptr waitsema; // semaphore for parking on locks uint32 waitsemacount; @@ -319,19 +340,18 @@ struct M GCStats gcstats; bool racecall; bool needextram; - void* racepc; void (*waitunlockf)(Lock*); void* waitlock; - uint32 moreframesize_minalloc; uintptr settype_buf[1024]; uintptr settype_bufsize; #ifdef GOOS_windows void* thread; // thread handle + WinCall wincall; #endif #ifdef GOOS_plan9 - int8* notesig; + int8* notesig; byte* errstr; #endif SEH* seh; @@ -342,10 +362,12 @@ struct P { Lock; - uint32 status; // one of Pidle/Prunning/... + int32 id; + uint32 status; // one of Pidle/Prunning/... P* link; - uint32 tick; // incremented on every scheduler or system call - M* m; // back-link to associated M (nil if idle) + uint32 schedtick; // incremented on every scheduler call + uint32 syscalltick; // incremented on every system call + M* m; // back-link to associated M (nil if idle) MCache* mcache; // Queue of runnable goroutines. @@ -361,9 +383,13 @@ struct P byte pad[64]; }; -// The m->locked word holds a single bit saying whether -// external calls to LockOSThread are in effect, and then a counter -// of the internal nesting depth of lockOSThread / unlockOSThread. +// The m->locked word holds two pieces of state counting active calls to LockOSThread/lockOSThread. +// The low bit (LockExternal) is a boolean reporting whether any LockOSThread call is active. +// External locks are not recursive; a second lock is silently ignored. +// The upper bits of m->lockedcount record the nesting depth of calls to lockOSThread +// (counting up by LockInternal), popped by unlockOSThread (counting down by LockInternal). +// Internal locks can be recursive. For instance, a lock for cgo can occur while the main +// goroutine is holding the lock during the initialization phase. enum { LockExternal = 1, @@ -373,10 +399,11 @@ enum struct Stktop { // The offsets of these fields are known to (hard-coded in) libmach. - uint8* stackguard; - uint8* stackbase; + uintptr stackguard; + uintptr stackbase; Gobuf gobuf; uint32 argsize; + uint32 panicwrap; uint8* argp; // pointer to arguments in old frame uintptr free; // if free>0, call stackfree using free as size @@ -398,23 +425,27 @@ enum SigIgnored = 1<<6, // the signal was ignored before we registered for it }; -// NOTE(rsc): keep in sync with extern.go:/type.Func. -// Eventually, the loaded symbol table should be closer to this form. +// Layout of in-memory per-function information prepared by linker +// See http://golang.org/s/go12symtab. +// Keep in sync with linker and with ../../libmach/sym.c +// and with package debug/gosym. struct Func { - String name; - String type; // go type string - String src; // src file name - Slice pcln; // pc/ln tab for this func - uintptr entry; // entry pc - uintptr pc0; // starting pc, ln for table - int32 ln0; - int32 frame; // stack frame size + uintptr entry; // start pc + int32 nameoff;// function name + int32 args; // in/out args size - int32 locals; // locals size + int32 frame; // legacy frame size; use pcsp if possible + + int32 pcsp; + int32 pcfile; + int32 pcln; + int32 npcdata; + int32 nfuncdata; }; // layout of Itab known to compilers +// allocated in non-garbage-collected memory struct Itab { InterfaceType* inter; @@ -425,21 +456,6 @@ struct Itab void (*fun[])(void); }; -struct WinCall -{ - void (*fn)(void*); - uintptr n; // number of parameters - void* args; // parameters - uintptr r1; // return values - uintptr r2; - uintptr err; // error number -}; -struct SEH -{ - void* prev; - void* handler; -}; - #ifdef GOOS_windows enum { Windows = 1 @@ -466,7 +482,7 @@ struct Timers // If this struct changes, adjust ../time/sleep.go:/runtimeTimer. struct Timer { - int32 i; // heap index + int32 i; // heap index // Timer wakes up at when, and then at when+period, ... (period > 0 only) // each time calling f(now, arg) in the timer goroutine, so f must be @@ -514,6 +530,16 @@ struct CgoMal void *alloc; }; +// Holds variables parsed from GODEBUG env var. +struct DebugVars +{ + int32 gctrace; + int32 schedtrace; + int32 scheddetail; +}; + +extern bool runtime·precisestack; + /* * defined macros * you need super-gopher-guru privilege @@ -621,9 +647,9 @@ void runtime·nilintercopy(uintptr, void*, void*); struct Defer { int32 siz; - bool special; // not part of defer frame - bool free; // if special, free when done - byte* argp; // where args were copied from + bool special; // not part of defer frame + bool free; // if special, free when done + byte* argp; // where args were copied from byte* pc; FuncVal* fn; Defer* link; @@ -642,12 +668,34 @@ struct DeferChunk struct Panic { Eface arg; // argument to panic - byte* stackbase; // g->stackbase in panic + uintptr stackbase; // g->stackbase in panic Panic* link; // link to earlier panic bool recovered; // whether this panic is over }; /* + * stack traces + */ +typedef struct Stkframe Stkframe; +struct Stkframe +{ + Func* fn; // function being run + uintptr pc; // program counter within fn + uintptr lr; // program counter at caller aka link register + uintptr sp; // stack pointer at pc + uintptr fp; // stack pointer at caller aka frame pointer + byte* varp; // top of local variables + byte* argp; // pointer to function arguments + uintptr arglen; // number of bytes at argp +}; + +int32 runtime·gentraceback(uintptr, uintptr, uintptr, G*, int32, uintptr*, int32, void(*)(Stkframe*, void*), void*, bool); +void runtime·traceback(uintptr pc, uintptr sp, uintptr lr, G* gp); +void runtime·tracebackothers(G*); +bool runtime·haszeroargs(uintptr pc); +bool runtime·topofstack(Func*); + +/* * external data */ extern String runtime·emptystring; @@ -657,25 +705,26 @@ extern G* runtime·lastg; extern M* runtime·allm; extern P** runtime·allp; extern int32 runtime·gomaxprocs; -extern bool runtime·singleproc; +extern uint32 runtime·needextram; extern uint32 runtime·panicking; -extern uint32 runtime·gcwaiting; // gc is waiting to run extern int8* runtime·goos; extern int32 runtime·ncpu; extern bool runtime·iscgo; extern void (*runtime·sysargs)(int32, uint8**); -extern uint32 runtime·maxstring; +extern uintptr runtime·maxstring; extern uint32 runtime·Hchansize; extern uint32 runtime·cpuid_ecx; extern uint32 runtime·cpuid_edx; +extern DebugVars runtime·debug; +extern uintptr runtime·maxstacksize; /* * common functions and data */ int32 runtime·strcmp(byte*, byte*); byte* runtime·strstr(byte*, byte*); -int32 runtime·findnull(byte*); -int32 runtime·findnullw(uint16*); +intgo runtime·findnull(byte*); +intgo runtime·findnullw(uint16*); void runtime·dump(byte*, int32); int32 runtime·runetochar(byte*, int32); int32 runtime·charntorune(int32*, uint8*, int32); @@ -685,9 +734,9 @@ int32 runtime·charntorune(int32*, uint8*, int32); */ #define FLUSH(x) USED(x) -void runtime·gogo(Gobuf*, uintptr); -void runtime·gogocall(Gobuf*, void(*)(void), uintptr); -void runtime·gogocallfn(Gobuf*, FuncVal*); +void runtime·gogo(Gobuf*); +void runtime·gostartcall(Gobuf*, void(*)(void), void*); +void runtime·gostartcallfn(Gobuf*, FuncVal*); void runtime·gosave(Gobuf*); void runtime·lessstack(void); void runtime·goargs(void); @@ -713,15 +762,13 @@ void runtime·sigenable(uint32 sig); void runtime·sigdisable(uint32 sig); int32 runtime·gotraceback(bool *crash); void runtime·goroutineheader(G*); -void runtime·traceback(uint8 *pc, uint8 *sp, uint8 *lr, G* gp); -void runtime·tracebackothers(G*); int32 runtime·open(int8*, int32, int32); int32 runtime·read(int32, void*, int32); int32 runtime·write(int32, void*, int32); int32 runtime·close(int32); int32 runtime·mincore(void*, uintptr, byte*); bool runtime·cas(uint32*, uint32, uint32); -bool runtime·cas64(uint64*, uint64*, uint64); +bool runtime·cas64(uint64*, uint64, uint64); bool runtime·casp(void**, void*, void*); // Don't confuse with XADD x86 instruction, // this one is actually 'addx', that is, add-and-fetch. @@ -748,8 +795,13 @@ void runtime·mpreinit(M*); void runtime·minit(void); void runtime·unminit(void); void runtime·signalstack(byte*, int32); +void runtime·symtabinit(void); Func* runtime·findfunc(uintptr); -int32 runtime·funcline(Func*, uintptr); +int32 runtime·funcline(Func*, uintptr, String*); +int32 runtime·funcarglen(Func*, uintptr); +int32 runtime·funcspdelta(Func*, uintptr); +int8* runtime·funcname(Func*); +int32 runtime·pcdatavalue(Func*, int32, uintptr); void* runtime·stackalloc(uint32); void runtime·stackfree(void*, uintptr); MCache* runtime·allocmcache(void); @@ -762,19 +814,22 @@ uintptr runtime·ifacehash(Iface, uintptr); uintptr runtime·efacehash(Eface, uintptr); void* runtime·malloc(uintptr size); void runtime·free(void *v); -bool runtime·addfinalizer(void*, FuncVal *fn, uintptr); void runtime·runpanic(Panic*); -void* runtime·getcallersp(void*); +uintptr runtime·getcallersp(void*); int32 runtime·mcount(void); int32 runtime·gcount(void); void runtime·mcall(void(*)(G*)); uint32 runtime·fastrand1(void); +void runtime·rewindmorestack(Gobuf*); +int32 runtime·timediv(int64, int32, int32*); void runtime·setmg(M*, G*); void runtime·newextram(void); void runtime·exit(int32); void runtime·breakpoint(void); void runtime·gosched(void); +void runtime·gosched0(G*); +void runtime·schedtrace(bool); void runtime·park(void(*)(Lock*), Lock*, int8*); void runtime·tsleep(int64, int8*); M* runtime·newm(void); @@ -786,10 +841,10 @@ void runtime·exitsyscall(void); G* runtime·newproc1(FuncVal*, byte*, int32, int32, void*); bool runtime·sigsend(int32 sig); int32 runtime·callers(int32, uintptr*, int32); -int32 runtime·gentraceback(byte*, byte*, byte*, G*, int32, uintptr*, int32, void (*)(Func*, byte*, byte*, void*), void*); int64 runtime·nanotime(void); void runtime·dopanic(int32); void runtime·startpanic(void); +void runtime·freezetheworld(void); void runtime·unwindstack(G*, byte*); void runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp); void runtime·resetcpuprofiler(int32); @@ -803,12 +858,17 @@ void runtime·addtimer(Timer*); bool runtime·deltimer(Timer*); G* runtime·netpoll(bool); void runtime·netpollinit(void); -int32 runtime·netpollopen(int32, PollDesc*); -int32 runtime·netpollclose(int32); +int32 runtime·netpollopen(uintptr, PollDesc*); +int32 runtime·netpollclose(uintptr); void runtime·netpollready(G**, PollDesc*, int32); +uintptr runtime·netpollfd(PollDesc*); void runtime·crash(void); +void runtime·parsedebugvars(void); +void _rt0_go(void); +void* runtime·funcdata(Func*, int32); #pragma varargck argpos runtime·printf 1 +#pragma varargck type "c" int32 #pragma varargck type "d" int32 #pragma varargck type "d" uint32 #pragma varargck type "D" int64 @@ -854,11 +914,15 @@ void runtime·unlock(Lock*); * wake up early, it must wait to call noteclear until it * can be sure that no other goroutine is calling * notewakeup. + * + * notesleep/notetsleep are generally called on g0, + * notetsleepg is similar to notetsleep but is called on user g. */ void runtime·noteclear(Note*); void runtime·notesleep(Note*); void runtime·notewakeup(Note*); -void runtime·notetsleep(Note*, int64); +bool runtime·notetsleep(Note*, int64); // false - timeout +bool runtime·notetsleepg(Note*, int64); // false - timeout /* * low-level synchronization for implementing the above @@ -927,6 +991,7 @@ void runtime·printuint(uint64); void runtime·printhex(uint64); void runtime·printslice(Slice); void runtime·printcomplex(Complex128); +void runtime·newstackcall(FuncVal*, byte*, uint32); void reflect·call(FuncVal*, byte*, uint32); void runtime·panic(Eface); void runtime·panicindex(void); @@ -938,6 +1003,7 @@ void runtime·panicslice(void); void runtime·printany(Eface); void runtime·newTypeAssertionError(String*, String*, String*, String*, Eface*); void runtime·newErrorString(String, Eface*); +void runtime·newErrorCString(int8*, Eface*); void runtime·fadd64c(uint64, uint64, uint64*); void runtime·fsub64c(uint64, uint64, uint64*); void runtime·fmul64c(uint64, uint64, uint64*); @@ -963,7 +1029,7 @@ bool runtime·isInf(float64 f, int32 sign); bool runtime·isNaN(float64 f); float64 runtime·ldexp(float64 d, int32 e); float64 runtime·modf(float64 d, float64 *ip); -void runtime·semacquire(uint32*); +void runtime·semacquire(uint32*, bool); void runtime·semrelease(uint32*); int32 runtime·gomaxprocsfunc(int32 n); void runtime·procyield(uint32); @@ -980,22 +1046,13 @@ Hmap* runtime·makemap_c(MapType*, int64); Hchan* runtime·makechan_c(ChanType*, int64); void runtime·chansend(ChanType*, Hchan*, byte*, bool*, void*); void runtime·chanrecv(ChanType*, Hchan*, byte*, bool*, bool*); -bool runtime·showframe(Func*, bool); +bool runtime·showframe(Func*, G*); +void runtime·printcreatedby(G*); void runtime·ifaceE2I(InterfaceType*, Eface, Iface*); - +bool runtime·ifaceE2I2(InterfaceType*, Eface, Iface*); uintptr runtime·memlimit(void); -// If appropriate, ask the operating system to control whether this -// thread should receive profiling signals. This is only necessary on OS X. -// An operating system should not deliver a profiling signal to a -// thread that is not actually executing (what good is that?), but that's -// what OS X prefers to do. When profiling is turned on, we mask -// away the profiling signal when threads go to sleep, so that OS X -// is forced to deliver the signal to a thread that's actually running. -// This is a no-op on other systems. -void runtime·setprof(bool); - // float.c extern float64 runtime·nan; extern float64 runtime·posinf; |