// Copyright 2009 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 #include "config.h" #include "runtime.h" #include "array.h" #include "go-panic.h" int32 runtime_gotraceback(void) { const byte *p; p = runtime_getenv("GOTRACEBACK"); if(p == nil || p[0] == '\0') return 1; // default is on return runtime_atoi(p); } static int32 argc; static byte** argv; extern Slice os_Args __asm__ (GOSYM_PREFIX "os.Args"); extern Slice syscall_Envs __asm__ (GOSYM_PREFIX "syscall.Envs"); void (*runtime_sysargs)(int32, uint8**); void runtime_args(int32 c, byte **v) { argc = c; argv = v; if(runtime_sysargs != nil) runtime_sysargs(c, v); } byte* runtime_progname() { return argc == 0 ? nil : argv[0]; } void runtime_goargs(void) { String *s; int32 i; // for windows implementation see "os" package if(Windows) return; s = runtime_malloc(argc*sizeof s[0]); for(i=0; ifastrand; x += x; if(x & 0x80000000L) x ^= 0x88888eefUL; m->fastrand = x; return x; } static struct root_list runtime_roots = { nil, { { &syscall_Envs, sizeof syscall_Envs }, { &os_Args, sizeof os_Args }, { nil, 0 } }, }; void runtime_check(void) { __go_register_gc_roots(&runtime_roots); } int64 runtime_cputicks(void) { #if defined(__386__) || defined(__x86_64__) uint32 low, high; asm("rdtsc" : "=a" (low), "=d" (high)); return (int64)(((uint64)high << 32) | (uint64)low); #else // FIXME: implement for other processors. return 0; #endif } bool runtime_showframe(String s) { static int32 traceback = -1; if(traceback < 0) traceback = runtime_gotraceback(); return traceback > 1 || (__builtin_memchr(s.str, '.', s.len) != nil && __builtin_memcmp(s.str, "runtime.", 7) != 0); } static Lock ticksLock; static int64 ticks; int64 runtime_tickspersecond(void) { int64 res, t0, t1, c0, c1; res = (int64)runtime_atomicload64((uint64*)&ticks); if(res != 0) return ticks; runtime_lock(&ticksLock); res = ticks; if(res == 0) { t0 = runtime_nanotime(); c0 = runtime_cputicks(); runtime_usleep(100*1000); t1 = runtime_nanotime(); c1 = runtime_cputicks(); if(t1 == t0) t1++; res = (c1-c0)*1000*1000*1000/(t1-t0); if(res == 0) res++; runtime_atomicstore64((uint64*)&ticks, res); } runtime_unlock(&ticksLock); return res; } int64 runtime_pprof_runtime_cyclesPerSecond(void) __asm__ (GOSYM_PREFIX "runtime_pprof.runtime_cyclesPerSecond"); int64 runtime_pprof_runtime_cyclesPerSecond(void) { return runtime_tickspersecond(); }