diff options
author | Russ Cox <rsc@golang.org> | 2009-08-24 21:16:15 -0700 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2009-08-24 21:16:15 -0700 |
commit | b688f19f674f8e160ce868bfead09a5b937101df (patch) | |
tree | 2ff53a077a959f063554685484c44a4ecec1e2d1 /src | |
parent | 5d7c0b6214f853469006f19582fa7b26fa47b896 (diff) | |
download | golang-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.c | 60 |
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); } } |