git: 9front

Download patch

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;
 }
--