runtime: move mstart from Go to C
The assignments done in mstart must be done without write barriers, as
mstart is running without an m or p. In the gc toolchain the
equivalent code to intialize g and g->m is written in assembler;
on GNU/Linux, it's in the clone function.
Change-Id: Id84d2897e2a72a7ff906c763cf4524e956b709e7
Reviewed-on: https://go-review.googlesource.com/40989
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go
index 9f467ee..0907afc 100644
--- a/libgo/go/runtime/proc.go
+++ b/libgo/go/runtime/proc.go
@@ -35,7 +35,6 @@
//go:linkname stopTheWorldWithSema runtime.stopTheWorldWithSema
//go:linkname startTheWorldWithSema runtime.startTheWorldWithSema
//go:linkname kickoff runtime.kickoff
-//go:linkname mstart runtime.mstart
//go:linkname mstart1 runtime.mstart1
//go:linkname globrunqput runtime.globrunqput
//go:linkname pidleget runtime.pidleget
@@ -54,7 +53,6 @@
func gogo(*g)
func setGContext()
func makeGContext(*g, unsafe.Pointer, uintptr)
-func mstartInitContext(*g, unsafe.Pointer)
func getTraceback(me, gp *g)
func gtraceback(*g)
func _cgo_notify_runtime_init_done()
@@ -988,26 +986,7 @@
goexit1()
}
-// Called to start an M.
-// For gccgo this is called directly by pthread_create.
-//go:nosplit
-func mstart(mpu unsafe.Pointer) unsafe.Pointer {
- mp := (*m)(mpu)
- _g_ := mp.g0
- _g_.m = mp
- setg(_g_)
-
- _g_.entry = nil
- _g_.param = nil
-
- mstartInitContext(_g_, unsafe.Pointer(&mp))
-
- // This is never reached, but is required because pthread_create
- // expects a function that returns a pointer.
- return nil
-}
-
-// This is called from mstartInitContext.
+// This is called from mstart.
func mstart1() {
_g_ := getg()
diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c
index 10dd0a8..23cfb73 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -459,14 +459,22 @@
runtime_gogo(traceback->gp);
}
-// Called to set up the context information for a new M.
-
-void mstartInitContext(G*, void*)
- __asm__(GOSYM_PREFIX "runtime.mstartInitContext");
-
-void
-mstartInitContext(G *gp, void *stack __attribute__ ((unused)))
+// Called by pthread_create to start an M.
+void*
+runtime_mstart(void *arg)
{
+ M* mp;
+ G* gp;
+
+ mp = (M*)(arg);
+ gp = mp->g0;
+ gp->m = mp;
+
+ g = gp;
+
+ gp->entry = nil;
+ gp->param = nil;
+
initcontext();
// Record top of stack for use by mcall.
@@ -475,11 +483,11 @@
#ifdef USING_SPLIT_STACK
__splitstack_getcontext(&gp->stackcontext[0]);
#else
- gp->gcinitialsp = stack;
+ gp->gcinitialsp = &arg;
// Setting gcstacksize to 0 is a marker meaning that gcinitialsp
// is the top of the stack, not the bottom.
gp->gcstacksize = 0;
- gp->gcnextsp = stack;
+ gp->gcnextsp = &arg;
#endif
// Save the currently active context. This will return
@@ -493,7 +501,7 @@
gtraceback(gp);
}
- if(gp->entry != 0) {
+ if(gp->entry != nil) {
// Got here from mcall.
FuncVal *fv = gp->entry;
void (*pfn)(G*) = (void (*)(G*))fv->fn;
@@ -514,6 +522,10 @@
#endif
mstart1();
+
+ // mstart1 does not return, but we need a return statement
+ // here to avoid a compiler warning.
+ return nil;
}
typedef struct CgoThreadStart CgoThreadStart;
@@ -550,7 +562,7 @@
#endif
getcontext(ucontext_arg(&gp->context[0]));
- if(gp->entry != 0) {
+ if(gp->entry != nil) {
// Got here from mcall.
FuncVal *fv = gp->entry;
void (*pfn)(G*) = (void (*)(G*))fv->fn;
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
index ac86fa4..e38bf06 100644
--- a/libgo/runtime/runtime.h
+++ b/libgo/runtime/runtime.h
@@ -293,8 +293,7 @@
__asm__ (GOSYM_PREFIX "runtime.ready");
String runtime_getenv(const char*);
int32 runtime_atoi(const byte*, intgo);
-void* runtime_mstart(void*)
- __asm__(GOSYM_PREFIX "runtime.mstart");
+void* runtime_mstart(void*);
G* runtime_malg(bool, bool, byte**, uintptr*)
__asm__(GOSYM_PREFIX "runtime.malg");
void runtime_minit(void)