aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/vbackup/queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/vbackup/queue.c')
-rw-r--r--src/cmd/vbackup/queue.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/cmd/vbackup/queue.c b/src/cmd/vbackup/queue.c
new file mode 100644
index 00000000..91fa221d
--- /dev/null
+++ b/src/cmd/vbackup/queue.c
@@ -0,0 +1,64 @@
+#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);
+}