cwfs: faster queue implementation using semacquire()

This commit is contained in:
cinap_lenrek 2013-08-04 06:47:56 +02:00
parent 24349c52b4
commit e3d9591283
2 changed files with 26 additions and 36 deletions

View file

@ -160,15 +160,17 @@ enum {
*/ */
struct Queue struct Queue
{ {
QLock; /* to manipulate values */
Rendez empty;
Rendez full;
char* name; /* for debugging */ char* name; /* for debugging */
int size; /* size of queue */ 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] */ void* args[1]; /* list of saved pointers, [->size] */
}; };

View file

@ -921,42 +921,27 @@ void*
fs_recv(Queue *q, int) fs_recv(Queue *q, int)
{ {
void *a; void *a;
int i, c;
if(q == nil) semacquire(&q->count, 1);
panic("recv null q"); lock(&q->rl);
qlock(q); a = *q->rp;
while((c = q->count) <= 0) if(++q->rp >= &q->args[q->size])
rsleep(&q->empty); q->rp = q->args;
i = q->loc; unlock(&q->rl);
a = q->args[i]; semrelease(&q->avail, 1);
i++;
if(i >= q->size)
i = 0;
q->loc = i;
q->count = c-1;
rwakeup(&q->full); /* no longer full */
qunlock(q);
return a; return a;
} }
void void
fs_send(Queue *q, void *a) fs_send(Queue *q, void *a)
{ {
int i, c; semacquire(&q->avail, 1);
lock(&q->wl);
if(q == nil) *q->wp = a;
panic("send null q"); if(++q->wp >= &q->args[q->size])
qlock(q); q->wp = q->args;
while((c = q->count) >= q->size) unlock(&q->wl);
rsleep(&q->full); semrelease(&q->count, 1);
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);
} }
Queue* Queue*
@ -966,7 +951,10 @@ newqueue(int size, char *name)
q = malloc(sizeof(Queue) + (size-1)*sizeof(void*)); q = malloc(sizeof(Queue) + (size-1)*sizeof(void*));
q->size = size; 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; q->name = name;
return q; return q;
} }