ref: 55540edfbf42f422c435510db4653f0c9629d204
parent: 68165901439ba484638ca76a41b32611a2e0720a
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sun Aug 4 02:47:56 EDT 2013
cwfs: faster queue implementation using semacquire()
--- a/sys/src/cmd/cwfs/portdat.h
+++ b/sys/src/cmd/cwfs/portdat.h
@@ -160,15 +160,17 @@
*/
struct Queue
{- QLock; /* to manipulate values */
- Rendez empty;
- Rendez full;
-
char* name; /* for debugging */
int size; /* size of queue */
- int loc; /* circular pointer */
- int count; /* how many in queue */
+
+ long count; /* how many in queue (semaphore) */
+ long avail; /* how many available to send (semaphore) */
+
+ Lock rl, wl; /* circular pointers */
+ void **rp;
+ void **wp;
+
void* args[1]; /* list of saved pointers, [->size] */
};
--- a/sys/src/cmd/cwfs/sub.c
+++ b/sys/src/cmd/cwfs/sub.c
@@ -921,22 +921,14 @@
fs_recv(Queue *q, int)
{void *a;
- int i, c;
- if(q == nil)
- panic("recv null q");- qlock(q);
- while((c = q->count) <= 0)
- rsleep(&q->empty);
- i = q->loc;
- a = q->args[i];
- i++;
- if(i >= q->size)
- i = 0;
- q->loc = i;
- q->count = c-1;
- rwakeup(&q->full); /* no longer full */
- qunlock(q);
+ semacquire(&q->count, 1);
+ lock(&q->rl);
+ a = *q->rp;
+ if(++q->rp >= &q->args[q->size])
+ q->rp = q->args;
+ unlock(&q->rl);
+ semrelease(&q->avail, 1);
return a;
}
@@ -943,20 +935,13 @@
void
fs_send(Queue *q, void *a)
{- int i, c;
-
- if(q == nil)
- panic("send null q");- qlock(q);
- while((c = q->count) >= q->size)
- rsleep(&q->full);
- i = q->loc + c;
- if(i >= q->size)
- i -= q->size;
- q->args[i] = a;
- q->count = c+1;
- rwakeup(&q->empty); /* no longer empty */
- qunlock(q);
+ semacquire(&q->avail, 1);
+ lock(&q->wl);
+ *q->wp = a;
+ if(++q->wp >= &q->args[q->size])
+ q->wp = q->args;
+ unlock(&q->wl);
+ semrelease(&q->count, 1);
}
Queue*
@@ -966,7 +951,10 @@
q = malloc(sizeof(Queue) + (size-1)*sizeof(void*));
q->size = size;
- q->full.l = q->empty.l = &q->QLock;
+ q->avail = size;
+ q->count = 0;
+ q->rp = q->args;
+ q->wp = q->args;
q->name = name;
return q;
}
--
⑨