diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-11-11 21:02:48 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-11-11 21:02:48 +0000 |
commit | 34277c5228d466ffcd4260eea1805ca77972c83c (patch) | |
tree | 6dc91773cd2743418de4eb59e161cb0a4381c77a /libgo/runtime | |
parent | 292b44341cc5355d353cb652eb3d78d3341c800f (diff) | |
download | gcc-34277c5228d466ffcd4260eea1805ca77972c83c.zip gcc-34277c5228d466ffcd4260eea1805ca77972c83c.tar.gz gcc-34277c5228d466ffcd4260eea1805ca77972c83c.tar.bz2 |
Introduce G structure and thread-local global g.
From-SVN: r181301
Diffstat (limited to 'libgo/runtime')
-rw-r--r-- | libgo/runtime/go-defer.c | 24 | ||||
-rw-r--r-- | libgo/runtime/go-deferred-recover.c | 5 | ||||
-rw-r--r-- | libgo/runtime/go-go.c | 14 | ||||
-rw-r--r-- | libgo/runtime/go-main.c | 4 | ||||
-rw-r--r-- | libgo/runtime/go-panic-defer.c | 13 | ||||
-rw-r--r-- | libgo/runtime/go-panic.c | 16 | ||||
-rw-r--r-- | libgo/runtime/go-panic.h | 30 | ||||
-rw-r--r-- | libgo/runtime/go-recover.c | 13 | ||||
-rw-r--r-- | libgo/runtime/go-unwind.c | 39 | ||||
-rw-r--r-- | libgo/runtime/mgc0.c | 3 | ||||
-rw-r--r-- | libgo/runtime/proc.c | 6 | ||||
-rw-r--r-- | libgo/runtime/runtime.h | 35 |
12 files changed, 91 insertions, 111 deletions
diff --git a/libgo/runtime/go-defer.c b/libgo/runtime/go-defer.c index 1f116eb..dda62fb 100644 --- a/libgo/runtime/go-defer.c +++ b/libgo/runtime/go-defer.c @@ -6,6 +6,7 @@ #include <stddef.h> +#include "runtime.h" #include "go-alloc.h" #include "go-panic.h" #include "go-defer.h" @@ -17,18 +18,14 @@ __go_defer (_Bool *frame, void (*pfn) (void *), void *arg) { struct __go_defer_stack *n; - if (__go_panic_defer == NULL) - __go_panic_defer = ((struct __go_panic_defer_struct *) - __go_alloc (sizeof (struct __go_panic_defer_struct))); - n = (struct __go_defer_stack *) __go_alloc (sizeof (struct __go_defer_stack)); - n->__next = __go_panic_defer->__defer; + n->__next = g->defer; n->__frame = frame; - n->__panic = __go_panic_defer->__panic; + n->__panic = g->panic; n->__pfn = pfn; n->__arg = arg; n->__retaddr = NULL; - __go_panic_defer->__defer = n; + g->defer = n; } /* This function is called when we want to undefer the stack. */ @@ -36,22 +33,19 @@ __go_defer (_Bool *frame, void (*pfn) (void *), void *arg) void __go_undefer (_Bool *frame) { - if (__go_panic_defer == NULL) - return; - while (__go_panic_defer->__defer != NULL - && __go_panic_defer->__defer->__frame == frame) + while (g->defer != NULL && g->defer->__frame == frame) { struct __go_defer_stack *d; void (*pfn) (void *); - d = __go_panic_defer->__defer; + d = g->defer; pfn = d->__pfn; d->__pfn = NULL; if (pfn != NULL) (*pfn) (d->__arg); - __go_panic_defer->__defer = d->__next; + g->defer = d->__next; __go_free (d); /* Since we are executing a defer function here, we know we are @@ -69,7 +63,7 @@ __go_undefer (_Bool *frame) _Bool __go_set_defer_retaddr (void *retaddr) { - if (__go_panic_defer != NULL && __go_panic_defer->__defer != NULL) - __go_panic_defer->__defer->__retaddr = retaddr; + if (g->defer != NULL) + g->defer->__retaddr = retaddr; return 0; } diff --git a/libgo/runtime/go-deferred-recover.c b/libgo/runtime/go-deferred-recover.c index 2d9ca14..d749c27 100644 --- a/libgo/runtime/go-deferred-recover.c +++ b/libgo/runtime/go-deferred-recover.c @@ -6,6 +6,7 @@ #include <stddef.h> +#include "runtime.h" #include "go-panic.h" #include "go-defer.h" @@ -78,9 +79,7 @@ struct __go_empty_interface __go_deferred_recover () { - if (__go_panic_defer == NULL - || __go_panic_defer->__defer == NULL - || __go_panic_defer->__defer->__panic != __go_panic_defer->__panic) + if (g->defer == NULL || g->defer->__panic != g->panic) { struct __go_empty_interface ret; diff --git a/libgo/runtime/go-go.c b/libgo/runtime/go-go.c index d56b8b1..82b265f 100644 --- a/libgo/runtime/go-go.c +++ b/libgo/runtime/go-go.c @@ -115,6 +115,7 @@ remove_current_thread (void *dummy __attribute__ ((unused))) any code from here to thread exit must not assume that m is valid. */ m = NULL; + g = NULL; i = pthread_mutex_unlock (&__go_thread_ids_lock); __go_assert (i == 0); @@ -135,10 +136,11 @@ start_go_thread (void *thread_arg) #ifdef __rtems__ __wrap_rtems_task_variable_add ((void **) &m); - __wrap_rtems_task_variable_add ((void **) &__go_panic_defer); + __wrap_rtems_task_variable_add ((void **) &g); #endif m = newm; + g = m->curg; pthread_cleanup_push (remove_current_thread, NULL); @@ -230,6 +232,9 @@ __go_go (void (*pfn) (void*), void *arg) newm->list_entry = list_entry; + newm->curg = __go_alloc (sizeof (G)); + newm->curg->m = newm; + newm->id = __sync_fetch_and_add (&mcount, 1); newm->fastrand = 0x49f6428aUL + newm->id; @@ -299,9 +304,6 @@ stop_for_gc (void) } #endif - /* FIXME: Perhaps we should just move __go_panic_defer into M. */ - m->gc_panic_defer = __go_panic_defer; - /* Tell the garbage collector that we are ready by posting to the semaphore. */ i = sem_post (&__go_thread_ready_sem); @@ -433,10 +435,6 @@ runtime_stoptheworld (void) --c; } - /* The gc_panic_defer field should now be set for all M's except the - one in this thread. Set this one now. */ - m->gc_panic_defer = __go_panic_defer; - /* Leave with __go_thread_ids_lock held. */ } diff --git a/libgo/runtime/go-main.c b/libgo/runtime/go-main.c index 927a36c..15a6a30 100644 --- a/libgo/runtime/go-main.c +++ b/libgo/runtime/go-main.c @@ -48,6 +48,10 @@ main (int argc, char **argv) int i; struct __go_string *values; + m = &runtime_m0; + g = &runtime_g0; + m->curg = g; + g->m = m; runtime_mallocinit (); runtime_cpuprofinit (); __go_gc_goroutine_init (&argc); diff --git a/libgo/runtime/go-panic-defer.c b/libgo/runtime/go-panic-defer.c deleted file mode 100644 index 64773bb..0000000 --- a/libgo/runtime/go-panic-defer.c +++ /dev/null @@ -1,13 +0,0 @@ -/* go-panic-stack.c -- The panic/defer stack. - - Copyright 2010 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. */ - -#include "go-panic.h" - -#ifdef __rtems__ -#define __thread -#endif - -__thread struct __go_panic_defer_struct *__go_panic_defer; diff --git a/libgo/runtime/go-panic.c b/libgo/runtime/go-panic.c index f3e182d..8b95cd4 100644 --- a/libgo/runtime/go-panic.c +++ b/libgo/runtime/go-panic.c @@ -41,14 +41,10 @@ __go_panic (struct __go_empty_interface arg) { struct __go_panic_stack *n; - if (__go_panic_defer == NULL) - __go_panic_defer = ((struct __go_panic_defer_struct *) - __go_alloc (sizeof (struct __go_panic_defer_struct))); - n = (struct __go_panic_stack *) __go_alloc (sizeof (struct __go_panic_stack)); n->__arg = arg; - n->__next = __go_panic_defer->__panic; - __go_panic_defer->__panic = n; + n->__next = g->panic; + g->panic = n; /* Run all the defer functions. */ @@ -57,7 +53,7 @@ __go_panic (struct __go_empty_interface arg) struct __go_defer_stack *d; void (*pfn) (void *); - d = __go_panic_defer->__defer; + d = g->defer; if (d == NULL) break; @@ -73,7 +69,7 @@ __go_panic (struct __go_empty_interface arg) /* Some defer function called recover. That means that we should stop running this panic. */ - __go_panic_defer->__panic = n->__next; + g->panic = n->__next; __go_free (n); /* Now unwind the stack by throwing an exception. The @@ -96,13 +92,13 @@ __go_panic (struct __go_empty_interface arg) *d->__frame = 0; } - __go_panic_defer->__defer = d->__next; + g->defer = d->__next; __go_free (d); } /* The panic was not recovered. */ - __printpanics (__go_panic_defer->__panic); + __printpanics (g->panic); /* FIXME: We should dump a call stack here. */ abort (); diff --git a/libgo/runtime/go-panic.h b/libgo/runtime/go-panic.h index 2836c46..bd3e238 100644 --- a/libgo/runtime/go-panic.h +++ b/libgo/runtime/go-panic.h @@ -31,36 +31,6 @@ struct __go_panic_stack _Bool __is_foreign; }; -/* The panic and defer stacks, grouped together into a single thread - local variable for convenience for systems without TLS. */ - -struct __go_panic_defer_struct -{ - /* The list of defers to execute. */ - struct __go_defer_stack *__defer; - - /* The list of currently active panics. There will be more than one - if a deferred function calls panic. */ - struct __go_panic_stack *__panic; - - /* The current exception being thrown when unwinding after a call to - panic . This is really struct _UnwindException *. */ - void *__exception; - - /* Whether the current exception is from some other language. */ - _Bool __is_foreign; -}; - -#ifdef __rtems__ -#define __thread -#endif - -extern __thread struct __go_panic_defer_struct *__go_panic_defer; - -#ifdef __rtems__ -#undef __thread -#endif - extern void __go_panic (struct __go_empty_interface) __attribute__ ((noreturn)); diff --git a/libgo/runtime/go-recover.c b/libgo/runtime/go-recover.c index 4de122e..fe6031c 100644 --- a/libgo/runtime/go-recover.c +++ b/libgo/runtime/go-recover.c @@ -4,6 +4,7 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ +#include "runtime.h" #include "interface.h" #include "go-panic.h" #include "go-defer.h" @@ -21,9 +22,7 @@ __go_can_recover (const void* retaddr) const char* ret; const char* dret; - if (__go_panic_defer == NULL) - return 0; - d = __go_panic_defer->__defer; + d = g->defer; if (d == NULL) return 0; @@ -31,7 +30,7 @@ __go_can_recover (const void* retaddr) of the panic stack. We do not want to recover it if that panic was on the top of the panic stack when this function was deferred. */ - if (d->__panic == __go_panic_defer->__panic) + if (d->__panic == g->panic) return 0; /* D->__RETADDR is the address of a label immediately following the @@ -53,9 +52,7 @@ __go_recover () { struct __go_panic_stack *p; - if (__go_panic_defer == NULL - || __go_panic_defer->__panic == NULL - || __go_panic_defer->__panic->__was_recovered) + if (g->panic == NULL || g->panic->__was_recovered) { struct __go_empty_interface ret; @@ -63,7 +60,7 @@ __go_recover () ret.__object = NULL; return ret; } - p = __go_panic_defer->__panic; + p = g->panic; p->__was_recovered = 1; return p->__arg; } diff --git a/libgo/runtime/go-unwind.c b/libgo/runtime/go-unwind.c index e64cf90..58c675a 100644 --- a/libgo/runtime/go-unwind.c +++ b/libgo/runtime/go-unwind.c @@ -13,6 +13,7 @@ #define NO_SIZE_OF_ENCODED_VALUE #include "unwind-pe.h" +#include "runtime.h" #include "go-alloc.h" #include "go-defer.h" #include "go-panic.h" @@ -48,12 +49,12 @@ __go_check_defer (_Bool *frame) { struct _Unwind_Exception *hdr; - if (__go_panic_defer == NULL) + if (g == NULL) { /* Some other language has thrown an exception. We know there are no defer handlers, so there is nothing to do. */ } - else if (__go_panic_defer->__is_foreign) + else if (g->is_foreign) { struct __go_panic_stack *n; _Bool was_recovered; @@ -69,20 +70,20 @@ __go_check_defer (_Bool *frame) n->__arg.__object = NULL; n->__was_recovered = 0; n->__is_foreign = 1; - n->__next = __go_panic_defer->__panic; - __go_panic_defer->__panic = n; + n->__next = g->panic; + g->panic = n; while (1) { struct __go_defer_stack *d; void (*pfn) (void *); - d = __go_panic_defer->__defer; + d = g->defer; if (d == NULL || d->__frame != frame || d->__pfn == NULL) break; pfn = d->__pfn; - __go_panic_defer->__defer = d->__next; + g->defer = d->__next; (*pfn) (d->__arg); @@ -97,7 +98,7 @@ __go_check_defer (_Bool *frame) } was_recovered = n->__was_recovered; - __go_panic_defer->__panic = n->__next; + g->panic = n->__next; __go_free (n); if (was_recovered) @@ -110,17 +111,17 @@ __go_check_defer (_Bool *frame) /* We are panicing through this function. */ *frame = 0; } - else if (__go_panic_defer->__defer != NULL - && __go_panic_defer->__defer->__pfn == NULL - && __go_panic_defer->__defer->__frame == frame) + else if (g->defer != NULL + && g->defer->__pfn == NULL + && g->defer->__frame == frame) { struct __go_defer_stack *d; /* This is the defer function which called recover. Simply return to stop the stack unwind, and let the Go code continue to execute. */ - d = __go_panic_defer->__defer; - __go_panic_defer->__defer = d->__next; + d = g->defer; + g->defer = d->__next; __go_free (d); /* We are returning from this function. */ @@ -132,7 +133,7 @@ __go_check_defer (_Bool *frame) /* This is some other defer function. It was already run by the call to panic, or just above. Rethrow the exception. */ - hdr = (struct _Unwind_Exception *) __go_panic_defer->__exception; + hdr = (struct _Unwind_Exception *) g->exception; #ifdef LIBGO_SJLJ_EXCEPTIONS _Unwind_SjLj_Resume_or_Rethrow (hdr); @@ -163,7 +164,7 @@ __go_unwind_stack () sizeof hdr->exception_class); hdr->exception_cleanup = NULL; - __go_panic_defer->__exception = hdr; + g->exception = hdr; #ifdef __USING_SJLJ_EXCEPTIONS__ _Unwind_SjLj_RaiseException (hdr); @@ -413,17 +414,17 @@ PERSONALITY_FUNCTION (int version, return _URC_HANDLER_FOUND; } - /* It's possible for __go_panic_defer to be NULL here for an - exception thrown by a language other than Go. */ - if (__go_panic_defer == NULL) + /* It's possible for g to be NULL here for an exception thrown by a + language other than Go. */ + if (g == NULL) { if (!is_foreign) abort (); } else { - __go_panic_defer->__exception = ue_header; - __go_panic_defer->__is_foreign = is_foreign; + g->exception = ue_header; + g->is_foreign = is_foreign; } _Unwind_SetGR (context, __builtin_eh_return_data_regno (0), diff --git a/libgo/runtime/mgc0.c b/libgo/runtime/mgc0.c index cb58525..6d402e5 100644 --- a/libgo/runtime/mgc0.c +++ b/libgo/runtime/mgc0.c @@ -652,7 +652,8 @@ mark(void (*scan)(byte*, int64)) } } - scan((byte*)&m0, sizeof m0); + scan((byte*)&runtime_m0, sizeof runtime_m0); + scan((byte*)&runtime_g0, sizeof runtime_g0); scan((byte*)&finq, sizeof finq); runtime_MProf_Mark(scan); diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c index 8af6935..e9b7c90 100644 --- a/libgo/runtime/proc.c +++ b/libgo/runtime/proc.c @@ -8,13 +8,15 @@ typedef struct Sched Sched; -M m0; +G runtime_g0; +M runtime_m0; #ifdef __rtems__ #define __thread #endif -__thread M *m = &m0; +__thread G *g; +__thread M *m; static struct { Lock; diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index 2767dd8..7f061cb 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -48,11 +48,15 @@ typedef unsigned int uintptr __attribute__ ((mode (pointer))); typedef uint8 bool; typedef uint8 byte; +typedef struct G G; typedef struct M M; typedef struct MCache MCache; typedef struct FixAlloc FixAlloc; typedef struct Lock Lock; +typedef struct __go_defer_stack Defer; +typedef struct __go_panic_stack Panic; + /* We use mutexes for locks. 6g uses futexes directly, and perhaps someday we will do that too. */ @@ -76,9 +80,11 @@ struct Note { #define __thread #endif +extern __thread G* g; extern __thread M* m; -extern M m0; +extern M runtime_m0; +extern G runtime_g0; #ifdef __rtems__ #undef __thread @@ -94,8 +100,34 @@ enum /* Structures. */ +struct G +{ + Defer* defer; + Panic* panic; + void* exception; // current exception being thrown + bool is_foreign; // whether current exception from other language + byte* entry; // initial function + G* alllink; // on allg + void* param; // passed parameter on wakeup + int16 status; + int32 goid; + int8* waitreason; // if status==Gwaiting + G* schedlink; + bool readyonstop; + bool ispanic; + M* m; // for debuggers, but offset not hard-coded + M* lockedm; + M* idlem; + // int32 sig; + // uintptr sigcode0; + // uintptr sigcode1; + // uintptr sigpc; + // uintptr gopc; // pc of go statement that created this goroutine +}; + struct M { + G* curg; // current running goroutine int32 id; int32 mallocing; int32 gcing; @@ -117,7 +149,6 @@ struct M void *gc_next_segment; void *gc_next_sp; void *gc_initial_sp; - struct __go_panic_defer_struct *gc_panic_defer; }; /* Macros. */ |