fill up the qread buffer if possible to conerve syscalls. free block lists outside ilock Reference: /n/patches.lsub.org/patch/qiofull Date: Sun Oct 28 17:57:50 CET 2012 Signed-off-by: quanstro@quanstro.net --- /sys/src/nix/port/qio.c Thu Apr 12 12:26:29 2012 +++ /sys/src/nix/port/qio.c Sun Oct 28 16:49:21 2012 @@ -228,7 +228,7 @@ } else { /* shouldn't happen but why crash if it does */ if(i < 0){ - print("pullupblock -ve length, from %#p\n", + print("pullup negative length packet, called from %#p\n", getcallerpc(&bp)); i = 0; } @@ -577,14 +577,14 @@ dowakeup = 0; ilock(q); if(q->len >= q->limit){ - freeblist(b); iunlock(q); + freeblist(b); return -1; } if(q->state & Qclosed){ len = BALLOC(b); - freeblist(b); iunlock(q); + freeblist(b); return len; } @@ -1079,7 +1079,7 @@ qread(Queue *q, void *vp, int len) { Block *b, *first, **l; - int blen, n; + int n; qlock(&q->rlock); if(waserror()){ @@ -1111,23 +1111,17 @@ goto again; } - /* grab the first block plus as many - * following blocks as will completely - * fit in the read. + /* + * grab the first block and as many following + * blocks as will partially fit in the read */ n = 0; l = &first; - blen = BLEN(b); for(;;) { *l = qremove(q); l = &b->next; - n += blen; - - b = q->bfirst; - if(b == nil) - break; - blen = BLEN(b); - if(n+blen > len) + n += BLEN(b); + if(n >= len || (b = q->bfirst) == nil) break; } } else {