OSDN Git Service

runtime: Tweak __go_can_recover for SPARC.
[pf3gnuchains/gcc-fork.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 int64
188 runtime_cputicks(void)
189 {
190 #if defined(__386__) || defined(__x86_64__)
191   uint32 low, high;
192   asm("rdtsc" : "=a" (low), "=d" (high));
193   return (int64)(((uint64)high << 32) | (uint64)low);
194 #else
195   // FIXME: implement for other processors.
196   return 0;
197 #endif
198 }
199
200 struct funcline_go_return
201 {
202   String retfile;
203   int32 retline;
204 };
205
206 struct funcline_go_return
207 runtime_funcline_go(void *f, uintptr targetpc)
208   __asm__("libgo_runtime.runtime.funcline_go");
209
210 struct funcline_go_return
211 runtime_funcline_go(void *f __attribute__((unused)),
212                     uintptr targetpc __attribute__((unused)))
213 {
214   struct funcline_go_return ret;
215   runtime_memclr(&ret, sizeof ret);
216   return ret;
217 }