re PR libstdc++/52591 ([C++0x] [4.7 Regression] moving std::vector relies on movable...
[gcc.git] / libgo / runtime / runtime.c
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.
4
5 #include <unistd.h>
6
7 #include "runtime.h"
8 #include "array.h"
9 #include "go-panic.h"
10 #include "go-string.h"
11
12 uint32 runtime_panicking;
13
14 static Lock paniclk;
15
16 void
17 runtime_startpanic(void)
18 {
19 M *m;
20
21 m = runtime_m();
22 if(m->dying) {
23 runtime_printf("panic during panic\n");
24 runtime_exit(3);
25 }
26 m->dying = 1;
27 runtime_xadd(&runtime_panicking, 1);
28 runtime_lock(&paniclk);
29 }
30
31 void
32 runtime_dopanic(int32 unused __attribute__ ((unused)))
33 {
34 /*
35 static bool didothers;
36
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);
40
41 if(runtime_gotraceback()){
42 if(!didothers) {
43 didothers = true;
44 runtime_tracebackothers(g);
45 }
46 }
47 */
48
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);
58 }
59
60 runtime_exit(2);
61 }
62
63 void
64 runtime_throw(const char *s)
65 {
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
71 }
72
73 void
74 runtime_panicstring(const char *s)
75 {
76 Eface err;
77
78 if(runtime_m()->gcing) {
79 runtime_printf("panic: %s\n", s);
80 runtime_throw("panic during gc");
81 }
82 runtime_newErrorString(runtime_gostringnocopy((const byte*)s), &err);
83 runtime_panic(err);
84 }
85
86 static int32 argc;
87 static byte** argv;
88
89 extern Slice os_Args asm ("libgo_os.os.Args");
90 extern Slice syscall_Envs asm ("libgo_syscall.syscall.Envs");
91
92 void
93 runtime_args(int32 c, byte **v)
94 {
95 argc = c;
96 argv = v;
97 }
98
99 void
100 runtime_goargs(void)
101 {
102 String *s;
103 int32 i;
104
105 // for windows implementation see "os" package
106 if(Windows)
107 return;
108
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;
115 }
116
117 void
118 runtime_goenvs_unix(void)
119 {
120 String *s;
121 int32 i, n;
122
123 for(n=0; argv[argc+1+n] != 0; n++)
124 ;
125
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;
132 }
133
134 const byte*
135 runtime_getenv(const char *s)
136 {
137 int32 i, j, len;
138 const byte *v, *bs;
139 String* envv;
140 int32 envc;
141
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:;
157 }
158 return nil;
159 }
160
161 int32
162 runtime_atoi(const byte *p)
163 {
164 int32 n;
165
166 n = 0;
167 while('0' <= *p && *p <= '9')
168 n = n*10 + *p++ - '0';
169 return n;
170 }
171
172 uint32
173 runtime_fastrand1(void)
174 {
175 M *m;
176 uint32 x;
177
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;
185 }
186
187 static struct root_list runtime_roots =
188 { NULL,
189 { { &syscall_Envs, sizeof syscall_Envs },
190 { &os_Args, sizeof os_Args },
191 { NULL, 0 } },
192 };
193
194 void
195 runtime_check(void)
196 {
197 __go_register_gc_roots(&runtime_roots);
198 }
199
200 int64
201 runtime_cputicks(void)
202 {
203 #if defined(__386__) || defined(__x86_64__)
204 uint32 low, high;
205 asm("rdtsc" : "=a" (low), "=d" (high));
206 return (int64)(((uint64)high << 32) | (uint64)low);
207 #else
208 // FIXME: implement for other processors.
209 return 0;
210 #endif
211 }