summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/proc.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-10-03 10:37:12 -0700
committerRuss Cox <rsc@golang.org>2009-10-03 10:37:12 -0700
commit1bb8f19f5e9016a9eb118b8aba2b5689b4505812 (patch)
tree7b69b0974f4999bac76d11abed2071a2dc9e97aa /src/pkg/runtime/proc.c
parent6b7539d607f26a1b1cd3eda71fc123ad4d52a133 (diff)
downloadgolang-1bb8f19f5e9016a9eb118b8aba2b5689b4505812.tar.gz
8c, 8l dynamic loading support.
better mach binaries. cgo working on darwin+linux amd64+386. eliminated context switches - pi is 30x faster. add libcgo to build. on snow leopard: - non-cgo binaries work; all tests pass. - cgo binaries work on amd64 but not 386. R=r DELTA=2031 (1316 added, 626 deleted, 89 changed) OCL=35264 CL=35304
Diffstat (limited to 'src/pkg/runtime/proc.c')
-rw-r--r--src/pkg/runtime/proc.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c
index 590c277dd..e3c7beccd 100644
--- a/src/pkg/runtime/proc.c
+++ b/src/pkg/runtime/proc.c
@@ -389,7 +389,20 @@ mstart(void)
scheduler();
}
-// Kick of new ms as needed (up to mcpumax).
+// When running with cgo, we call libcgo_thread_start
+// to start threads for us so that we can play nicely with
+// foreign code.
+void (*libcgo_thread_start)(void*);
+
+typedef struct CgoThreadStart CgoThreadStart;
+struct CgoThreadStart
+{
+ M *m;
+ G *g;
+ void (*fn)(void);
+};
+
+// Kick off new ms as needed (up to mcpumax).
// There are already `other' other cpus that will
// start looking for goroutines shortly.
// Sched is locked.
@@ -405,7 +418,21 @@ matchmg(void)
m = malloc(sizeof(M));
m->g0 = malg(8192);
m->id = sched.mcount++;
- newosproc(m, m->g0, m->g0->stackbase, mstart);
+
+ if(libcgo_thread_start != nil) {
+ CgoThreadStart ts;
+ // pthread_create will make us a stack,
+ // so free the one malg made.
+ stackfree(m->g0->stack0);
+ m->g0->stack0 = nil;
+ m->g0->stackguard = nil;
+ m->g0->stackbase = nil;
+ ts.m = m;
+ ts.g = m->g0;
+ ts.fn = mstart;
+ runcgo(libcgo_thread_start, &ts);
+ } else
+ newosproc(m, m->g0, m->g0->stackbase, mstart);
}
mnextg(m, g);
}
@@ -419,6 +446,17 @@ scheduler(void)
lock(&sched);
if(gosave(&m->sched) != 0){
+ gp = m->curg;
+ if(gp->status == Gcgocall){
+ // Runtime call into external code (FFI).
+ // When running with FFI, the scheduler stack is a
+ // native pthread stack, so it suffices to switch to the
+ // scheduler stack and make the call.
+ runcgo(gp->cgofn, gp->cgoarg);
+ gp->status = Grunning;
+ gogo(&gp->sched, 1);
+ }
+
// Jumped here via gosave/gogo, so didn't
// execute lock(&sched) above.
lock(&sched);
@@ -426,8 +464,7 @@ scheduler(void)
if(sched.predawn)
throw("init sleeping");
- // Just finished running m->curg.
- gp = m->curg;
+ // Just finished running gp.
gp->m = nil;
sched.mcpu--;