diff options
| author | Russ Cox <rsc@golang.org> | 2014-04-08 22:35:41 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2014-04-08 22:35:41 -0400 |
| commit | 5556bfa9c736f63ae18ec0ab8ef9b6a986e32ef3 (patch) | |
| tree | db94514c23e3f92f702bfd5471c828018d5c0457 /src/pkg/runtime/runtime.c | |
| parent | b3a33a654d2f640f3b6c7856ea742c23f6c49d1c (diff) | |
| download | go-5556bfa9c736f63ae18ec0ab8ef9b6a986e32ef3.tar.xz | |
runtime: cache gotraceback setting
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
Diffstat (limited to 'src/pkg/runtime/runtime.c')
| -rw-r--r-- | src/pkg/runtime/runtime.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/src/pkg/runtime/runtime.c b/src/pkg/runtime/runtime.c index d995bf97ae..725c6d838e 100644 --- a/src/pkg/runtime/runtime.c +++ b/src/pkg/runtime/runtime.c @@ -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 |
