This patch to the Go library uses some of the runtime.c file from the 6g compiler. This is to make it easier to merge changes to the scheduler. There are no functional changes with this patch. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline.
Ian
diff -r 43ab6b20960d libgo/Makefile.am --- a/libgo/Makefile.am Fri Nov 11 12:59:28 2011 -0800 +++ b/libgo/Makefile.am Sun Nov 13 12:39:14 2011 -0800 @@ -435,7 +435,6 @@ runtime/go-note.c \ runtime/go-panic.c \ runtime/go-print.c \ - runtime/go-rand.c \ runtime/go-rec-big.c \ runtime/go-rec-nb-big.c \ runtime/go-rec-nb-small.c \ @@ -484,6 +483,7 @@ runtime/mheap.c \ runtime/msize.c \ runtime/proc.c \ + runtime/runtime.c \ runtime/thread.c \ runtime/yield.c \ $(rtems_task_variable_add_file) \ diff -r 43ab6b20960d libgo/runtime/go-main.c --- a/libgo/runtime/go-main.c Fri Nov 11 12:59:28 2011 -0800 +++ b/libgo/runtime/go-main.c Sun Nov 13 12:39:14 2011 -0800 @@ -32,10 +32,6 @@ extern char **environ; -extern struct __go_open_array Args asm ("libgo_os.os.Args"); - -extern struct __go_open_array Envs asm ("libgo_os.os.Envs"); - /* These functions are created for the main package. */ extern void __go_init_main (void); extern void real_main (void) asm ("main.main"); @@ -45,38 +41,19 @@ int main (int argc, char **argv) { - int i; - struct __go_string *values; + runtime_args (argc, (byte **) argv); m = &runtime_m0; g = &runtime_g0; m->curg = g; g->m = m; + runtime_initpanic (); runtime_mallocinit (); runtime_cpuprofinit (); __go_gc_goroutine_init (&argc); - Args.__count = argc; - Args.__capacity = argc; - values = __go_alloc (argc * sizeof (struct __go_string)); - for (i = 0; i < argc; ++i) - { - values[i].__data = (unsigned char *) argv[i]; - values[i].__length = __builtin_strlen (argv[i]); - } - Args.__values = values; - - for (i = 0; environ[i] != NULL; ++i) - ; - Envs.__count = i; - Envs.__capacity = i; - values = __go_alloc (i * sizeof (struct __go_string)); - for (i = 0; environ[i] != NULL; ++i) - { - values[i].__data = (unsigned char *) environ[i]; - values[i].__length = __builtin_strlen (environ[i]); - } - Envs.__values = values; + runtime_goargs(); + runtime_goenvs(); __initsig (); diff -r 43ab6b20960d libgo/runtime/go-panic.c --- a/libgo/runtime/go-panic.c Fri Nov 11 12:59:28 2011 -0800 +++ b/libgo/runtime/go-panic.c Sun Nov 13 12:39:14 2011 -0800 @@ -98,10 +98,9 @@ /* The panic was not recovered. */ + runtime_startpanic (); __printpanics (g->panic); - - /* FIXME: We should dump a call stack here. */ - abort (); + runtime_dopanic (0); } /* This is used by the runtime library. */ diff -r 43ab6b20960d libgo/runtime/go-rand.c --- a/libgo/runtime/go-rand.c Fri Nov 11 12:59:28 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -// 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 "runtime.h" - -uint32 -runtime_fastrand1(void) -{ - uint32 x; - - x = m->fastrand; - x += x; - if(x & 0x80000000L) - x ^= 0x88888eefUL; - m->fastrand = x; - return x; -} diff -r 43ab6b20960d libgo/runtime/mgc0.c --- a/libgo/runtime/mgc0.c Fri Nov 11 12:59:28 2011 -0800 +++ b/libgo/runtime/mgc0.c Sun Nov 13 12:39:14 2011 -0800 @@ -834,7 +834,7 @@ { int64 t0, t1, t2, t3; uint64 heap0, heap1, obj0, obj1; - char *p; + const byte *p; bool extra; // The gc is turned off (via enablegc) until @@ -852,7 +852,7 @@ p = runtime_getenv("GOGC"); if(p == nil || p[0] == '\0') gcpercent = 100; - else if(runtime_strcmp(p, "off") == 0) + else if(runtime_strcmp((const char*)p, "off") == 0) gcpercent = -1; else gcpercent = runtime_atoi(p); diff -r 43ab6b20960d libgo/runtime/runtime.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgo/runtime/runtime.c Sun Nov 13 12:39:14 2011 -0800 @@ -0,0 +1,174 @@ +// 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_initpanic(void) +{ + runtime_initlock(&paniclk); +} + +void +runtime_startpanic(void) +{ + 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_initlock(&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 +} + +static int32 argc; +static byte** argv; + +extern Slice os_Args asm ("libgo_os.os.Args"); +extern Slice os_Envs asm ("libgo_os.os.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((byte*)argv[i]); + os_Args.__values = (void*)s; + os_Args.__count = argc; + os_Args.__capacity = argc; +} + +void +runtime_goenvs(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]); + os_Envs.__values = (void*)s; + os_Envs.__count = n; + os_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*)os_Envs.__values; + envc = os_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) +{ + uint32 x; + + x = m->fastrand; + x += x; + if(x & 0x80000000L) + x ^= 0x88888eefUL; + m->fastrand = x; + return x; +} diff -r 43ab6b20960d libgo/runtime/runtime.h --- a/libgo/runtime/runtime.h Fri Nov 11 12:59:28 2011 -0800 +++ b/libgo/runtime/runtime.h Sun Nov 13 12:39:14 2011 -0800 @@ -22,12 +22,11 @@ #include <sys/mman.h> #endif +#include "array.h" #include "go-alloc.h" #include "go-panic.h" #include "go-string.h" -typedef struct __go_string String; - /* This file supports C files copied from the 6g runtime library. This is a version of the 6g runtime.h rewritten for gccgo's version of the code. */ @@ -56,6 +55,8 @@ typedef struct __go_defer_stack Defer; typedef struct __go_panic_stack Panic; +typedef struct __go_open_array Slice; +typedef struct __go_string String; /* We use mutexes for locks. 6g uses futexes directly, and perhaps someday we will do that too. */ @@ -136,6 +137,7 @@ int32 gcing_for_prof; int32 holds_finlock; int32 gcing_for_finlock; + int32 dying; int32 profilehz; uint32 fastrand; MCache *mcache; @@ -152,14 +154,40 @@ }; /* Macros. */ + +#ifdef __WINDOWS__ +enum { + Windows = 1 +}; +#else +enum { + Windows = 0 +}; +#endif + #define nelem(x) (sizeof(x)/sizeof((x)[0])) #define nil ((void*)0) #define USED(v) ((void) v) -/* We map throw to assert. */ -#define runtime_throw(s) __go_assert(s == 0) +/* + * external data + */ +extern uint32 runtime_panicking; +/* + * common functions and data + */ +int32 runtime_findnull(const byte*); + +/* + * very low level c-called + */ +void runtime_args(int32, byte**); +void runtime_goargs(void); +void runtime_goenvs(void); +void runtime_throw(const char*); void* runtime_mal(uintptr); +String runtime_gostringnocopy(byte*); void runtime_mallocinit(void); void runtime_initfintab(void); void siginit(void); @@ -208,10 +236,9 @@ #define runtime_free(p) __go_free(p) #define runtime_memclr(buf, size) __builtin_memset((buf), 0, (size)) #define runtime_strcmp(s1, s2) __builtin_strcmp((s1), (s2)) -#define runtime_getenv(s) getenv(s) -#define runtime_atoi(s) atoi(s) #define runtime_mcmp(a, b, s) __builtin_memcmp((a), (b), (s)) #define runtime_memmove(a, b, s) __builtin_memmove((a), (b), (s)) +#define runtime_exit(s) _exit(s) MCache* runtime_allocmcache(void); void free(void *v); struct __go_func_type; @@ -222,6 +249,11 @@ #define runtime_casp(pval, old, new) __sync_bool_compare_and_swap (pval, old, new) #define runtime_xadd(p, v) __sync_add_and_fetch (p, v) +void runtime_initpanic(void); +void runtime_dopanic(int32) __attribute__ ((noreturn)); +void runtime_startpanic(void); +const byte* runtime_getenv(const char*); +int32 runtime_atoi(const byte*); void runtime_sigprof(uint8 *pc, uint8 *sp, uint8 *lr); void runtime_cpuprofinit(void); void runtime_resetcpuprofiler(int32); diff -r 43ab6b20960d libgo/runtime/string.goc --- a/libgo/runtime/string.goc Fri Nov 11 12:59:28 2011 -0800 +++ b/libgo/runtime/string.goc Sun Nov 13 12:39:14 2011 -0800 @@ -6,6 +6,24 @@ #include "runtime.h" #define charntorune(pv, str, len) __go_get_rune(str, len, pv) +int32 +runtime_findnull(const byte *s) +{ + if(s == nil) + return 0; + return __builtin_strlen((const char*) s); +} + +String +runtime_gostringnocopy(byte *str) +{ + String s; + + s.__data = (const unsigned char *) str; + s.__length = runtime_findnull(str); + return s; +} + enum { Runeself = 0x80,