runtime: Multiplex goroutines onto OS threads.
[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 static int32 argc;
74 static byte** argv;
75
76 extern Slice os_Args asm ("libgo_os.os.Args");
77 extern Slice os_Envs asm ("libgo_os.os.Envs");
78
79 void
80 runtime_args(int32 c, byte **v)
81 {
82 argc = c;
83 argv = v;
84 }
85
86 void
87 runtime_goargs(void)
88 {
89 String *s;
90 int32 i;
91
92 // for windows implementation see "os" package
93 if(Windows)
94 return;
95
96 s = runtime_malloc(argc*sizeof s[0]);
97 for(i=0; i<argc; i++)
98 s[i] = runtime_gostringnocopy((byte*)argv[i]);
99 os_Args.__values = (void*)s;
100 os_Args.__count = argc;
101 os_Args.__capacity = argc;
102 }
103
104 void
105 runtime_goenvs(void)
106 {
107 String *s;
108 int32 i, n;
109
110 for(n=0; argv[argc+1+n] != 0; n++)
111 ;
112
113 s = runtime_malloc(n*sizeof s[0]);
114 for(i=0; i<n; i++)
115 s[i] = runtime_gostringnocopy(argv[argc+1+i]);
116 os_Envs.__values = (void*)s;
117 os_Envs.__count = n;
118 os_Envs.__capacity = n;
119 }
120
121 const byte*
122 runtime_getenv(const char *s)
123 {
124 int32 i, j, len;
125 const byte *v, *bs;
126 String* envv;
127 int32 envc;
128
129 bs = (const byte*)s;
130 len = runtime_findnull(bs);
131 envv = (String*)os_Envs.__values;
132 envc = os_Envs.__count;
133 for(i=0; i<envc; i++){
134 if(envv[i].__length <= len)
135 continue;
136 v = (const byte*)envv[i].__data;
137 for(j=0; j<len; j++)
138 if(bs[j] != v[j])
139 goto nomatch;
140 if(v[len] != '=')
141 goto nomatch;
142 return v+len+1;
143 nomatch:;
144 }
145 return nil;
146 }
147
148 int32
149 runtime_atoi(const byte *p)
150 {
151 int32 n;
152
153 n = 0;
154 while('0' <= *p && *p <= '9')
155 n = n*10 + *p++ - '0';
156 return n;
157 }
158
159 uint32
160 runtime_fastrand1(void)
161 {
162 M *m;
163 uint32 x;
164
165 m = runtime_m();
166 x = m->fastrand;
167 x += x;
168 if(x & 0x80000000L)
169 x ^= 0x88888eefUL;
170 m->fastrand = x;
171 return x;
172 }