* testsuite/libgomp.c/examples-4/e.53.5.c: Require
[official-gcc.git] / libgo / runtime / runtime.c
blob496e77b75c5510913eaa392a4a5d5af0140cbe8c
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 <signal.h>
6 #include <unistd.h>
8 #include "config.h"
10 #include "runtime.h"
11 #include "arch.h"
12 #include "array.h"
14 enum {
15 maxround = sizeof(uintptr),
18 // Keep a cached value to make gotraceback fast,
19 // since we call it on every call to gentraceback.
20 // The cached value is a uint32 in which the low bit
21 // is the "crash" setting and the top 31 bits are the
22 // gotraceback value.
23 static uint32 traceback_cache = ~(uint32)0;
25 // The GOTRACEBACK environment variable controls the
26 // behavior of a Go program that is crashing and exiting.
27 // GOTRACEBACK=0 suppress all tracebacks
28 // GOTRACEBACK=1 default behavior - show tracebacks but exclude runtime frames
29 // GOTRACEBACK=2 show tracebacks including runtime frames
30 // GOTRACEBACK=crash show tracebacks including runtime frames, then crash (core dump etc)
31 int32
32 runtime_gotraceback(bool *crash)
34 const byte *p;
35 uint32 x;
37 if(crash != nil)
38 *crash = false;
39 if(runtime_m()->traceback != 0)
40 return runtime_m()->traceback;
41 x = runtime_atomicload(&traceback_cache);
42 if(x == ~(uint32)0) {
43 p = runtime_getenv("GOTRACEBACK");
44 if(p == nil)
45 p = (const byte*)"";
46 if(p[0] == '\0')
47 x = 1<<1;
48 else if(runtime_strcmp((const char *)p, "crash") == 0)
49 x = (2<<1) | 1;
50 else
51 x = runtime_atoi(p)<<1;
52 runtime_atomicstore(&traceback_cache, x);
54 if(crash != nil)
55 *crash = x&1;
56 return x>>1;
59 static int32 argc;
60 static byte** argv;
62 extern Slice os_Args __asm__ (GOSYM_PREFIX "os.Args");
63 extern Slice syscall_Envs __asm__ (GOSYM_PREFIX "syscall.Envs");
65 void (*runtime_sysargs)(int32, uint8**);
67 void
68 runtime_args(int32 c, byte **v)
70 argc = c;
71 argv = v;
72 if(runtime_sysargs != nil)
73 runtime_sysargs(c, v);
76 byte*
77 runtime_progname()
79 return argc == 0 ? nil : argv[0];
82 void
83 runtime_goargs(void)
85 String *s;
86 int32 i;
88 // for windows implementation see "os" package
89 if(Windows)
90 return;
92 s = runtime_malloc(argc*sizeof s[0]);
93 for(i=0; i<argc; i++)
94 s[i] = runtime_gostringnocopy((const byte*)argv[i]);
95 os_Args.__values = (void*)s;
96 os_Args.__count = argc;
97 os_Args.__capacity = argc;
100 void
101 runtime_goenvs_unix(void)
103 String *s;
104 int32 i, n;
106 for(n=0; argv[argc+1+n] != 0; n++)
109 s = runtime_malloc(n*sizeof s[0]);
110 for(i=0; i<n; i++)
111 s[i] = runtime_gostringnocopy(argv[argc+1+i]);
112 syscall_Envs.__values = (void*)s;
113 syscall_Envs.__count = n;
114 syscall_Envs.__capacity = n;
117 int32
118 runtime_atoi(const byte *p)
120 int32 n;
122 n = 0;
123 while('0' <= *p && *p <= '9')
124 n = n*10 + *p++ - '0';
125 return n;
128 static struct root_list runtime_roots =
129 { nil,
130 { { &syscall_Envs, sizeof syscall_Envs },
131 { &os_Args, sizeof os_Args },
132 { nil, 0 } },
135 static void
136 TestAtomic64(void)
138 uint64 z64, x64;
140 z64 = 42;
141 x64 = 0;
142 PREFETCH(&z64);
143 if(runtime_cas64(&z64, x64, 1))
144 runtime_throw("cas64 failed");
145 if(x64 != 0)
146 runtime_throw("cas64 failed");
147 x64 = 42;
148 if(!runtime_cas64(&z64, x64, 1))
149 runtime_throw("cas64 failed");
150 if(x64 != 42 || z64 != 1)
151 runtime_throw("cas64 failed");
152 if(runtime_atomicload64(&z64) != 1)
153 runtime_throw("load64 failed");
154 runtime_atomicstore64(&z64, (1ull<<40)+1);
155 if(runtime_atomicload64(&z64) != (1ull<<40)+1)
156 runtime_throw("store64 failed");
157 if(runtime_xadd64(&z64, (1ull<<40)+1) != (2ull<<40)+2)
158 runtime_throw("xadd64 failed");
159 if(runtime_atomicload64(&z64) != (2ull<<40)+2)
160 runtime_throw("xadd64 failed");
161 if(runtime_xchg64(&z64, (3ull<<40)+3) != (2ull<<40)+2)
162 runtime_throw("xchg64 failed");
163 if(runtime_atomicload64(&z64) != (3ull<<40)+3)
164 runtime_throw("xchg64 failed");
167 void
168 runtime_check(void)
170 __go_register_gc_roots(&runtime_roots);
172 TestAtomic64();
175 uint32
176 runtime_fastrand1(void)
178 M *m;
179 uint32 x;
181 m = runtime_m();
182 x = m->fastrand;
183 x += x;
184 if(x & 0x80000000L)
185 x ^= 0x88888eefUL;
186 m->fastrand = x;
187 return x;
190 int64
191 runtime_cputicks(void)
193 #if defined(__386__) || defined(__x86_64__)
194 uint32 low, high;
195 asm("rdtsc" : "=a" (low), "=d" (high));
196 return (int64)(((uint64)high << 32) | (uint64)low);
197 #elif defined (__s390__) || defined (__s390x__)
198 uint64 clock = 0;
199 /* stckf may not write the return variable in case of a clock error, so make
200 it read-write to prevent that the initialisation is optimised out.
201 Note: Targets below z9-109 will crash when executing store clock fast, i.e.
202 we don't support Go for machines older than that. */
203 asm volatile(".insn s,0xb27c0000,%0" /* stckf */ : "+Q" (clock) : : "cc" );
204 return (int64)clock;
205 #else
206 // FIXME: implement for other processors.
207 return 0;
208 #endif
211 bool
212 runtime_showframe(String s, bool current)
214 static int32 traceback = -1;
216 if(current && runtime_m()->throwing > 0)
217 return 1;
218 if(traceback < 0)
219 traceback = runtime_gotraceback(nil);
220 return traceback > 1 || (__builtin_memchr(s.str, '.', s.len) != nil && __builtin_memcmp(s.str, "runtime.", 7) != 0);
223 static Lock ticksLock;
224 static int64 ticks;
226 int64
227 runtime_tickspersecond(void)
229 int64 res, t0, t1, c0, c1;
231 res = (int64)runtime_atomicload64((uint64*)&ticks);
232 if(res != 0)
233 return ticks;
234 runtime_lock(&ticksLock);
235 res = ticks;
236 if(res == 0) {
237 t0 = runtime_nanotime();
238 c0 = runtime_cputicks();
239 runtime_usleep(100*1000);
240 t1 = runtime_nanotime();
241 c1 = runtime_cputicks();
242 if(t1 == t0)
243 t1++;
244 res = (c1-c0)*1000*1000*1000/(t1-t0);
245 if(res == 0)
246 res++;
247 runtime_atomicstore64((uint64*)&ticks, res);
249 runtime_unlock(&ticksLock);
250 return res;
253 // Called to initialize a new m (including the bootstrap m).
254 // Called on the parent thread (main thread in case of bootstrap), can allocate memory.
255 void
256 runtime_mpreinit(M *mp)
258 mp->gsignal = runtime_malg(32*1024, &mp->gsignalstack, &mp->gsignalstacksize); // OS X wants >=8K, Linux >=2K
261 // Called to initialize a new m (including the bootstrap m).
262 // Called on the new thread, can not allocate memory.
263 void
264 runtime_minit(void)
266 M* m;
267 sigset_t sigs;
269 // Initialize signal handling.
270 m = runtime_m();
271 runtime_signalstack(m->gsignalstack, m->gsignalstacksize);
272 if (sigemptyset(&sigs) != 0)
273 runtime_throw("sigemptyset");
274 pthread_sigmask(SIG_SETMASK, &sigs, nil);
277 // Called from dropm to undo the effect of an minit.
278 void
279 runtime_unminit(void)
281 runtime_signalstack(nil, 0);
285 void
286 runtime_signalstack(byte *p, int32 n)
288 stack_t st;
290 st.ss_sp = p;
291 st.ss_size = n;
292 st.ss_flags = 0;
293 if(p == nil)
294 st.ss_flags = SS_DISABLE;
295 if(sigaltstack(&st, nil) < 0)
296 *(int *)0xf1 = 0xf1;
299 DebugVars runtime_debug;
301 static struct {
302 const char* name;
303 int32* value;
304 } dbgvar[] = {
305 {"allocfreetrace", &runtime_debug.allocfreetrace},
306 {"efence", &runtime_debug.efence},
307 {"gctrace", &runtime_debug.gctrace},
308 {"gcdead", &runtime_debug.gcdead},
309 {"scheddetail", &runtime_debug.scheddetail},
310 {"schedtrace", &runtime_debug.schedtrace},
313 void
314 runtime_parsedebugvars(void)
316 const byte *p;
317 intgo i, n;
318 bool tmp;
320 // gotraceback caches the GOTRACEBACK setting in traceback_cache.
321 // gotraceback can be called before the environment is available.
322 // traceback_cache must be reset after the environment is made
323 // available, in order for the environment variable to take effect.
324 // The code is fixed differently in Go 1.4.
325 // This is a limited fix for Go 1.3.3.
326 traceback_cache = ~(uint32)0;
327 runtime_gotraceback(&tmp);
329 p = runtime_getenv("GODEBUG");
330 if(p == nil)
331 return;
332 for(;;) {
333 for(i=0; i<(intgo)nelem(dbgvar); i++) {
334 n = runtime_findnull((const byte*)dbgvar[i].name);
335 if(runtime_mcmp(p, dbgvar[i].name, n) == 0 && p[n] == '=')
336 *dbgvar[i].value = runtime_atoi(p+n+1);
338 p = (const byte *)runtime_strstr((const char *)p, ",");
339 if(p == nil)
340 break;
341 p++;
345 // Poor mans 64-bit division.
346 // This is a very special function, do not use it if you are not sure what you are doing.
347 // int64 division is lowered into _divv() call on 386, which does not fit into nosplit functions.
348 // Handles overflow in a time-specific manner.
349 int32
350 runtime_timediv(int64 v, int32 div, int32 *rem)
352 int32 res, bit;
354 if(v >= (int64)div*0x7fffffffLL) {
355 if(rem != nil)
356 *rem = 0;
357 return 0x7fffffff;
359 res = 0;
360 for(bit = 30; bit >= 0; bit--) {
361 if(v >= ((int64)div<<bit)) {
362 v = v - ((int64)div<<bit);
363 res += 1<<bit;
366 if(rem != nil)
367 *rem = v;
368 return res;
371 // Setting the max stack size doesn't really do anything for gccgo.
373 uintptr runtime_maxstacksize = 1<<20; // enough until runtime.main sets it for real
375 void memclrBytes(Slice)
376 __asm__ (GOSYM_PREFIX "runtime.memclrBytes");
378 void
379 memclrBytes(Slice s)
381 runtime_memclr(s.__values, s.__count);