runtime: Fix defer of unlock thread at program startup.
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 12 Dec 2013 20:13:58 +0000 (20:13 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 12 Dec 2013 20:13:58 +0000 (20:13 +0000)
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

libgo/runtime/go-defer.c
libgo/runtime/go-defer.h
libgo/runtime/go-panic.c
libgo/runtime/go-unwind.c
libgo/runtime/panic.c
libgo/runtime/proc.c

index fed8db385ae830172aa06ef2e101abf22d1c341b..4c61ae7db2f26aaed0030fa4cce63179d98bad21 100644 (file)
@@ -28,6 +28,7 @@ __go_defer (_Bool *frame, void (*pfn) (void *), void *arg)
   n->__arg = arg;
   n->__retaddr = NULL;
   n->__makefunc_can_recover = 0;
+  n->__free = 1;
   g->defer = n;
 }
 
@@ -59,7 +60,7 @@ __go_undefer (_Bool *frame)
         have a memory context.  Don't try to free anything in that
         case--the GC will release it later.  */
       m = runtime_m ();
-      if (m != NULL && m->mcache != NULL)
+      if (m != NULL && m->mcache != NULL && d->__free)
        __go_free (d);
 
       /* Since we are executing a defer function here, we know we are
index 3298ce9505913c456fd913c7dfeb67ea90d3c584..d110a8766e3cdb26f53a6cbc6487c2c2082b9060 100644 (file)
@@ -40,4 +40,8 @@ struct __go_defer_stack
      function will be somewhere in libffi, so __retaddr is not
      useful.  */
   _Bool __makefunc_can_recover;
+
+  /* Set to true if this defer stack entry should be freed when
+     done.  */
+  _Bool __free;
 };
index 7e284eeaa3d01eedd6ecb2f1cc46d284ed971e02..0cacbcd91cbb511b5e5a869140f76f345273b656 100644 (file)
@@ -102,7 +102,7 @@ __go_panic (struct __go_empty_interface arg)
         have a memory context.  Don't try to free anything in that
         case--the GC will release it later.  */
       m = runtime_m ();
-      if (m != NULL && m->mcache != NULL)
+      if (m != NULL && m->mcache != NULL && d->__free)
        __go_free (d);
     }
 
index c669a3ce889f543cc157069e5568e5afac384126..04b0a28607aa4d0ccdcef7df6f87e60349777290 100644 (file)
@@ -80,6 +80,7 @@ __go_check_defer (_Bool *frame)
        {
          struct __go_defer_stack *d;
          void (*pfn) (void *);
+         M *m;
 
          d = g->defer;
          if (d == NULL || d->__frame != frame || d->__pfn == NULL)
@@ -90,7 +91,9 @@ __go_check_defer (_Bool *frame)
 
          (*pfn) (d->__arg);
 
-         __go_free (d);
+         m = runtime_m ();
+         if (m != NULL && m->mcache != NULL && d->__free)
+           __go_free (d);
 
          if (n->__was_recovered)
            {
@@ -119,13 +122,17 @@ __go_check_defer (_Bool *frame)
           && g->defer->__frame == frame)
     {
       struct __go_defer_stack *d;
+      M *m;
 
       /* This is the defer function which called recover.  Simply
         return to stop the stack unwind, and let the Go code continue
         to execute.  */
       d = g->defer;
       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.  */
       *frame = 1;
index 7a8d95b1ade8a16af6cbb63ee267b33d4232eb1a..8fe321f6af2de675268a7ee3b246dd82db406d4e 100644 (file)
@@ -28,7 +28,8 @@ rundefer(void)
                d->__pfn = nil;
                if (pfn != nil)
                        (*pfn)(d->__arg);
-               runtime_free(d);
+               if (d->__free)
+                 runtime_free(d);
        }
 }
 
index 0d0127b6c75acc225aef96ff8a31034a42212efe..8f54e51df35e0bc95fe62d5055547d649245e030 100644 (file)
@@ -541,6 +541,7 @@ runtime_main(void* dummy __attribute__((unused)))
        d.__retaddr = nil;
        d.__makefunc_can_recover = 0;
        d.__frame = &frame;
+       d.__free = 0;
        g->defer = &d;
 
        if(m != &runtime_m0)