diff options
Diffstat (limited to 'libgo/runtime/runtime.h')
-rw-r--r-- | libgo/runtime/runtime.h | 158 |
1 files changed, 108 insertions, 50 deletions
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index da2416335e..515ae58ff8 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -5,6 +5,7 @@ #include "config.h" #include "go-assert.h" +#include <complex.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> @@ -48,6 +49,8 @@ typedef unsigned int uintptr __attribute__ ((mode (pointer))); typedef intptr intgo; // Go's int typedef uintptr uintgo; // Go's uint +typedef uintptr uintreg; + /* Defined types. */ typedef uint8 bool; @@ -192,7 +195,6 @@ struct Location struct G { - void* closure; // Closure value. Defer* defer; Panic* panic; void* exception; // current exception being thrown @@ -204,24 +206,23 @@ struct G void* gcinitial_sp; ucontext_t gcregs; byte* entry; // initial function - G* alllink; // on allg void* param; // passed parameter on wakeup bool fromgogo; // reached from gogo int16 status; uint32 selgen; // valid sudog pointer int64 goid; + int64 waitsince; // approx time when the G become blocked const char* waitreason; // if status==Gwaiting G* schedlink; bool ispanic; bool issystem; // do not output in stack dump bool isbackground; // ignore in deadlock detector + bool paniconfault; // panic (instead of crash) on unexpected fault address M* m; // for debuggers, but offset not hard-coded M* lockedm; int32 sig; int32 writenbuf; byte* writebuf; - // DeferChunk* dchunk; - // DeferChunk* dchunknext; uintptr sigcode0; uintptr sigcode1; // uintptr sigpc; @@ -252,10 +253,12 @@ struct M int32 throwing; int32 gcing; int32 locks; + int32 softfloat; int32 dying; int32 profilehz; int32 helpgc; - bool spinning; + bool spinning; // M is out of work and is actively looking for work + bool blocked; // M is blocked on a Note uint32 fastrand; uint64 ncgocall; // number of cgo calls in total int32 ncgo; // number of cgo calls currently in progress @@ -272,16 +275,11 @@ struct M uint32 waitsemacount; uint32 waitsemalock; GCStats gcstats; - bool racecall; bool needextram; bool dropextram; // for gccgo: drop after call is done. - void* racepc; - void (*waitunlockf)(Lock*); + uint8 traceback; + bool (*waitunlockf)(G*, void*); void* waitlock; - - uintptr settype_buf[1024]; - uintptr settype_bufsize; - uintptr end[]; }; @@ -296,12 +294,16 @@ struct P uint32 syscalltick; // incremented on every system call M* m; // back-link to associated M (nil if idle) MCache* mcache; + Defer* deferpool; // pool of available Defer structs (see panic.c) + + // Cache of goroutine ids, amortizes accesses to runtime_sched.goidgen. + uint64 goidcache; + uint64 goidcacheend; // Queue of runnable goroutines. - G** runq; - int32 runqhead; - int32 runqtail; - int32 runqsize; + uint32 runqhead; + uint32 runqtail; + G* runq[256]; // Available G's (status == Gdead) G* gfree; @@ -337,6 +339,7 @@ enum SigDefault = 1<<4, // if the signal isn't explicitly requested, don't monitor it SigHandling = 1<<5, // our signal handler is registered SigIgnored = 1<<6, // the signal was ignored before we registered for it + SigGoExit = 1<<7, // cause all runtime procs to exit (only used on Plan 9). }; // Layout of in-memory per-function information prepared by linker @@ -349,6 +352,16 @@ struct Func uintptr entry; // entry pc }; +#ifdef GOOS_nacl +enum { + NaCl = 1, +}; +#else +enum { + NaCl = 0, +}; +#endif + #ifdef GOOS_windows enum { Windows = 1 @@ -358,6 +371,15 @@ enum { Windows = 0 }; #endif +#ifdef GOOS_solaris +enum { + Solaris = 1 +}; +#else +enum { + Solaris = 0 +}; +#endif struct Timers { @@ -373,9 +395,11 @@ struct Timers // Package time knows the layout of this structure. // If this struct changes, adjust ../time/sleep.go:/runtimeTimer. +// For GOOS=nacl, package syscall knows the layout of this structure. +// If this struct changes, adjust ../syscall/net_nacl.go:/runtimeTimer. struct Timer { - int32 i; // heap index + intgo 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 @@ -384,6 +408,7 @@ struct Timer int64 period; FuncVal *fv; Eface arg; + uintptr seq; }; // Lock-free stack node. @@ -426,12 +451,16 @@ struct CgoMal // Holds variables parsed from GODEBUG env var. struct DebugVars { + int32 allocfreetrace; + int32 efence; int32 gctrace; - int32 schedtrace; + int32 gcdead; int32 scheddetail; + int32 schedtrace; }; extern bool runtime_precisestack; +extern bool runtime_copystack; /* * defined macros @@ -441,7 +470,7 @@ extern bool runtime_precisestack; #define nelem(x) (sizeof(x)/sizeof((x)[0])) #define nil ((void*)0) #define USED(v) ((void) v) -#define ROUND(x, n) (((x)+(n)-1)&~((n)-1)) /* all-caps to mark as macro: it evaluates n twice */ +#define ROUND(x, n) (((x)+(n)-1)&~(uintptr)((n)-1)) /* all-caps to mark as macro: it evaluates n twice */ byte* runtime_startup_random_data; uint32 runtime_startup_random_data_len; @@ -455,12 +484,18 @@ void runtime_hashinit(void); void runtime_traceback(void); void runtime_tracebackothers(G*); +enum +{ + // The maximum number of frames we print for a traceback + TracebackMaxFrames = 100, +}; /* * external data */ extern uintptr runtime_zerobase; -extern G* runtime_allg; +extern G** runtime_allg; +extern uintptr runtime_allglen; extern G* runtime_lastg; extern M* runtime_allm; extern P** runtime_allp; @@ -470,20 +505,20 @@ extern uint32 runtime_panicking; extern int8* runtime_goos; extern int32 runtime_ncpu; extern void (*runtime_sysargs)(int32, uint8**); +extern uint32 runtime_Hchansize; extern DebugVars runtime_debug; +extern uintptr runtime_maxstacksize; /* * common functions and data */ #define runtime_strcmp(s1, s2) __builtin_strcmp((s1), (s2)) +#define runtime_strncmp(s1, s2, n) __builtin_strncmp((s1), (s2), (n)) #define runtime_strstr(s1, s2) __builtin_strstr((s1), (s2)) intgo runtime_findnull(const byte*); intgo runtime_findnullw(const uint16*); void runtime_dump(byte*, int32); -/* - * very low level c-called - */ void runtime_gogo(G*); struct __go_func_type; void runtime_args(int32, byte**); @@ -493,8 +528,10 @@ void runtime_goenvs(void); void runtime_goenvs_unix(void); void runtime_throw(const char*) __attribute__ ((noreturn)); void runtime_panicstring(const char*) __attribute__ ((noreturn)); +bool runtime_canpanic(G*); void runtime_prints(const char*); void runtime_printf(const char*, ...); +int32 runtime_snprintf(byte*, int32, const char*, ...); #define runtime_mcmp(a, b, s) __builtin_memcmp((a), (b), (s)) #define runtime_memmove(a, b, s) __builtin_memmove((a), (b), (s)) void* runtime_mal(uintptr); @@ -511,21 +548,6 @@ void runtime_printtrace(Location*, int32, bool); #define runtime_read(d, v, n) read((d), (v), (n)) #define runtime_write(d, v, n) write((d), (v), (n)) #define runtime_close(d) close(d) -#define runtime_cas(pval, old, new) __sync_bool_compare_and_swap (pval, old, new) -#define runtime_cas64(pval, old, new) __sync_bool_compare_and_swap (pval, old, new) -#define runtime_casp(pval, old, new) __sync_bool_compare_and_swap (pval, old, new) -// Don't confuse with XADD x86 instruction, -// this one is actually 'addx', that is, add-and-fetch. -#define runtime_xadd(p, v) __sync_add_and_fetch (p, v) -#define runtime_xadd64(p, v) __sync_add_and_fetch (p, v) -#define runtime_xchg(p, v) __atomic_exchange_n (p, v, __ATOMIC_SEQ_CST) -#define runtime_xchg64(p, v) __atomic_exchange_n (p, v, __ATOMIC_SEQ_CST) -#define runtime_atomicload(p) __atomic_load_n (p, __ATOMIC_SEQ_CST) -#define runtime_atomicstore(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST) -#define runtime_atomicstore64(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST) -#define runtime_atomicload64(p) __atomic_load_n (p, __ATOMIC_SEQ_CST) -#define runtime_atomicloadp(p) __atomic_load_n (p, __ATOMIC_SEQ_CST) -#define runtime_atomicstorep(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST) void runtime_ready(G*); const byte* runtime_getenv(const char*); int32 runtime_atoi(const byte*); @@ -543,13 +565,31 @@ void runtime_mallocinit(void); void runtime_mprofinit(void); #define runtime_malloc(s) __go_alloc(s) #define runtime_free(p) __go_free(p) -bool runtime_addfinalizer(void*, FuncVal *fn, const struct __go_func_type *, const struct __go_ptr_type *); #define runtime_getcallersp(p) __builtin_frame_address(1) int32 runtime_mcount(void); int32 runtime_gcount(void); void runtime_mcall(void(*)(G*)); uint32 runtime_fastrand1(void); int32 runtime_timediv(int64, int32, int32*); +int32 runtime_round2(int32 x); // round x up to a power of 2. + +// atomic operations +#define runtime_cas(pval, old, new) __sync_bool_compare_and_swap (pval, old, new) +#define runtime_cas64(pval, old, new) __sync_bool_compare_and_swap (pval, old, new) +#define runtime_casp(pval, old, new) __sync_bool_compare_and_swap (pval, old, new) +// Don't confuse with XADD x86 instruction, +// this one is actually 'addx', that is, add-and-fetch. +#define runtime_xadd(p, v) __sync_add_and_fetch (p, v) +#define runtime_xadd64(p, v) __sync_add_and_fetch (p, v) +#define runtime_xchg(p, v) __atomic_exchange_n (p, v, __ATOMIC_SEQ_CST) +#define runtime_xchg64(p, v) __atomic_exchange_n (p, v, __ATOMIC_SEQ_CST) +#define runtime_xchgp(p, v) __atomic_exchange_n (p, v, __ATOMIC_SEQ_CST) +#define runtime_atomicload(p) __atomic_load_n (p, __ATOMIC_SEQ_CST) +#define runtime_atomicstore(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST) +#define runtime_atomicstore64(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST) +#define runtime_atomicload64(p) __atomic_load_n (p, __ATOMIC_SEQ_CST) +#define runtime_atomicloadp(p) __atomic_load_n (p, __ATOMIC_SEQ_CST) +#define runtime_atomicstorep(p, v) __atomic_store_n (p, v, __ATOMIC_SEQ_CST) void runtime_setmg(M*, G*); void runtime_newextram(void); @@ -558,7 +598,8 @@ void runtime_newextram(void); void runtime_gosched(void); void runtime_gosched0(G*); void runtime_schedtrace(bool); -void runtime_park(void(*)(Lock*), Lock*, const char*); +void runtime_park(bool(*)(G*, void*), void*, const char*); +void runtime_parkunlock(Lock*, const char*); void runtime_tsleep(int64, const char*); M* runtime_newm(void); void runtime_goexit(void); @@ -568,8 +609,9 @@ void runtime_exitsyscall(void) __asm__ (GOSYM_PREFIX "syscall.Exitsyscall"); G* __go_go(void (*pfn)(void*), void*); void siginit(void); bool __go_sigsend(int32 sig); -int32 runtime_callers(int32, Location*, int32); -int64 runtime_nanotime(void); +int32 runtime_callers(int32, Location*, int32, bool keep_callers); +int64 runtime_nanotime(void); // monotonic time +int64 runtime_unixnanotime(void); // real time, can skip void runtime_dopanic(int32) __attribute__ ((noreturn)); void runtime_startpanic(void); void runtime_freezetheworld(void); @@ -590,10 +632,18 @@ int32 runtime_netpollopen(uintptr, PollDesc*); int32 runtime_netpollclose(uintptr); void runtime_netpollready(G**, PollDesc*, int32); uintptr runtime_netpollfd(PollDesc*); +void runtime_netpollarm(PollDesc*, int32); +void** runtime_netpolluser(PollDesc*); +bool runtime_netpollclosing(PollDesc*); +void runtime_netpolllock(PollDesc*); +void runtime_netpollunlock(PollDesc*); void runtime_crash(void); void runtime_parsedebugvars(void); void _rt0_go(void); void* runtime_funcdata(Func*, int32); +int32 runtime_setmaxthreads(int32); +G* runtime_timejump(void); +void runtime_iterate_finq(void (*callback)(FuncVal*, void*, const FuncType*, const PtrType*)); void runtime_stoptheworld(void); void runtime_starttheworld(void); @@ -666,7 +716,8 @@ LFNode* runtime_lfstackpop(uint64 *head); */ ParFor* runtime_parforalloc(uint32 nthrmax); void runtime_parforsetup(ParFor *desc, uint32 nthr, uint32 n, void *ctx, bool wait, void (*body)(ParFor*, uint32)); -void runtime_parfordo(ParFor *desc) __asm__ (GOSYM_PREFIX "runtime.parfordo"); +void runtime_parfordo(ParFor *desc); +void runtime_parforiters(ParFor*, uintptr, uintptr*, uintptr*); /* * low level C-called @@ -710,7 +761,7 @@ void runtime_printpointer(void*); void runtime_printuint(uint64); void runtime_printhex(uint64); void runtime_printslice(Slice); -void runtime_printcomplex(__complex double); +void runtime_printcomplex(complex double); void reflect_call(const struct __go_func_type *, FuncVal *, _Bool, _Bool, void **, void **) __asm__ (GOSYM_PREFIX "reflect.call"); @@ -723,8 +774,6 @@ void runtime_printany(Eface) __asm__ (GOSYM_PREFIX "runtime.Printany"); void runtime_newTypeAssertionError(const String*, const String*, const String*, const String*, Eface*) __asm__ (GOSYM_PREFIX "runtime.NewTypeAssertionError"); -void runtime_newErrorString(String, Eface*) - __asm__ (GOSYM_PREFIX "runtime.NewErrorString"); void runtime_newErrorCString(const char*, Eface*) __asm__ (GOSYM_PREFIX "runtime.NewErrorCString"); @@ -738,6 +787,7 @@ void runtime_procyield(uint32); void runtime_osyield(void); void runtime_lockOSThread(void); void runtime_unlockOSThread(void); +bool runtime_lockedOSThread(void); bool runtime_showframe(String, bool); void runtime_printcreatedby(G*); @@ -748,7 +798,7 @@ uintptr runtime_memlimit(void); enum { - UseSpanType = 0, + UseSpanType = 1, }; #define runtime_setitimer setitimer @@ -782,8 +832,16 @@ int32 getproccount(void); #define PREFETCH(p) __builtin_prefetch(p) -void __go_set_closure(void*); -void* __go_get_closure(void); - bool runtime_gcwaiting(void); void runtime_badsignal(int); +Defer* runtime_newdefer(void); +void runtime_freedefer(Defer*); + +struct time_now_ret +{ + int64_t sec; + int32_t nsec; +}; + +struct time_now_ret now() __asm__ (GOSYM_PREFIX "time.now") + __attribute__ ((no_split_stack)); |