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
{
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] */
};

View file

@ -921,42 +921,27 @@ void*
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;
}
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 @@ newqueue(int size, char *name)
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;
}