cwfs: faster queue implementation using semacquire()
This commit is contained in:
parent
24349c52b4
commit
e3d9591283
2 changed files with 26 additions and 36 deletions
|
@ -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] */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue