Comments
Patch
@@ -5876,13 +5876,13 @@
ret->append("interface {");
if (this->methods_ != NULL)
{
+ ret->push_back(' ');
for (Typed_identifier_list::const_iterator p = this->methods_->begin();
p != this->methods_->end();
++p)
{
if (p != this->methods_->begin())
- ret->append(";");
- ret->push_back(' ');
+ ret->append("; ");
if (!Gogo::is_hidden_name(p->name()))
ret->append(p->name());
else
@@ -5898,8 +5898,9 @@
sub = sub.substr(4);
ret->append(sub);
}
- }
- ret->append(" }");
+ ret->push_back(' ');
+ }
+ ret->append("}");
}
// Mangled name.
@@ -452,7 +452,7 @@
AM_CONDITIONAL(HAVE_SYS_MMAN_H, test "$ac_cv_header_sys_mman_h" = yes)
-AC_CHECK_FUNCS(srandom random strerror_r strsignal wait4 mincore setenv)
+AC_CHECK_FUNCS(strerror_r strsignal wait4 mincore setenv)
AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes)
AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes)
@@ -32,10 +32,7 @@
extern char **environ;
-/* These functions are created for the main package. */
-extern void __go_init_main (void);
-extern void real_main (void) asm ("main.main");
-
+extern void runtime_main (void);
static void mainstart (void *);
/* The main function. */
@@ -47,13 +44,6 @@
runtime_args (argc, (byte **) argv);
runtime_osinit ();
runtime_schedinit ();
-
-#if defined(HAVE_SRANDOM)
- srandom ((unsigned int) time (NULL));
-#else
- srand ((unsigned int) time (NULL));
-#endif
-
__go_go (mainstart, NULL);
runtime_mstart (runtime_m ());
abort ();
@@ -62,13 +52,5 @@
static void
mainstart (void *arg __attribute__ ((unused)))
{
- __go_init_main ();
-
- mstats.enablegc = 1;
-
- real_main ();
-
- runtime_exit (0);
-
- abort ();
+ runtime_main ();
}
@@ -128,6 +128,9 @@
volatile uint32 atomic; // atomic scheduling word (see below)
int32 profilehz; // cpu profiling rate
+
+ bool init; // running initialization
+ bool lockmain; // init called runtime.LockOSThread
Note stopped; // one g can set waitstop and wait here for m's to stop
};
@@ -292,11 +295,7 @@
// make & queue new G
// call runtime_mstart
//
-// The new G does:
-//
-// call main_init_function
-// call initdone
-// call main_main
+// The new G calls runtime_main.
void
runtime_schedinit(void)
{
@@ -340,6 +339,37 @@
m->nomemprof--;
}
+extern void main_init(void) __asm__ ("__go_init_main");
+extern void main_main(void) __asm__ ("main.main");
+
+// The main goroutine.
+void
+runtime_main(void)
+{
+ // Lock the main goroutine onto this, the main OS thread,
+ // during initialization. Most programs won't care, but a few
+ // do require certain calls to be made by the main thread.
+ // Those can arrange for main.main to run in the main thread
+ // by calling runtime.LockOSThread during initialization
+ // to preserve the lock.
+ runtime_LockOSThread();
+ runtime_sched.init = true;
+ main_init();
+ runtime_sched.init = false;
+ if(!runtime_sched.lockmain)
+ runtime_UnlockOSThread();
+
+ // For gccgo we have to wait until after main is initialized
+ // to enable GC, because initializing main registers the GC
+ // roots.
+ mstats.enablegc = 1;
+
+ main_main();
+ runtime_exit(0);
+ for(;;)
+ *(int32*)0 = 0;
+}
+
// Lock the scheduler.
static void
schedlock(void)
@@ -1233,16 +1263,6 @@
runtime_gosched();
}
-void runtime_LockOSThread (void)
- __asm__ ("libgo_runtime.runtime.LockOSThread");
-
-void
-runtime_LockOSThread(void)
-{
- m->lockedg = g;
- g->lockedm = m;
-}
-
// delete when scheduler is stronger
int32
runtime_gomaxprocsfunc(int32 n)
@@ -1282,12 +1302,24 @@
return ret;
}
-void runtime_UnlockOSThread (void)
- __asm__ ("libgo_runtime.runtime.UnlockOSThread");
+void
+runtime_LockOSThread(void)
+{
+ if(m == &runtime_m0 && runtime_sched.init) {
+ runtime_sched.lockmain = true;
+ return;
+ }
+ m->lockedg = g;
+ g->lockedm = m;
+}
void
runtime_UnlockOSThread(void)
{
+ if(m == &runtime_m0 && runtime_sched.init) {
+ runtime_sched.lockmain = false;
+ return;
+ }
m->lockedg = nil;
g->lockedm = nil;
}
@@ -318,16 +318,20 @@
void runtime_ready(G*);
const byte* runtime_getenv(const char*);
int32 runtime_atoi(const byte*);
+uint32 runtime_fastrand1(void);
+
void runtime_sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp);
void runtime_resetcpuprofiler(int32);
void runtime_setcpuprofilerate(void(*)(uintptr*, int32), int32);
-uint32 runtime_fastrand1(void);
+void runtime_usleep(uint32);
+
void runtime_semacquire(uint32 volatile *);
void runtime_semrelease(uint32 volatile *);
int32 runtime_gomaxprocsfunc(int32 n);
void runtime_procyield(uint32);
void runtime_osyield(void);
-void runtime_usleep(uint32);
+void runtime_LockOSThread(void) __asm__("libgo_runtime.runtime.LockOSThread");
+void runtime_UnlockOSThread(void) __asm__("libgo_runtime.runtime.UnlockOSThread");
struct __go_func_type;
void reflect_call(const struct __go_func_type *, const void *, _Bool, _Bool,