Introduce G structure and thread-local global g.

From-SVN: r181301
This commit is contained in:
Ian Lance Taylor 2011-11-11 21:02:48 +00:00
parent 292b44341c
commit 34277c5228
14 changed files with 102 additions and 133 deletions

View file

@ -434,7 +434,6 @@ runtime_files = \
runtime/go-new.c \ runtime/go-new.c \
runtime/go-note.c \ runtime/go-note.c \
runtime/go-panic.c \ runtime/go-panic.c \
runtime/go-panic-defer.c \
runtime/go-print.c \ runtime/go-print.c \
runtime/go-rand.c \ runtime/go-rand.c \
runtime/go-rec-big.c \ runtime/go-rec-big.c \

View file

@ -198,14 +198,14 @@ am__libgo_la_SOURCES_DIST = runtime/go-append.c runtime/go-assert.c \
runtime/go-map-index.c runtime/go-map-len.c \ runtime/go-map-index.c runtime/go-map-len.c \
runtime/go-map-range.c runtime/go-nanotime.c \ runtime/go-map-range.c runtime/go-nanotime.c \
runtime/go-new-channel.c runtime/go-new-map.c runtime/go-new.c \ runtime/go-new-channel.c runtime/go-new-map.c runtime/go-new.c \
runtime/go-note.c runtime/go-panic.c runtime/go-panic-defer.c \ runtime/go-note.c runtime/go-panic.c runtime/go-print.c \
runtime/go-print.c runtime/go-rand.c runtime/go-rec-big.c \ runtime/go-rand.c runtime/go-rec-big.c runtime/go-rec-nb-big.c \
runtime/go-rec-nb-big.c runtime/go-rec-nb-small.c \ runtime/go-rec-nb-small.c runtime/go-rec-small.c \
runtime/go-rec-small.c runtime/go-recover.c \ runtime/go-recover.c runtime/go-reflect.c \
runtime/go-reflect.c runtime/go-reflect-call.c \ runtime/go-reflect-call.c runtime/go-reflect-chan.c \
runtime/go-reflect-chan.c runtime/go-reflect-map.c \ runtime/go-reflect-map.c runtime/go-rune.c \
runtime/go-rune.c runtime/go-runtime-error.c \ runtime/go-runtime-error.c runtime/go-sched.c \
runtime/go-sched.c runtime/go-select.c runtime/go-semacquire.c \ runtime/go-select.c runtime/go-semacquire.c \
runtime/go-send-big.c runtime/go-send-nb-big.c \ runtime/go-send-big.c runtime/go-send-nb-big.c \
runtime/go-send-nb-small.c runtime/go-send-small.c \ runtime/go-send-nb-small.c runtime/go-send-small.c \
runtime/go-setenv.c runtime/go-signal.c runtime/go-strcmp.c \ runtime/go-setenv.c runtime/go-signal.c runtime/go-strcmp.c \
@ -239,10 +239,9 @@ am__objects_3 = go-append.lo go-assert.lo go-assert-interface.lo \
go-interface-val-compare.lo go-lock-os-thread.lo \ go-interface-val-compare.lo go-lock-os-thread.lo \
go-make-slice.lo go-map-delete.lo go-map-index.lo \ go-make-slice.lo go-map-delete.lo go-map-index.lo \
go-map-len.lo go-map-range.lo go-nanotime.lo go-new-channel.lo \ go-map-len.lo go-map-range.lo go-nanotime.lo go-new-channel.lo \
go-new-map.lo go-new.lo go-note.lo go-panic.lo \ go-new-map.lo go-new.lo go-note.lo go-panic.lo go-print.lo \
go-panic-defer.lo go-print.lo go-rand.lo go-rec-big.lo \ go-rand.lo go-rec-big.lo go-rec-nb-big.lo go-rec-nb-small.lo \
go-rec-nb-big.lo go-rec-nb-small.lo go-rec-small.lo \ go-rec-small.lo go-recover.lo go-reflect.lo go-reflect-call.lo \
go-recover.lo go-reflect.lo go-reflect-call.lo \
go-reflect-chan.lo go-reflect-map.lo go-rune.lo \ go-reflect-chan.lo go-reflect-map.lo go-rune.lo \
go-runtime-error.lo go-sched.lo go-select.lo go-semacquire.lo \ go-runtime-error.lo go-sched.lo go-select.lo go-semacquire.lo \
go-send-big.lo go-send-nb-big.lo go-send-nb-small.lo \ go-send-big.lo go-send-nb-big.lo go-send-nb-small.lo \
@ -865,7 +864,6 @@ runtime_files = \
runtime/go-new.c \ runtime/go-new.c \
runtime/go-note.c \ runtime/go-note.c \
runtime/go-panic.c \ runtime/go-panic.c \
runtime/go-panic-defer.c \
runtime/go-print.c \ runtime/go-print.c \
runtime/go-rand.c \ runtime/go-rand.c \
runtime/go-rec-big.c \ runtime/go-rec-big.c \
@ -2492,7 +2490,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-new-map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-new-map.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-new.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-new.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-note.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-note.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-panic-defer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-panic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-panic.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-print.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-print.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-rand.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-rand.Plo@am__quote@
@ -2863,13 +2860,6 @@ go-panic.lo: runtime/go-panic.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-panic.lo `test -f 'runtime/go-panic.c' || echo '$(srcdir)/'`runtime/go-panic.c @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-panic.lo `test -f 'runtime/go-panic.c' || echo '$(srcdir)/'`runtime/go-panic.c
go-panic-defer.lo: runtime/go-panic-defer.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-panic-defer.lo -MD -MP -MF $(DEPDIR)/go-panic-defer.Tpo -c -o go-panic-defer.lo `test -f 'runtime/go-panic-defer.c' || echo '$(srcdir)/'`runtime/go-panic-defer.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-panic-defer.Tpo $(DEPDIR)/go-panic-defer.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-panic-defer.c' object='go-panic-defer.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-panic-defer.lo `test -f 'runtime/go-panic-defer.c' || echo '$(srcdir)/'`runtime/go-panic-defer.c
go-print.lo: runtime/go-print.c go-print.lo: runtime/go-print.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-print.lo -MD -MP -MF $(DEPDIR)/go-print.Tpo -c -o go-print.lo `test -f 'runtime/go-print.c' || echo '$(srcdir)/'`runtime/go-print.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-print.lo -MD -MP -MF $(DEPDIR)/go-print.Tpo -c -o go-print.lo `test -f 'runtime/go-print.c' || echo '$(srcdir)/'`runtime/go-print.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-print.Tpo $(DEPDIR)/go-print.Plo @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-print.Tpo $(DEPDIR)/go-print.Plo

View file

@ -6,6 +6,7 @@
#include <stddef.h> #include <stddef.h>
#include "runtime.h"
#include "go-alloc.h" #include "go-alloc.h"
#include "go-panic.h" #include "go-panic.h"
#include "go-defer.h" #include "go-defer.h"
@ -17,18 +18,14 @@ __go_defer (_Bool *frame, void (*pfn) (void *), void *arg)
{ {
struct __go_defer_stack *n; 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 = (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->__frame = frame;
n->__panic = __go_panic_defer->__panic; n->__panic = g->panic;
n->__pfn = pfn; n->__pfn = pfn;
n->__arg = arg; n->__arg = arg;
n->__retaddr = NULL; n->__retaddr = NULL;
__go_panic_defer->__defer = n; g->defer = n;
} }
/* This function is called when we want to undefer the stack. */ /* 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 void
__go_undefer (_Bool *frame) __go_undefer (_Bool *frame)
{ {
if (__go_panic_defer == NULL) while (g->defer != NULL && g->defer->__frame == frame)
return;
while (__go_panic_defer->__defer != NULL
&& __go_panic_defer->__defer->__frame == frame)
{ {
struct __go_defer_stack *d; struct __go_defer_stack *d;
void (*pfn) (void *); void (*pfn) (void *);
d = __go_panic_defer->__defer; d = g->defer;
pfn = d->__pfn; pfn = d->__pfn;
d->__pfn = NULL; d->__pfn = NULL;
if (pfn != NULL) if (pfn != NULL)
(*pfn) (d->__arg); (*pfn) (d->__arg);
__go_panic_defer->__defer = d->__next; g->defer = d->__next;
__go_free (d); __go_free (d);
/* Since we are executing a defer function here, we know we are /* Since we are executing a defer function here, we know we are
@ -69,7 +63,7 @@ __go_undefer (_Bool *frame)
_Bool _Bool
__go_set_defer_retaddr (void *retaddr) __go_set_defer_retaddr (void *retaddr)
{ {
if (__go_panic_defer != NULL && __go_panic_defer->__defer != NULL) if (g->defer != NULL)
__go_panic_defer->__defer->__retaddr = retaddr; g->defer->__retaddr = retaddr;
return 0; return 0;
} }

View file

@ -6,6 +6,7 @@
#include <stddef.h> #include <stddef.h>
#include "runtime.h"
#include "go-panic.h" #include "go-panic.h"
#include "go-defer.h" #include "go-defer.h"
@ -78,9 +79,7 @@
struct __go_empty_interface struct __go_empty_interface
__go_deferred_recover () __go_deferred_recover ()
{ {
if (__go_panic_defer == NULL if (g->defer == NULL || g->defer->__panic != g->panic)
|| __go_panic_defer->__defer == NULL
|| __go_panic_defer->__defer->__panic != __go_panic_defer->__panic)
{ {
struct __go_empty_interface ret; struct __go_empty_interface ret;

View file

@ -115,6 +115,7 @@ remove_current_thread (void *dummy __attribute__ ((unused)))
any code from here to thread exit must not assume that m is any code from here to thread exit must not assume that m is
valid. */ valid. */
m = NULL; m = NULL;
g = NULL;
i = pthread_mutex_unlock (&__go_thread_ids_lock); i = pthread_mutex_unlock (&__go_thread_ids_lock);
__go_assert (i == 0); __go_assert (i == 0);
@ -135,10 +136,11 @@ start_go_thread (void *thread_arg)
#ifdef __rtems__ #ifdef __rtems__
__wrap_rtems_task_variable_add ((void **) &m); __wrap_rtems_task_variable_add ((void **) &m);
__wrap_rtems_task_variable_add ((void **) &__go_panic_defer); __wrap_rtems_task_variable_add ((void **) &g);
#endif #endif
m = newm; m = newm;
g = m->curg;
pthread_cleanup_push (remove_current_thread, NULL); pthread_cleanup_push (remove_current_thread, NULL);
@ -230,6 +232,9 @@ __go_go (void (*pfn) (void*), void *arg)
newm->list_entry = list_entry; newm->list_entry = list_entry;
newm->curg = __go_alloc (sizeof (G));
newm->curg->m = newm;
newm->id = __sync_fetch_and_add (&mcount, 1); newm->id = __sync_fetch_and_add (&mcount, 1);
newm->fastrand = 0x49f6428aUL + newm->id; newm->fastrand = 0x49f6428aUL + newm->id;
@ -299,9 +304,6 @@ stop_for_gc (void)
} }
#endif #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 /* Tell the garbage collector that we are ready by posting to the
semaphore. */ semaphore. */
i = sem_post (&__go_thread_ready_sem); i = sem_post (&__go_thread_ready_sem);
@ -433,10 +435,6 @@ runtime_stoptheworld (void)
--c; --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. */ /* Leave with __go_thread_ids_lock held. */
} }

View file

@ -48,6 +48,10 @@ main (int argc, char **argv)
int i; int i;
struct __go_string *values; struct __go_string *values;
m = &runtime_m0;
g = &runtime_g0;
m->curg = g;
g->m = m;
runtime_mallocinit (); runtime_mallocinit ();
runtime_cpuprofinit (); runtime_cpuprofinit ();
__go_gc_goroutine_init (&argc); __go_gc_goroutine_init (&argc);

View file

@ -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;

View file

@ -41,14 +41,10 @@ __go_panic (struct __go_empty_interface arg)
{ {
struct __go_panic_stack *n; 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 = (struct __go_panic_stack *) __go_alloc (sizeof (struct __go_panic_stack));
n->__arg = arg; n->__arg = arg;
n->__next = __go_panic_defer->__panic; n->__next = g->panic;
__go_panic_defer->__panic = n; g->panic = n;
/* Run all the defer functions. */ /* Run all the defer functions. */
@ -57,7 +53,7 @@ __go_panic (struct __go_empty_interface arg)
struct __go_defer_stack *d; struct __go_defer_stack *d;
void (*pfn) (void *); void (*pfn) (void *);
d = __go_panic_defer->__defer; d = g->defer;
if (d == NULL) if (d == NULL)
break; break;
@ -73,7 +69,7 @@ __go_panic (struct __go_empty_interface arg)
/* Some defer function called recover. That means that /* Some defer function called recover. That means that
we should stop running this panic. */ we should stop running this panic. */
__go_panic_defer->__panic = n->__next; g->panic = n->__next;
__go_free (n); __go_free (n);
/* Now unwind the stack by throwing an exception. The /* Now unwind the stack by throwing an exception. The
@ -96,13 +92,13 @@ __go_panic (struct __go_empty_interface arg)
*d->__frame = 0; *d->__frame = 0;
} }
__go_panic_defer->__defer = d->__next; g->defer = d->__next;
__go_free (d); __go_free (d);
} }
/* The panic was not recovered. */ /* The panic was not recovered. */
__printpanics (__go_panic_defer->__panic); __printpanics (g->panic);
/* FIXME: We should dump a call stack here. */ /* FIXME: We should dump a call stack here. */
abort (); abort ();

View file

@ -31,36 +31,6 @@ struct __go_panic_stack
_Bool __is_foreign; _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) extern void __go_panic (struct __go_empty_interface)
__attribute__ ((noreturn)); __attribute__ ((noreturn));

View file

@ -4,6 +4,7 @@
Use of this source code is governed by a BSD-style Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file. */ license that can be found in the LICENSE file. */
#include "runtime.h"
#include "interface.h" #include "interface.h"
#include "go-panic.h" #include "go-panic.h"
#include "go-defer.h" #include "go-defer.h"
@ -21,9 +22,7 @@ __go_can_recover (const void* retaddr)
const char* ret; const char* ret;
const char* dret; const char* dret;
if (__go_panic_defer == NULL) d = g->defer;
return 0;
d = __go_panic_defer->__defer;
if (d == NULL) if (d == NULL)
return 0; 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 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 was on the top of the panic stack when this function was
deferred. */ deferred. */
if (d->__panic == __go_panic_defer->__panic) if (d->__panic == g->panic)
return 0; return 0;
/* D->__RETADDR is the address of a label immediately following the /* D->__RETADDR is the address of a label immediately following the
@ -53,9 +52,7 @@ __go_recover ()
{ {
struct __go_panic_stack *p; struct __go_panic_stack *p;
if (__go_panic_defer == NULL if (g->panic == NULL || g->panic->__was_recovered)
|| __go_panic_defer->__panic == NULL
|| __go_panic_defer->__panic->__was_recovered)
{ {
struct __go_empty_interface ret; struct __go_empty_interface ret;
@ -63,7 +60,7 @@ __go_recover ()
ret.__object = NULL; ret.__object = NULL;
return ret; return ret;
} }
p = __go_panic_defer->__panic; p = g->panic;
p->__was_recovered = 1; p->__was_recovered = 1;
return p->__arg; return p->__arg;
} }

View file

@ -13,6 +13,7 @@
#define NO_SIZE_OF_ENCODED_VALUE #define NO_SIZE_OF_ENCODED_VALUE
#include "unwind-pe.h" #include "unwind-pe.h"
#include "runtime.h"
#include "go-alloc.h" #include "go-alloc.h"
#include "go-defer.h" #include "go-defer.h"
#include "go-panic.h" #include "go-panic.h"
@ -48,12 +49,12 @@ __go_check_defer (_Bool *frame)
{ {
struct _Unwind_Exception *hdr; struct _Unwind_Exception *hdr;
if (__go_panic_defer == NULL) if (g == NULL)
{ {
/* Some other language has thrown an exception. We know there /* Some other language has thrown an exception. We know there
are no defer handlers, so there is nothing to do. */ 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; struct __go_panic_stack *n;
_Bool was_recovered; _Bool was_recovered;
@ -69,20 +70,20 @@ __go_check_defer (_Bool *frame)
n->__arg.__object = NULL; n->__arg.__object = NULL;
n->__was_recovered = 0; n->__was_recovered = 0;
n->__is_foreign = 1; n->__is_foreign = 1;
n->__next = __go_panic_defer->__panic; n->__next = g->panic;
__go_panic_defer->__panic = n; g->panic = n;
while (1) while (1)
{ {
struct __go_defer_stack *d; struct __go_defer_stack *d;
void (*pfn) (void *); void (*pfn) (void *);
d = __go_panic_defer->__defer; d = g->defer;
if (d == NULL || d->__frame != frame || d->__pfn == NULL) if (d == NULL || d->__frame != frame || d->__pfn == NULL)
break; break;
pfn = d->__pfn; pfn = d->__pfn;
__go_panic_defer->__defer = d->__next; g->defer = d->__next;
(*pfn) (d->__arg); (*pfn) (d->__arg);
@ -97,7 +98,7 @@ __go_check_defer (_Bool *frame)
} }
was_recovered = n->__was_recovered; was_recovered = n->__was_recovered;
__go_panic_defer->__panic = n->__next; g->panic = n->__next;
__go_free (n); __go_free (n);
if (was_recovered) if (was_recovered)
@ -110,17 +111,17 @@ __go_check_defer (_Bool *frame)
/* We are panicing through this function. */ /* We are panicing through this function. */
*frame = 0; *frame = 0;
} }
else if (__go_panic_defer->__defer != NULL else if (g->defer != NULL
&& __go_panic_defer->__defer->__pfn == NULL && g->defer->__pfn == NULL
&& __go_panic_defer->__defer->__frame == frame) && g->defer->__frame == frame)
{ {
struct __go_defer_stack *d; struct __go_defer_stack *d;
/* This is the defer function which called recover. Simply /* This is the defer function which called recover. Simply
return to stop the stack unwind, and let the Go code continue return to stop the stack unwind, and let the Go code continue
to execute. */ to execute. */
d = __go_panic_defer->__defer; d = g->defer;
__go_panic_defer->__defer = d->__next; g->defer = d->__next;
__go_free (d); __go_free (d);
/* We are returning from this function. */ /* 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 /* This is some other defer function. It was already run by the
call to panic, or just above. Rethrow the exception. */ 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 #ifdef LIBGO_SJLJ_EXCEPTIONS
_Unwind_SjLj_Resume_or_Rethrow (hdr); _Unwind_SjLj_Resume_or_Rethrow (hdr);
@ -163,7 +164,7 @@ __go_unwind_stack ()
sizeof hdr->exception_class); sizeof hdr->exception_class);
hdr->exception_cleanup = NULL; hdr->exception_cleanup = NULL;
__go_panic_defer->__exception = hdr; g->exception = hdr;
#ifdef __USING_SJLJ_EXCEPTIONS__ #ifdef __USING_SJLJ_EXCEPTIONS__
_Unwind_SjLj_RaiseException (hdr); _Unwind_SjLj_RaiseException (hdr);
@ -413,17 +414,17 @@ PERSONALITY_FUNCTION (int version,
return _URC_HANDLER_FOUND; return _URC_HANDLER_FOUND;
} }
/* It's possible for __go_panic_defer to be NULL here for an /* It's possible for g to be NULL here for an exception thrown by a
exception thrown by a language other than Go. */ language other than Go. */
if (__go_panic_defer == NULL) if (g == NULL)
{ {
if (!is_foreign) if (!is_foreign)
abort (); abort ();
} }
else else
{ {
__go_panic_defer->__exception = ue_header; g->exception = ue_header;
__go_panic_defer->__is_foreign = is_foreign; g->is_foreign = is_foreign;
} }
_Unwind_SetGR (context, __builtin_eh_return_data_regno (0), _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),

View file

@ -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); scan((byte*)&finq, sizeof finq);
runtime_MProf_Mark(scan); runtime_MProf_Mark(scan);

View file

@ -8,13 +8,15 @@
typedef struct Sched Sched; typedef struct Sched Sched;
M m0; G runtime_g0;
M runtime_m0;
#ifdef __rtems__ #ifdef __rtems__
#define __thread #define __thread
#endif #endif
__thread M *m = &m0; __thread G *g;
__thread M *m;
static struct { static struct {
Lock; Lock;

View file

@ -48,11 +48,15 @@ typedef unsigned int uintptr __attribute__ ((mode (pointer)));
typedef uint8 bool; typedef uint8 bool;
typedef uint8 byte; typedef uint8 byte;
typedef struct G G;
typedef struct M M; typedef struct M M;
typedef struct MCache MCache; typedef struct MCache MCache;
typedef struct FixAlloc FixAlloc; typedef struct FixAlloc FixAlloc;
typedef struct Lock Lock; 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 /* We use mutexes for locks. 6g uses futexes directly, and perhaps
someday we will do that too. */ someday we will do that too. */
@ -76,9 +80,11 @@ struct Note {
#define __thread #define __thread
#endif #endif
extern __thread G* g;
extern __thread M* m; extern __thread M* m;
extern M m0; extern M runtime_m0;
extern G runtime_g0;
#ifdef __rtems__ #ifdef __rtems__
#undef __thread #undef __thread
@ -94,8 +100,34 @@ enum
/* Structures. */ /* 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 struct M
{ {
G* curg; // current running goroutine
int32 id; int32 id;
int32 mallocing; int32 mallocing;
int32 gcing; int32 gcing;
@ -117,7 +149,6 @@ struct M
void *gc_next_segment; void *gc_next_segment;
void *gc_next_sp; void *gc_next_sp;
void *gc_initial_sp; void *gc_initial_sp;
struct __go_panic_defer_struct *gc_panic_defer;
}; };
/* Macros. */ /* Macros. */