* const-uniq-1.c: Expand regex to match AIX XCOFF labels.
[official-gcc.git] / libgo / runtime / runtime.c
blob3d4865a001a34d63d8363ba1c7a2ec4a2d9f8817
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 #include <unistd.h>
7 #include "config.h"
9 #include "runtime.h"
10 #include "array.h"
11 #include "go-panic.h"
13 int32
14 runtime_gotraceback(void)
16 const byte *p;
18 p = runtime_getenv("GOTRACEBACK");
19 if(p == nil || p[0] == '\0')
20 return 1; // default is on
21 return runtime_atoi(p);
24 static int32 argc;
25 static byte** argv;
27 extern Slice os_Args asm ("os.Args");
28 extern Slice syscall_Envs asm ("syscall.Envs");
30 void (*runtime_sysargs)(int32, uint8**);
32 void
33 runtime_args(int32 c, byte **v)
35 argc = c;
36 argv = v;
37 if(runtime_sysargs != nil)
38 runtime_sysargs(c, v);
41 byte*
42 runtime_progname()
44 return argc == 0 ? nil : argv[0];
47 void
48 runtime_goargs(void)
50 String *s;
51 int32 i;
53 // for windows implementation see "os" package
54 if(Windows)
55 return;
57 s = runtime_malloc(argc*sizeof s[0]);
58 for(i=0; i<argc; i++)
59 s[i] = runtime_gostringnocopy((const byte*)argv[i]);
60 os_Args.__values = (void*)s;
61 os_Args.__count = argc;
62 os_Args.__capacity = argc;
65 void
66 runtime_goenvs_unix(void)
68 String *s;
69 int32 i, n;
71 for(n=0; argv[argc+1+n] != 0; n++)
74 s = runtime_malloc(n*sizeof s[0]);
75 for(i=0; i<n; i++)
76 s[i] = runtime_gostringnocopy(argv[argc+1+i]);
77 syscall_Envs.__values = (void*)s;
78 syscall_Envs.__count = n;
79 syscall_Envs.__capacity = n;
82 const byte*
83 runtime_getenv(const char *s)
85 int32 i, j, len;
86 const byte *v, *bs;
87 String* envv;
88 int32 envc;
90 bs = (const byte*)s;
91 len = runtime_findnull(bs);
92 envv = (String*)syscall_Envs.__values;
93 envc = syscall_Envs.__count;
94 for(i=0; i<envc; i++){
95 if(envv[i].len <= len)
96 continue;
97 v = (const byte*)envv[i].str;
98 for(j=0; j<len; j++)
99 if(bs[j] != v[j])
100 goto nomatch;
101 if(v[len] != '=')
102 goto nomatch;
103 return v+len+1;
104 nomatch:;
106 return nil;
109 int32
110 runtime_atoi(const byte *p)
112 int32 n;
114 n = 0;
115 while('0' <= *p && *p <= '9')
116 n = n*10 + *p++ - '0';
117 return n;
120 uint32
121 runtime_fastrand1(void)
123 M *m;
124 uint32 x;
126 m = runtime_m();
127 x = m->fastrand;
128 x += x;
129 if(x & 0x80000000L)
130 x ^= 0x88888eefUL;
131 m->fastrand = x;
132 return x;
135 static struct root_list runtime_roots =
136 { nil,
137 { { &syscall_Envs, sizeof syscall_Envs },
138 { &os_Args, sizeof os_Args },
139 { nil, 0 } },
142 void
143 runtime_check(void)
145 __go_register_gc_roots(&runtime_roots);
148 int64
149 runtime_cputicks(void)
151 #if defined(__386__) || defined(__x86_64__)
152 uint32 low, high;
153 asm("rdtsc" : "=a" (low), "=d" (high));
154 return (int64)(((uint64)high << 32) | (uint64)low);
155 #else
156 // FIXME: implement for other processors.
157 return 0;
158 #endif
161 bool
162 runtime_showframe(const unsigned char *s)
164 static int32 traceback = -1;
166 if(traceback < 0)
167 traceback = runtime_gotraceback();
168 return traceback > 1 || (s != nil && __builtin_strchr((const char*)s, '.') != nil && __builtin_memcmp(s, "runtime.", 7) != 0);
171 static Lock ticksLock;
172 static int64 ticks;
174 int64
175 runtime_tickspersecond(void)
177 int64 res, t0, t1, c0, c1;
179 res = (int64)runtime_atomicload64((uint64*)&ticks);
180 if(res != 0)
181 return ticks;
182 runtime_lock(&ticksLock);
183 res = ticks;
184 if(res == 0) {
185 t0 = runtime_nanotime();
186 c0 = runtime_cputicks();
187 runtime_usleep(100*1000);
188 t1 = runtime_nanotime();
189 c1 = runtime_cputicks();
190 if(t1 == t0)
191 t1++;
192 res = (c1-c0)*1000*1000*1000/(t1-t0);
193 if(res == 0)
194 res++;
195 runtime_atomicstore64((uint64*)&ticks, res);
197 runtime_unlock(&ticksLock);
198 return res;
201 int64 runtime_pprof_runtime_cyclesPerSecond(void)
202 asm("runtime_pprof.runtime_cyclesPerSecond");
204 int64
205 runtime_pprof_runtime_cyclesPerSecond(void)
207 return runtime_tickspersecond();