rs6000.c: Delete unnecessary forward declarations.
[official-gcc.git] / libgo / runtime / runtime.c
blob3c8d76225fc7a5d98944df0eee1d6804487d55cd
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 "runtime.h"
8 #include "array.h"
9 #include "go-panic.h"
10 #include "go-string.h"
12 uint32 runtime_panicking;
14 int32
15 runtime_gotraceback(void)
17 const byte *p;
19 p = runtime_getenv("GOTRACEBACK");
20 if(p == nil || p[0] == '\0')
21 return 1; // default is on
22 return runtime_atoi(p);
25 static Lock paniclk;
27 void
28 runtime_startpanic(void)
30 M *m;
32 m = runtime_m();
33 if(m->dying) {
34 runtime_printf("panic during panic\n");
35 runtime_exit(3);
37 m->dying = 1;
38 runtime_xadd(&runtime_panicking, 1);
39 runtime_lock(&paniclk);
42 void
43 runtime_dopanic(int32 unused __attribute__ ((unused)))
45 G* g;
46 static bool didothers;
48 g = runtime_g();
49 if(g->sig != 0)
50 runtime_printf("[signal %x code=%p addr=%p]\n",
51 g->sig, (void*)(g->sigcode0), (void*)(g->sigcode1));
53 if(runtime_gotraceback()){
54 if(g != runtime_m()->g0) {
55 runtime_printf("\n");
56 runtime_goroutineheader(g);
57 runtime_traceback();
58 runtime_goroutinetrailer(g);
60 if(!didothers) {
61 didothers = true;
62 runtime_tracebackothers(g);
66 runtime_unlock(&paniclk);
67 if(runtime_xadd(&runtime_panicking, -1) != 0) {
68 // Some other m is panicking too.
69 // Let it print what it needs to print.
70 // Wait forever without chewing up cpu.
71 // It will exit when it's done.
72 static Lock deadlock;
73 runtime_lock(&deadlock);
74 runtime_lock(&deadlock);
77 runtime_exit(2);
80 void
81 runtime_throw(const char *s)
83 runtime_startpanic();
84 runtime_printf("throw: %s\n", s);
85 runtime_dopanic(0);
86 *(int32*)0 = 0; // not reached
87 runtime_exit(1); // even more not reached
90 void
91 runtime_panicstring(const char *s)
93 Eface err;
95 if(runtime_m()->gcing) {
96 runtime_printf("panic: %s\n", s);
97 runtime_throw("panic during gc");
99 runtime_newErrorString(runtime_gostringnocopy((const byte*)s), &err);
100 runtime_panic(err);
103 static int32 argc;
104 static byte** argv;
106 extern Slice os_Args asm ("os.Args");
107 extern Slice syscall_Envs asm ("syscall.Envs");
109 void
110 runtime_args(int32 c, byte **v)
112 argc = c;
113 argv = v;
116 void
117 runtime_goargs(void)
119 String *s;
120 int32 i;
122 // for windows implementation see "os" package
123 if(Windows)
124 return;
126 s = runtime_malloc(argc*sizeof s[0]);
127 for(i=0; i<argc; i++)
128 s[i] = runtime_gostringnocopy((const byte*)argv[i]);
129 os_Args.__values = (void*)s;
130 os_Args.__count = argc;
131 os_Args.__capacity = argc;
134 void
135 runtime_goenvs_unix(void)
137 String *s;
138 int32 i, n;
140 for(n=0; argv[argc+1+n] != 0; n++)
143 s = runtime_malloc(n*sizeof s[0]);
144 for(i=0; i<n; i++)
145 s[i] = runtime_gostringnocopy(argv[argc+1+i]);
146 syscall_Envs.__values = (void*)s;
147 syscall_Envs.__count = n;
148 syscall_Envs.__capacity = n;
151 const byte*
152 runtime_getenv(const char *s)
154 int32 i, j, len;
155 const byte *v, *bs;
156 String* envv;
157 int32 envc;
159 bs = (const byte*)s;
160 len = runtime_findnull(bs);
161 envv = (String*)syscall_Envs.__values;
162 envc = syscall_Envs.__count;
163 for(i=0; i<envc; i++){
164 if(envv[i].__length <= len)
165 continue;
166 v = (const byte*)envv[i].__data;
167 for(j=0; j<len; j++)
168 if(bs[j] != v[j])
169 goto nomatch;
170 if(v[len] != '=')
171 goto nomatch;
172 return v+len+1;
173 nomatch:;
175 return nil;
178 int32
179 runtime_atoi(const byte *p)
181 int32 n;
183 n = 0;
184 while('0' <= *p && *p <= '9')
185 n = n*10 + *p++ - '0';
186 return n;
189 uint32
190 runtime_fastrand1(void)
192 M *m;
193 uint32 x;
195 m = runtime_m();
196 x = m->fastrand;
197 x += x;
198 if(x & 0x80000000L)
199 x ^= 0x88888eefUL;
200 m->fastrand = x;
201 return x;
204 static struct root_list runtime_roots =
205 { nil,
206 { { &syscall_Envs, sizeof syscall_Envs },
207 { &os_Args, sizeof os_Args },
208 { nil, 0 } },
211 void
212 runtime_check(void)
214 __go_register_gc_roots(&runtime_roots);
217 int64
218 runtime_cputicks(void)
220 #if defined(__386__) || defined(__x86_64__)
221 uint32 low, high;
222 asm("rdtsc" : "=a" (low), "=d" (high));
223 return (int64)(((uint64)high << 32) | (uint64)low);
224 #else
225 // FIXME: implement for other processors.
226 return 0;
227 #endif
230 bool
231 runtime_showframe(const unsigned char *s)
233 static int32 traceback = -1;
235 if(traceback < 0)
236 traceback = runtime_gotraceback();
237 return traceback > 1 || (__builtin_strchr((const char*)s, '.') != nil && __builtin_memcmp(s, "runtime.", 7) != 0);