summaryrefslogtreecommitdiff
path: root/libgo/runtime/runtime.h
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/runtime/runtime.h')
-rw-r--r--libgo/runtime/runtime.h158
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));