summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-08-24 21:16:15 -0700
committerRuss Cox <rsc@golang.org>2009-08-24 21:16:15 -0700
commitb688f19f674f8e160ce868bfead09a5b937101df (patch)
tree2ff53a077a959f063554685484c44a4ecec1e2d1 /src
parent5d7c0b6214f853469006f19582fa7b26fa47b896 (diff)
downloadgolang-b688f19f674f8e160ce868bfead09a5b937101df.tar.gz
cgocall bug fix.
better FFI demo: compute fibonacci numbers using FFI'ed libgmp. R=r DELTA=281 (255 added, 19 deleted, 7 changed) OCL=33815 CL=33820
Diffstat (limited to 'src')
-rw-r--r--src/libcgo/cgocall.c60
1 files changed, 39 insertions, 21 deletions
diff --git a/src/libcgo/cgocall.c b/src/libcgo/cgocall.c
index c089f1d5d..d501a38ef 100644
--- a/src/libcgo/cgocall.c
+++ b/src/libcgo/cgocall.c
@@ -218,25 +218,25 @@ newserver(void)
pthread_t p;
lock(&cgo.lock);
- if(cgo.idle == nil) {
- // kick off new servers with work to do
- for(w=cgo.whead; w; w=next) {
- next = w;
- w->next = nil;
- f = malloc(sizeof *f);
- memset(f, 0, sizeof *f);
- f->work = w;
- noteclear(&f->note);
- notewakeup(&f->note);
- if(pthread_create(&p, nil, go_pthread, f) < 0) {
- fprintf(stderr, "pthread_create: %s\n", strerror(errno));
- *(int*)0 = 0;
- }
+ // kick off new servers with work to do
+ for(w=cgo.whead; w; w=next) {
+ next = w;
+ w->next = nil;
+ f = malloc(sizeof *f);
+ memset(f, 0, sizeof *f);
+ f->work = w;
+ noteclear(&f->note);
+ notewakeup(&f->note);
+ if(pthread_create(&p, nil, go_pthread, f) < 0) {
+ fprintf(stderr, "pthread_create: %s\n", strerror(errno));
+ *(int*)0 = 0;
}
- cgo.whead = nil;
- cgo.wtail = nil;
+ }
+ cgo.whead = nil;
+ cgo.wtail = nil;
- // kick off one more server to sit idle
+ // kick off one more server to sit idle
+ if(cgo.idle == nil) {
f = malloc(sizeof *f);
memset(f, 0, sizeof *f);
f->next = cgo.idle;
@@ -256,23 +256,41 @@ go_pthread(void *v)
CgoServer *f;
CgoWork *w;
+ // newserver queued us; wait for work
f = v;
+ goto wait;
+
for(;;) {
- // wait for work
- notesleep(&f->note);
+ // kick off new server to handle requests while we work
+ newserver();
// do work
w = f->work;
w->fn(w->arg);
notewakeup(&w->note);
+ f->work = nil;
- // queue f on idle list
+ // take some work if available
+ lock(&cgo.lock);
+ if((w = cgo.whead) != nil) {
+ cgo.whead = w->next;
+ if(cgo.whead == nil)
+ cgo.wtail = nil;
+ unlock(&cgo.lock);
+ f->work = w;
+ continue;
+ }
+
+ // otherwise queue
f->work = nil;
noteclear(&f->note);
- lock(&cgo.lock);
f->next = cgo.idle;
cgo.idle = f;
unlock(&cgo.lock);
+
+wait:
+ // wait for work
+ notesleep(&f->note);
}
}