Commit 1635eab3 by Ian Lance Taylor

runtime: Fix defer of unlock thread at program startup.

Don't free stack allocated defer block.  Also ensure we have a
Go context in a few more places before freeing the block.

From-SVN: r205940
parent 96d91784
...@@ -28,6 +28,7 @@ __go_defer (_Bool *frame, void (*pfn) (void *), void *arg) ...@@ -28,6 +28,7 @@ __go_defer (_Bool *frame, void (*pfn) (void *), void *arg)
n->__arg = arg; n->__arg = arg;
n->__retaddr = NULL; n->__retaddr = NULL;
n->__makefunc_can_recover = 0; n->__makefunc_can_recover = 0;
n->__free = 1;
g->defer = n; g->defer = n;
} }
...@@ -59,7 +60,7 @@ __go_undefer (_Bool *frame) ...@@ -59,7 +60,7 @@ __go_undefer (_Bool *frame)
have a memory context. Don't try to free anything in that have a memory context. Don't try to free anything in that
case--the GC will release it later. */ case--the GC will release it later. */
m = runtime_m (); m = runtime_m ();
if (m != NULL && m->mcache != NULL) if (m != NULL && m->mcache != NULL && d->__free)
__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
......
...@@ -40,4 +40,8 @@ struct __go_defer_stack ...@@ -40,4 +40,8 @@ struct __go_defer_stack
function will be somewhere in libffi, so __retaddr is not function will be somewhere in libffi, so __retaddr is not
useful. */ useful. */
_Bool __makefunc_can_recover; _Bool __makefunc_can_recover;
/* Set to true if this defer stack entry should be freed when
done. */
_Bool __free;
}; };
...@@ -102,7 +102,7 @@ __go_panic (struct __go_empty_interface arg) ...@@ -102,7 +102,7 @@ __go_panic (struct __go_empty_interface arg)
have a memory context. Don't try to free anything in that have a memory context. Don't try to free anything in that
case--the GC will release it later. */ case--the GC will release it later. */
m = runtime_m (); m = runtime_m ();
if (m != NULL && m->mcache != NULL) if (m != NULL && m->mcache != NULL && d->__free)
__go_free (d); __go_free (d);
} }
......
...@@ -80,6 +80,7 @@ __go_check_defer (_Bool *frame) ...@@ -80,6 +80,7 @@ __go_check_defer (_Bool *frame)
{ {
struct __go_defer_stack *d; struct __go_defer_stack *d;
void (*pfn) (void *); void (*pfn) (void *);
M *m;
d = g->defer; d = g->defer;
if (d == NULL || d->__frame != frame || d->__pfn == NULL) if (d == NULL || d->__frame != frame || d->__pfn == NULL)
...@@ -90,7 +91,9 @@ __go_check_defer (_Bool *frame) ...@@ -90,7 +91,9 @@ __go_check_defer (_Bool *frame)
(*pfn) (d->__arg); (*pfn) (d->__arg);
__go_free (d); m = runtime_m ();
if (m != NULL && m->mcache != NULL && d->__free)
__go_free (d);
if (n->__was_recovered) if (n->__was_recovered)
{ {
...@@ -119,13 +122,17 @@ __go_check_defer (_Bool *frame) ...@@ -119,13 +122,17 @@ __go_check_defer (_Bool *frame)
&& g->defer->__frame == frame) && g->defer->__frame == frame)
{ {
struct __go_defer_stack *d; struct __go_defer_stack *d;
M *m;
/* 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 = g->defer; d = g->defer;
g->defer = d->__next; g->defer = d->__next;
__go_free (d);
m = runtime_m ();
if (m != NULL && m->mcache != NULL && d->__free)
__go_free (d);
/* We are returning from this function. */ /* We are returning from this function. */
*frame = 1; *frame = 1;
......
...@@ -28,7 +28,8 @@ rundefer(void) ...@@ -28,7 +28,8 @@ rundefer(void)
d->__pfn = nil; d->__pfn = nil;
if (pfn != nil) if (pfn != nil)
(*pfn)(d->__arg); (*pfn)(d->__arg);
runtime_free(d); if (d->__free)
runtime_free(d);
} }
} }
......
...@@ -541,6 +541,7 @@ runtime_main(void* dummy __attribute__((unused))) ...@@ -541,6 +541,7 @@ runtime_main(void* dummy __attribute__((unused)))
d.__retaddr = nil; d.__retaddr = nil;
d.__makefunc_can_recover = 0; d.__makefunc_can_recover = 0;
d.__frame = &frame; d.__frame = &frame;
d.__free = 0;
g->defer = &d; g->defer = &d;
if(m != &runtime_m0) if(m != &runtime_m0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment