@@ -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) \
@@ -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 ();
@@ -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. */
@@ -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;
-}
@@ -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);
@@ -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;
+}
@@ -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);
@@ -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,