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