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.
6
#include "defs_GOOS_GOARCH.h"
10
extern SigTab runtime·sigtab[];
12
int32 runtime·open(uint8*, int32, int32);
13
int32 runtime·close(int32);
14
int32 runtime·read(int32, void*, int32);
16
static Sigset sigset_all = { ~(uint32)0, ~(uint32)0 };
17
static Sigset sigset_none;
21
// futexsleep(uint32 *addr, uint32 val)
22
// futexwakeup(uint32 *addr)
24
// Futexsleep atomically checks if *addr == val and if so, sleeps on addr.
25
// Futexwakeup wakes up threads sleeping on addr.
26
// Futexsleep is allowed to wake up spuriously.
38
// if(*addr == val) sleep
39
// Might be woken up spuriously; that's allowed.
40
// Don't sleep longer than ns; ns < 0 means forever.
42
runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
49
ts.tv_sec = ns/1000000000LL;
50
ts.tv_nsec = ns%1000000000LL;
57
// Some Linux kernels have a bug where futex of
58
// FUTEX_WAIT returns an internal error code
59
// as an errno. Libpthread ignores the return value
60
// here, and so can we: as it says a few lines up,
61
// spurious wakeups are allowed.
62
runtime·futex(addr, FUTEX_WAIT, val, tsp, nil, 0);
65
// If any procs are sleeping on addr, wake up at most cnt.
67
runtime·futexwakeup(uint32 *addr, uint32 cnt)
71
ret = runtime·futex(addr, FUTEX_WAKE, cnt, nil, nil, 0);
76
// I don't know that futex wakeup can return
77
// EAGAIN or EINTR, but if it does, it would be
78
// safe to loop and call futex again.
79
runtime·printf("futexwakeup addr=%p returned %D\n", addr, ret);
80
*(int32*)0x1006 = 0x1006;
86
int32 fd, rd, cnt, cpustrlen;
87
byte *cpustr, *pos, *bufpos;
90
fd = runtime·open((byte*)"/proc/stat", O_RDONLY|O_CLOEXEC, 0);
95
cpustr = (byte*)"\ncpu";
96
cpustrlen = runtime·findnull(cpustr);
98
rd = runtime·read(fd, bufpos, sizeof(buf)-cpustrlen);
102
for(pos=buf; pos=runtime·strstr(pos, cpustr); cnt++, pos++) {
106
runtime·memmove(buf, bufpos+rd-cpustrlen+1, cpustrlen-1);
107
bufpos = buf+cpustrlen-1;
110
return cnt ? cnt : 1;
113
// Clone, the Linux rfork.
119
CLONE_SIGHAND = 0x800,
120
CLONE_PTRACE = 0x2000,
121
CLONE_VFORK = 0x4000,
122
CLONE_PARENT = 0x8000,
123
CLONE_THREAD = 0x10000,
124
CLONE_NEWNS = 0x20000,
125
CLONE_SYSVSEM = 0x40000,
126
CLONE_SETTLS = 0x80000,
127
CLONE_PARENT_SETTID = 0x100000,
128
CLONE_CHILD_CLEARTID = 0x200000,
129
CLONE_UNTRACED = 0x800000,
130
CLONE_CHILD_SETTID = 0x1000000,
131
CLONE_STOPPED = 0x2000000,
132
CLONE_NEWUTS = 0x4000000,
133
CLONE_NEWIPC = 0x8000000,
137
runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
144
* note: strace gets confused if we use CLONE_PTRACE here.
146
flags = CLONE_VM /* share memory */
147
| CLONE_FS /* share cwd, etc */
148
| CLONE_FILES /* share fd table */
149
| CLONE_SIGHAND /* share sig handler table */
150
| CLONE_THREAD /* revisit - okay for now */
153
m->tls[0] = m->id; // so 386 asm can find it
155
runtime·printf("newosproc stk=%p m=%p g=%p fn=%p clone=%p id=%d/%d ostk=%p\n",
156
stk, m, g, fn, runtime·clone, m->id, m->tls[0], &m);
159
// Disable signals during clone, so that the new thread starts
160
// with signals disabled. It will enable them in minit.
161
runtime·rtsigprocmask(SIG_SETMASK, &sigset_all, &oset, sizeof oset);
162
ret = runtime·clone(flags, stk, m, g, fn);
163
runtime·rtsigprocmask(SIG_SETMASK, &oset, nil, sizeof oset);
166
runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), -ret);
167
runtime·throw("runtime.newosproc");
174
runtime·ncpu = getproccount();
180
runtime·goenvs_unix();
183
// Called to initialize a new m (including the bootstrap m).
187
// Initialize signal handling.
188
m->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K
189
runtime·signalstack(m->gsignal->stackguard - StackGuard, 32*1024);
190
runtime·rtsigprocmask(SIG_SETMASK, &sigset_none, nil, sizeof sigset_none);
194
runtime·sigpanic(void)
198
if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000) {
200
runtime·panicstring("call of nil func value");
202
runtime·panicstring("invalid memory address or nil pointer dereference");
203
runtime·printf("unexpected fault address %p\n", g->sigcode1);
204
runtime·throw("fault");
206
if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode0 == SEGV_ACCERR) && g->sigcode1 < 0x1000) {
208
runtime·panicstring("call of nil func value");
209
runtime·panicstring("invalid memory address or nil pointer dereference");
211
runtime·printf("unexpected fault address %p\n", g->sigcode1);
212
runtime·throw("fault");
214
switch(g->sigcode0) {
216
runtime·panicstring("integer divide by zero");
218
runtime·panicstring("integer overflow");
220
runtime·panicstring("floating point error");
222
runtime·panicstring(runtime·sigtab[g->sig].name);
226
runtime·memlimit(void)
229
extern byte text[], end[];
232
if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
234
if(rl.rlim_cur >= 0x7fffffff)
237
// Estimate our VM footprint excluding the heap.
238
// Not an exact science: use size of binary plus
239
// some room for thread stacks.
240
used = end - text + (64<<20);
241
if(used >= rl.rlim_cur)
244
// If there's not at least 16 MB left, we're probably
245
// not going to be able to do much. Treat as no limit.
247
if(rl.rlim_cur < (16<<20))
250
return rl.rlim_cur - used;
254
runtime·setprof(bool on)
259
static int8 badcallback[] = "runtime: cgo callback on thread not created by Go.\n";
261
// This runs on a foreign stack, without an m or a g. No stack split.
264
runtime·badcallback(void)
266
runtime·write(2, badcallback, sizeof badcallback - 1);
269
static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n";
271
// This runs on a foreign stack, without an m or a g. No stack split.
274
runtime·badsignal(void)
276
runtime·write(2, badsignal, sizeof badsignal - 1);