#include <u.h> | |
#include <libc.h> | |
#include <thread.h> | |
#include <venti.h> | |
#include <diskfs.h> | |
#include "queue.h" | |
Queue* | |
qalloc(void) | |
{ | |
Queue *q; | |
q = vtmallocz(sizeof(Queue)); | |
q->r.l = &q->lk; | |
return q; | |
} | |
Block* | |
qread(Queue *q, u32int *pbno) | |
{ | |
Block *db; | |
u32int bno; | |
qlock(&q->lk); | |
while(q->nel == 0 && !q->closed) | |
rsleep(&q->r); | |
if(q->nel == 0 && q->closed){ | |
qunlock(&q->lk); | |
return nil; | |
} | |
db = q->el[q->ri].db; | |
bno = q->el[q->ri].bno; | |
if(++q->ri == MAXQ) | |
q->ri = 0; | |
if(q->nel-- == MAXQ/2) | |
rwakeup(&q->r); | |
qunlock(&q->lk); | |
*pbno = bno; | |
return db; | |
} | |
void | |
qwrite(Queue *q, Block *db, u32int bno) | |
{ | |
qlock(&q->lk); | |
while(q->nel == MAXQ) | |
rsleep(&q->r); | |
q->el[q->wi].db = db; | |
q->el[q->wi].bno = bno; | |
if(++q->wi == MAXQ) | |
q->wi = 0; | |
if(q->nel++ == MAXQ/2) | |
rwakeup(&q->r); | |
qunlock(&q->lk); | |
} | |
void | |
qclose(Queue *q) | |
{ | |
qlock(&q->lk); | |
q->closed = 1; | |
rwakeup(&q->r); | |
qunlock(&q->lk); | |
} | |
void | |
qfree(Queue *q) | |
{ | |
vtfree(q); | |
} |