mirror of
https://github.com/autc04/Retro68.git
synced 2024-12-22 19:30:36 +00:00
214 lines
3.7 KiB
C
214 lines
3.7 KiB
C
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#include "runtime.h"
|
||
|
#include "array.h"
|
||
|
#include "go-panic.h"
|
||
|
#include "go-string.h"
|
||
|
|
||
|
uint32 runtime_panicking;
|
||
|
|
||
|
static Lock paniclk;
|
||
|
|
||
|
void
|
||
|
runtime_startpanic(void)
|
||
|
{
|
||
|
M *m;
|
||
|
|
||
|
m = runtime_m();
|
||
|
if(m->dying) {
|
||
|
runtime_printf("panic during panic\n");
|
||
|
runtime_exit(3);
|
||
|
}
|
||
|
m->dying = 1;
|
||
|
runtime_xadd(&runtime_panicking, 1);
|
||
|
runtime_lock(&paniclk);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
runtime_dopanic(int32 unused __attribute__ ((unused)))
|
||
|
{
|
||
|
/*
|
||
|
static bool didothers;
|
||
|
|
||
|
if(g->sig != 0)
|
||
|
runtime_printf("[signal %x code=%p addr=%p pc=%p]\n",
|
||
|
g->sig, g->sigcode0, g->sigcode1, g->sigpc);
|
||
|
|
||
|
if(runtime_gotraceback()){
|
||
|
if(!didothers) {
|
||
|
didothers = true;
|
||
|
runtime_tracebackothers(g);
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
runtime_unlock(&paniclk);
|
||
|
if(runtime_xadd(&runtime_panicking, -1) != 0) {
|
||
|
// Some other m is panicking too.
|
||
|
// Let it print what it needs to print.
|
||
|
// Wait forever without chewing up cpu.
|
||
|
// It will exit when it's done.
|
||
|
static Lock deadlock;
|
||
|
runtime_lock(&deadlock);
|
||
|
runtime_lock(&deadlock);
|
||
|
}
|
||
|
|
||
|
runtime_exit(2);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
runtime_throw(const char *s)
|
||
|
{
|
||
|
runtime_startpanic();
|
||
|
runtime_printf("throw: %s\n", s);
|
||
|
runtime_dopanic(0);
|
||
|
*(int32*)0 = 0; // not reached
|
||
|
runtime_exit(1); // even more not reached
|
||
|
}
|
||
|
|
||
|
void
|
||
|
runtime_panicstring(const char *s)
|
||
|
{
|
||
|
Eface err;
|
||
|
|
||
|
if(runtime_m()->gcing) {
|
||
|
runtime_printf("panic: %s\n", s);
|
||
|
runtime_throw("panic during gc");
|
||
|
}
|
||
|
runtime_newErrorString(runtime_gostringnocopy((const byte*)s), &err);
|
||
|
runtime_panic(err);
|
||
|
}
|
||
|
|
||
|
static int32 argc;
|
||
|
static byte** argv;
|
||
|
|
||
|
extern Slice os_Args asm ("libgo_os.os.Args");
|
||
|
extern Slice syscall_Envs asm ("libgo_syscall.syscall.Envs");
|
||
|
|
||
|
void
|
||
|
runtime_args(int32 c, byte **v)
|
||
|
{
|
||
|
argc = c;
|
||
|
argv = v;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
runtime_goargs(void)
|
||
|
{
|
||
|
String *s;
|
||
|
int32 i;
|
||
|
|
||
|
// for windows implementation see "os" package
|
||
|
if(Windows)
|
||
|
return;
|
||
|
|
||
|
s = runtime_malloc(argc*sizeof s[0]);
|
||
|
for(i=0; i<argc; i++)
|
||
|
s[i] = runtime_gostringnocopy((const byte*)argv[i]);
|
||
|
os_Args.__values = (void*)s;
|
||
|
os_Args.__count = argc;
|
||
|
os_Args.__capacity = argc;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
runtime_goenvs_unix(void)
|
||
|
{
|
||
|
String *s;
|
||
|
int32 i, n;
|
||
|
|
||
|
for(n=0; argv[argc+1+n] != 0; n++)
|
||
|
;
|
||
|
|
||
|
s = runtime_malloc(n*sizeof s[0]);
|
||
|
for(i=0; i<n; i++)
|
||
|
s[i] = runtime_gostringnocopy(argv[argc+1+i]);
|
||
|
syscall_Envs.__values = (void*)s;
|
||
|
syscall_Envs.__count = n;
|
||
|
syscall_Envs.__capacity = n;
|
||
|
}
|
||
|
|
||
|
const byte*
|
||
|
runtime_getenv(const char *s)
|
||
|
{
|
||
|
int32 i, j, len;
|
||
|
const byte *v, *bs;
|
||
|
String* envv;
|
||
|
int32 envc;
|
||
|
|
||
|
bs = (const byte*)s;
|
||
|
len = runtime_findnull(bs);
|
||
|
envv = (String*)syscall_Envs.__values;
|
||
|
envc = syscall_Envs.__count;
|
||
|
for(i=0; i<envc; i++){
|
||
|
if(envv[i].__length <= len)
|
||
|
continue;
|
||
|
v = (const byte*)envv[i].__data;
|
||
|
for(j=0; j<len; j++)
|
||
|
if(bs[j] != v[j])
|
||
|
goto nomatch;
|
||
|
if(v[len] != '=')
|
||
|
goto nomatch;
|
||
|
return v+len+1;
|
||
|
nomatch:;
|
||
|
}
|
||
|
return nil;
|
||
|
}
|
||
|
|
||
|
int32
|
||
|
runtime_atoi(const byte *p)
|
||
|
{
|
||
|
int32 n;
|
||
|
|
||
|
n = 0;
|
||
|
while('0' <= *p && *p <= '9')
|
||
|
n = n*10 + *p++ - '0';
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
uint32
|
||
|
runtime_fastrand1(void)
|
||
|
{
|
||
|
M *m;
|
||
|
uint32 x;
|
||
|
|
||
|
m = runtime_m();
|
||
|
x = m->fastrand;
|
||
|
x += x;
|
||
|
if(x & 0x80000000L)
|
||
|
x ^= 0x88888eefUL;
|
||
|
m->fastrand = x;
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
static struct root_list runtime_roots =
|
||
|
{ NULL,
|
||
|
{ { &syscall_Envs, sizeof syscall_Envs },
|
||
|
{ &os_Args, sizeof os_Args },
|
||
|
{ NULL, 0 } },
|
||
|
};
|
||
|
|
||
|
void
|
||
|
runtime_check(void)
|
||
|
{
|
||
|
__go_register_gc_roots(&runtime_roots);
|
||
|
|
||
|
runtime_initsig ();
|
||
|
}
|
||
|
|
||
|
int64
|
||
|
runtime_cputicks(void)
|
||
|
{
|
||
|
#if defined(__386__) || defined(__x86_64__)
|
||
|
uint32 low, high;
|
||
|
asm("rdtsc" : "=a" (low), "=d" (high));
|
||
|
return (int64)(((uint64)high << 32) | (uint64)low);
|
||
|
#else
|
||
|
// FIXME: implement for other processors.
|
||
|
return 0;
|
||
|
#endif
|
||
|
}
|