Added completion data structure
authorDavide Libenzi <dlibenzi@google.com>
Sun, 8 Nov 2015 19:25:39 +0000 (11:25 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 24 Nov 2015 20:38:22 +0000 (15:38 -0500)
Added completion data structure. It allows waiters to be woken up once
the given number of complete operations have been issued.

Signed-off-by: Davide Libenzi <dlibenzi@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/completion.h [new file with mode: 0644]
kern/src/Kbuild
kern/src/completion.c [new file with mode: 0644]

diff --git a/kern/include/completion.h b/kern/include/completion.h
new file mode 100644 (file)
index 0000000..b061e84
--- /dev/null
@@ -0,0 +1,17 @@
+/* Copyright (c) 2015 Google Inc
+ * Davide Libenzi <dlibenzi@google.com>
+ * See LICENSE for details.
+ */
+
+#pragma once
+
+#include <kthread.h>
+
+struct completion {
+       struct cond_var cv;
+       int count;
+};
+
+void completion_init(struct completion *comp, int count);
+void completion_complete(struct completion *comp, int how_much);
+void completion_wait(struct completion *comp);
index 5e380e3..8e57062 100644 (file)
@@ -15,6 +15,7 @@ obj-y                                         += bitmap.o
 obj-y                                          += blockdev.o
 obj-y                                          += ceq.o
 obj-y                                          += colored_caches.o
+obj-y                                          += completion.o
 obj-y                                          += console.o
 obj-y                                          += coreprov.o
 obj-y                                          += ctype.o
diff --git a/kern/src/completion.c b/kern/src/completion.c
new file mode 100644 (file)
index 0000000..80ce232
--- /dev/null
@@ -0,0 +1,37 @@
+/* Copyright (c) 2015 Google Inc
+ * Davide Libenzi <dlibenzi@google.com>
+ * See LICENSE for details.
+ */
+
+#include <kthread.h>
+#include <completion.h>
+
+void completion_init(struct completion *comp, int count)
+{
+       cv_init_irqsave(&comp->cv);
+       comp->count = count;
+}
+
+void completion_complete(struct completion *comp, int how_much)
+{
+       int8_t state = 0;
+
+       cv_lock_irqsave(&comp->cv, &state);
+       comp->count -= how_much;
+       if (comp->count <= 0)
+               __cv_broadcast(&comp->cv);
+       cv_unlock_irqsave(&comp->cv, &state);
+}
+
+void completion_wait(struct completion *comp)
+{
+       int8_t state = 0;
+
+       cv_lock_irqsave(&comp->cv, &state);
+       if (comp->count > 0) {
+               cv_wait_and_unlock(&comp->cv);
+               enable_irqsave(&state);
+       } else {
+               cv_unlock_irqsave(&comp->cv, &state);
+       }
+}