Introduce G structure and thread-local global g.
From-SVN: r181301
This commit is contained in:
parent
292b44341c
commit
34277c5228
14 changed files with 102 additions and 133 deletions
|
@ -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 \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
|
|
@ -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 ();
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue