2012-01-13 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / libgo / runtime / runtime.c
blobec96f5b615f711247bf2107cb52e8b3dc8df828c
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 static Lock paniclk;
16 void
17 runtime_startpanic(void)
19 M *m;
21 m = runtime_m();
22 if(m->dying) {
23 runtime_printf("panic during panic\n");
24 runtime_exit(3);
26 m->dying = 1;
27 runtime_xadd(&runtime_panicking, 1);
28 runtime_lock(&paniclk);
31 void
32 runtime_dopanic(int32 unused __attribute__ ((unused)))
35 static bool didothers;
37 if(g->sig != 0)
38 runtime_printf("[signal %x code=%p addr=%p pc=%p]\n",
39 g->sig, g->sigcode0, g->sigcode1, g->sigpc);
41 if(runtime_gotraceback()){
42 if(!didothers) {
43 didothers = true;
44 runtime_tracebackothers(g);
49 runtime_unlock(&paniclk);
50 if(runtime_xadd(&runtime_panicking, -1) != 0) {
51 // Some other m is panicking too.
52 // Let it print what it needs to print.
53 // Wait forever without chewing up cpu.
54 // It will exit when it's done.
55 static Lock deadlock;
56 runtime_lock(&deadlock);
57 runtime_lock(&deadlock);
60 runtime_exit(2);
63 void
64 runtime_throw(const char *s)
66 runtime_startpanic();
67 runtime_printf("throw: %s\n", s);
68 runtime_dopanic(0);
69 *(int32*)0 = 0; // not reached
70 runtime_exit(1); // even more not reached
73 void
74 runtime_panicstring(const char *s)
76 Eface err;
78 if(runtime_m()->gcing) {
79 runtime_printf("panic: %s\n", s);
80 runtime_throw("panic during gc");
82 runtime_newErrorString(runtime_gostringnocopy((const byte*)s), &err);
83 runtime_panic(err);
86 static int32 argc;
87 static byte** argv;
89 extern Slice os_Args asm ("libgo_os.os.Args");
90 extern Slice syscall_Envs asm ("libgo_syscall.syscall.Envs");
92 void
93 runtime_args(int32 c, byte **v)
95 argc = c;
96 argv = v;
99 void
100 runtime_goargs(void)
102 String *s;
103 int32 i;
105 // for windows implementation see "os" package
106 if(Windows)
107 return;
109 s = runtime_malloc(argc*sizeof s[0]);
110 for(i=0; i<argc; i++)
111 s[i] = runtime_gostringnocopy((const byte*)argv[i]);
112 os_Args.__values = (void*)s;
113 os_Args.__count = argc;
114 os_Args.__capacity = argc;
117 void
118 runtime_goenvs(void)
120 String *s;
121 int32 i, n;
123 for(n=0; argv[argc+1+n] != 0; n++)
126 s = runtime_malloc(n*sizeof s[0]);
127 for(i=0; i<n; i++)
128 s[i] = runtime_gostringnocopy(argv[argc+1+i]);
129 syscall_Envs.__values = (void*)s;
130 syscall_Envs.__count = n;
131 syscall_Envs.__capacity = n;
134 const byte*
135 runtime_getenv(const char *s)
137 int32 i, j, len;
138 const byte *v, *bs;
139 String* envv;
140 int32 envc;
142 bs = (const byte*)s;
143 len = runtime_findnull(bs);
144 envv = (String*)syscall_Envs.__values;
145 envc = syscall_Envs.__count;
146 for(i=0; i<envc; i++){
147 if(envv[i].__length <= len)
148 continue;
149 v = (const byte*)envv[i].__data;
150 for(j=0; j<len; j++)
151 if(bs[j] != v[j])
152 goto nomatch;
153 if(v[len] != '=')
154 goto nomatch;
155 return v+len+1;
156 nomatch:;
158 return nil;
161 int32
162 runtime_atoi(const byte *p)
164 int32 n;
166 n = 0;
167 while('0' <= *p && *p <= '9')
168 n = n*10 + *p++ - '0';
169 return n;
172 uint32
173 runtime_fastrand1(void)
175 M *m;
176 uint32 x;
178 m = runtime_m();
179 x = m->fastrand;
180 x += x;
181 if(x & 0x80000000L)
182 x ^= 0x88888eefUL;
183 m->fastrand = x;
184 return x;