]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: cache gotraceback setting
authorRuss Cox <rsc@golang.org>
Wed, 9 Apr 2014 02:35:41 +0000 (22:35 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 9 Apr 2014 02:35:41 +0000 (22:35 -0400)
On Plan 9 gotraceback calls getenv calls malloc, and we gotraceback
on every call to gentraceback, which happens during garbage collection.
Honestly I don't even know how this works on Plan 9.
I suspect it does not, and that we are getting by because
no one has tried to run with $GOTRACEBACK set at all.

This will speed up all the other systems by epsilon, since they
won't call getenv and atoi repeatedly.

LGTM=bradfitz
R=golang-codereviews, bradfitz, 0intro
CC=golang-codereviews
https://golang.org/cl/85430046

src/pkg/runtime/proc.c
src/pkg/runtime/runtime.c

index 2ab54be70c8f3b3c72dbc46f86ca0e08a622db31..6b5c031c8748c596e37b4ed49a47450c35d90fe7 100644 (file)
@@ -155,6 +155,10 @@ runtime·schedinit(void)
        // in a fault during a garbage collection, it will not
        // need to allocated memory.
        runtime·newErrorCString(0, &i);
+       
+       // Initialize the cached gotraceback value, since
+       // gotraceback calls getenv, which mallocs on Plan 9.
+       runtime·gotraceback(nil);
 
        runtime·goargs();
        runtime·goenvs();
index d995bf97ae95159207ef4e1b60c1285ce17391c2..725c6d838e55dd5e4a4566a7f2cfd85d6242e652 100644 (file)
@@ -20,22 +20,35 @@ enum {
 int32
 runtime·gotraceback(bool *crash)
 {
+       // Keep a cached value to make gotraceback fast,
+       // since we call it on every call to gentraceback.
+       // The cached value is a uint32 in which the low bit
+       // is the "crash" setting and the top 31 bits are the
+       // gotraceback value.
+       static uint32 cache = ~(uint32)0;
        byte *p;
+       uint32 x;
 
        if(crash != nil)
                *crash = false;
-       p = runtime·getenv("GOTRACEBACK");
-       if(p == nil || p[0] == '\0') {
-               if(m->traceback != 0)
-                       return m->traceback;
-               return 1;       // default is on
-       }
-       if(runtime·strcmp(p, (byte*)"crash") == 0) {
-               if(crash != nil)
-                       *crash = true;
-               return 2;       // extra information
+       if(m->traceback != 0)
+               return m->traceback;
+       x = runtime·atomicload(&cache);
+       if(x == ~(uint32)0) {
+               p = runtime·getenv("GOTRACEBACK");
+               if(p == nil)
+                       p = (byte*)"";
+               if(p[0] == '\0')
+                       x = 1<<1;
+               else if(runtime·strcmp(p, (byte*)"crash") == 0)
+                       x = (2<<1) | 1;
+               else
+                       x = runtime·atoi(p)<<1;        
+               runtime·atomicstore(&cache, x);
        }
-       return runtime·atoi(p);
+       if(crash != nil)
+               *crash = x&1;
+       return x>>1;
 }
 
 int32