DeviceQueue: pushed descriptor queue to desc_queue.c
authorRoni Häcki <roni.haecki@inf.ethz.ch>
Fri, 12 Aug 2016 12:43:19 +0000 (14:43 +0200)
committerRoni Häcki <roni.haecki@inf.ethz.ch>
Fri, 12 Aug 2016 12:43:19 +0000 (14:43 +0200)
Signed-off-by: Roni Häcki <roni.haecki@inf.ethz.ch>

errors/errno.fugu
lib/devif/Hakefile
lib/devif/desc_queue.c [new file with mode: 0644]
lib/devif/desc_queue.h [new file with mode: 0644]
lib/devif/queue_interface.c

index db1c2de..e39989f 100755 (executable)
@@ -1225,6 +1225,6 @@ errors cpuid DEVQ_ERR_ {
     failure INVALID_REGION_ID       "The region id is not valid",
     failure REGION_DESTROY          "The region has still buffers that are in use",
     failure TX_FULL                 "Send queue full",
-    failure RX_FULL                 "Receive queue full",
+    failure RX_EMPTY                 "Receive queue emtpy",
 };
 
index 5715d8a..ddaa56f 100644 (file)
@@ -16,7 +16,8 @@
     build library { 
         target = "devif",
         cFiles = ["queue_interface.c", "region_pool.c", 
-                  "region.c"],
-        addCFlags = [ "-DLIBRARY" ]
+                  "region.c", "desc_queue.c"],
+        addCFlags = [ "-DLIBRARY" ],
+        flounderBindings = ["devif"]
     }
 ]
diff --git a/lib/devif/desc_queue.c b/lib/devif/desc_queue.c
new file mode 100644 (file)
index 0000000..37df34c
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2016 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <barrelfish/barrelfish.h>
+#include <devif/queue_interface.h>
+#include "desc_queue.h"
+#include "dqi_debug.h"
+
+
+struct __attribute__((aligned(DESCQ_ALIGNMENT))) desc {
+    regionid_t region_id; // 4
+    bufferid_t buffer_id; // 8
+    lpaddr_t base; // 16
+    size_t length; // 24
+    uint64_t misc_flags; // 32
+    uint8_t pad[32];
+};
+
+struct descq {
+    // Shared memory of the queue
+    struct capref shm;
+    size_t slots;
+
+    // Queue pointers
+    size_t head;
+    size_t tail;
+
+    // The queue itself
+    struct desc* descs;
+};
+
+
+/**
+ * @brief initialized a descriptor queue
+ *
+ * @param q                     Return pointer to the descriptor queue
+ * @param shm                   Cap of the shared memory of the queue
+ * @param slots                 Number of slots in the queue
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t descq_init(struct descq** q,
+                    struct capref shm,
+                    size_t slots)
+{
+    USER_PANIC("NIY");
+    return SYS_ERR_OK;
+}
+
+/**
+ * @brief Destroys a descriptor queue and frees its resources
+ *
+ * @param q                     The descriptor queue
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t descq_destroy(struct descq* q)
+{
+    USER_PANIC("NIY");
+    return SYS_ERR_OK;
+}
+
+/**
+ * @brief Enqueue a descriptor (as seperate fields) 
+ *        into the descriptor queue
+ *
+ * @param q                     The descriptor queue
+ * @param region_id             Region id of the enqueued buffer
+ * @param buffer_id             Buffer id of the buffer
+ * @param base                  Physical address of hte buffer
+ * @param len                   Lenght of the buffer
+ * @param misc_flags            Miscellaneous flags
+ *
+ * @returns error if queue is full or SYS_ERR_OK on success
+ */
+errval_t descq_enqueue(struct descq* q,
+                       regionid_t region_id,
+                       bufferid_t buffer_id,
+                       lpaddr_t base,
+                       size_t len,
+                       uint64_t misc_flags)
+{
+    USER_PANIC("NIY");
+    return SYS_ERR_OK;
+}
+/**
+ * @brief Dequeue a descriptor (as seperate fields) 
+ *        from the descriptor queue
+ *
+ * @param q                     The descriptor queue
+ * @param region_id             Return pointer to the region id of 
+ *                              the denqueued buffer
+ * @param buffer_id             Return pointer to the buffer id of the buffer
+ * @param base                  Return pointer to the physical address 
+ *                              of the buffer
+ * @param len                   Return pointer to the lenght of the buffer
+ * @param misc_flags            Return pointer to miscellaneous flags
+ *
+ * @returns error if queue is empty or SYS_ERR_OK on success
+ */
+errval_t descq_dequeue(struct descq* q,
+                       regionid_t* region_id,
+                       bufferid_t* buffer_id,
+                       lpaddr_t* base,
+                       size_t* len,
+                       uint64_t* misc_flags)
+{
+    USER_PANIC("NIY");
+    return SYS_ERR_OK;
+}
+/**
+ * @brief Check if the descriptor queue is full
+ *
+ * @param q                     The descriptor queue
+ *
+ * @returns true if the queue is full, otherwise false
+ */
+bool descq_full(struct descq* q)
+{
+    USER_PANIC("NIY");
+    return false;
+}
+/**
+ * @brief Check if the descriptor queue is empty
+ *
+ * @param q                     The descriptor queue
+ *
+ * @returns true if the queue is empty, otherwise false
+ */
+bool descq_empty(struct descq* q)
+{
+    USER_PANIC("NIY");
+    return false;
+}
+/**
+ * @brief Returns the number of occupied slots in the queue
+ *
+ * @param q                     The descriptor queue
+ *
+ * @returns the number of occupied slots
+ */
+size_t descq_full_slots(struct descq* q)
+{
+    USER_PANIC("NIY");
+    return 0;
+}
diff --git a/lib/devif/desc_queue.h b/lib/devif/desc_queue.h
new file mode 100644 (file)
index 0000000..606e5a6
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2016 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+#ifndef DESCQ_H_
+#define DESCQ_H_ 1
+
+
+#include <barrelfish/barrelfish.h>
+#include <devif/queue_interface.h>
+
+#define DESCQ_DEFAULT_SIZE 64
+#define DESCQ_ALIGNMENT 64
+
+struct descq;
+/**
+ * @brief initialized a descriptor queue
+ *
+ * @param q                     Return pointer to the descriptor queue
+ * @param shm                   Cap of the shared memory of the queue
+ * @param slots                 Number of slots in the queue
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t descq_init(struct descq** q,
+                    struct capref shm,
+                    size_t slots);
+
+/**
+ * @brief Destroys a descriptor queue and frees its resources
+ *
+ * @param q                     The descriptor queue
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t descq_destroy(struct descq* q);
+
+/**
+ * @brief Enqueue a descriptor (as seperate fields) 
+ *        into the descriptor queue
+ *
+ * @param q                     The descriptor queue
+ * @param region_id             Region id of the enqueued buffer
+ * @param buffer_id             Buffer id of the buffer
+ * @param base                  Physical address of hte buffer
+ * @param len                   Lenght of the buffer
+ * @param misc_flags            Miscellaneous flags
+ *
+ * @returns error if queue is full or SYS_ERR_OK on success
+ */
+errval_t descq_enqueue(struct descq* q,
+                       regionid_t region_id,
+                       bufferid_t buffer_id,
+                       lpaddr_t base,
+                       size_t len,
+                       uint64_t misc_flags);
+
+/**
+ * @brief Dequeue a descriptor (as seperate fields) 
+ *        from the descriptor queue
+ *
+ * @param q                     The descriptor queue
+ * @param region_id             Return pointer to the region id of 
+ *                              the denqueued buffer
+ * @param buffer_id             Return pointer to the buffer id of the buffer
+ * @param base                  Return pointer to the physical address 
+ *                              of the buffer
+ * @param len                   Return pointer to the lenght of the buffer
+ * @param misc_flags            Return pointer to miscellaneous flags
+ *
+ * @returns error if queue is empty or SYS_ERR_OK on success
+ */
+errval_t descq_dequeue(struct descq* q,
+                       regionid_t* region_id,
+                       bufferid_t* buffer_id,
+                       lpaddr_t* base,
+                       size_t* len,
+                       uint64_t* misc_flags);
+
+/**
+ * @brief Check if the descriptor queue is full
+ *
+ * @param q                     The descriptor queue
+ *
+ * @returns true if the queue is full, otherwise false
+ */
+bool descq_full(struct descq* q);
+
+/**
+ * @brief Check if the descriptor queue is empty
+ *
+ * @param q                     The descriptor queue
+ *
+ * @returns true if the queue is empty, otherwise false
+ */
+bool descq_empty(struct descq* q);
+
+/**
+ * @brief Returns the number of occupied slots in the queue
+ *
+ * @param q                     The descriptor queue
+ *
+ * @returns the number of occupied slots
+ */
+size_t descq_full_slots(struct descq* q);
+
+#endif /* DESCQ_H_ */
index e589ab2..d828bed 100644 (file)
 #include <barrelfish/barrelfish.h>
 #include <devif/queue_interface.h>
 #include "region_pool.h"
+#include "desc_queue.h"
 #include "dqi_debug.h"
 
-#define DESCQ_SIZE 64
-#define DESCQ_ALIGNMENT 64
-
-struct __attribute__((aligned(DESCQ_ALIGNMENT))) descriptor {
-    regionid_t region_id; // 4
-    bufferid_t buffer_id; // 8
-    lpaddr_t base; // 16
-    size_t length; // 24
-    uint64_t misc_flags; // 32
-    uint8_t pad[32];
-};
 
 struct devq_func_pointer {
     devq_create_t create;
@@ -52,17 +42,9 @@ struct devq {
     // Function pointers for backend
     struct devq_func_pointer f;
 
-    // queue state 
-    uint16_t tx_head;
-    uint16_t tx_tail;
-
-    uint16_t rx_head;
-    uint16_t rx_tail;
-
-    // Queues themselves
-    struct descriptor rx[DESCQ_SIZE];
-    struct descriptor tx[DESCQ_SIZE];
-
+    // queues
+    struct descq* rx;
+    struct descq* tx;
     //TODO Other state needed ...
 };
 
@@ -92,14 +74,12 @@ errval_t devq_create(struct devq **q,
                      uint64_t flags)
 {
     errval_t err;
+    struct capref rx;
+    struct capref tx;
+
     struct devq* tmp = malloc(sizeof(struct devq));
     strncpy(tmp->device_name, device_name, MAX_DEVICE_NAME);
 
-    tmp->rx_head = 0;
-    tmp->tx_head = 0;
-    tmp->rx_tail = 0;
-    tmp->tx_tail = 0;
-    
     err = region_pool_init(&(tmp->pool));
     if (err_is_fail(err)) {
         free(tmp);
@@ -116,9 +96,32 @@ errval_t devq_create(struct devq **q,
 
     }
     
-    *q = tmp;
+    // Allocate shared memory
+    err = frame_alloc(&rx, DESCQ_DEFAULT_SIZE*DESCQ_ALIGNMENT, NULL); 
+    if (err_is_fail(err)) {
+        return err;
+    }   
+
+    err = frame_alloc(&tx, DESCQ_DEFAULT_SIZE*DESCQ_ALIGNMENT, NULL); 
+    if (err_is_fail(err)) {
+        return err;
+    }   
+
+    // Initialize rx/tx queues
+    err = descq_init(&(tmp->rx), rx, DESCQ_DEFAULT_SIZE);
+    if (err_is_fail(err)){
+        return err;
+    }   
+
+    err = descq_init(&(tmp->tx), tx, DESCQ_DEFAULT_SIZE);
+    if (err_is_fail(err)){
+        return err;
+    }   
+
+    // TODO send queue caps to other endpoint
     // TODO initalize device 
     // TODO initalize device state
+    *q = tmp;
     return SYS_ERR_OK;
 }
 
@@ -135,6 +138,16 @@ errval_t devq_destroy(struct devq *q)
 {
     errval_t err;
 
+    err = descq_destroy(q->rx);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    err = descq_destroy(q->tx);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
     err = region_pool_destroy(q->pool);
     if (err_is_fail(err)) {
         return err;
@@ -202,17 +215,6 @@ errval_t devq_enqueue(struct devq *q,
                       bufferid_t* buffer_id)
 {
     errval_t err;
-    size_t num_free = 0;
-
-    if (q->tx_head >= q->tx_tail) {
-       num_free = DESCQ_SIZE - (q->tx_head - q->tx_tail);
-    } else {
-       num_free = DESCQ_SIZE - (q->tx_head + DESCQ_SIZE - q->tx_tail);
-    }
-
-    if (num_free == 0) {
-        return DEVQ_ERR_TX_FULL;
-    }
 
     // Add buffer to used ones
     err = region_pool_get_buffer_id_from_region(q->pool, region_id, base,
@@ -221,12 +223,12 @@ errval_t devq_enqueue(struct devq *q,
         return DEVQ_ERR_BUFFER_ID;
     }
 
-    q->tx[q->tx_head].region_id = region_id;
-    q->tx[q->tx_head].base = base;
-    q->tx[q->tx_head].length = length;
-    q->tx[q->tx_head].buffer_id = *buffer_id;
-    q->tx[q->tx_head].misc_flags = misc_flags;
-    q->tx_head = q->tx_head + 1 % DESCQ_SIZE;    
+    // Enqueue into queue
+    err = descq_enqueue(q->tx, region_id, *buffer_id,
+                        base, length, misc_flags);
+    if (err_is_fail(err)) {
+        return err;
+    }
 
     return SYS_ERR_OK;
 }
@@ -255,48 +257,19 @@ errval_t devq_dequeue(struct devq *q,
                       uint64_t* misc_flags)
 {
     errval_t err;
-    size_t num_used = 0;
-    if (q->rx_head >= q->rx_tail) {
-       num_used = (q->rx_head - q->rx_tail);
-    } else {
-       num_used = (q->rx_head + DESCQ_SIZE - q->rx_tail);
-    }
-
-    if (num_used == 0) {
-        return DEVQ_ERR_RX_FULL;
-    }
 
-    *region_id = q->rx[q->rx_head].region_id;
-    *base = q->rx[q->rx_head].base;
-    *length = q->rx[q->rx_head].length;
-    *buffer_id = q->rx[q->rx_head].buffer_id;
-    *misc_flags = q->rx[q->rx_head].misc_flags;
-
-    q->rx_head = q->rx_head + 1 % DESCQ_SIZE;
-
-/*a
-    // Only uncomment for testing
-    if (q->tx_head >= q->tx_tail) {
-       num_used = (q->tx_head - q->tx_tail);
-    } else {
-       num_used = (q->tx_head + DESCQ_SIZE - q->tx_tail);
-    }
-    if (num_used == 0) {
-        return DEVQ_ERR_RX_FULL;
+    // Dequeue descriptor from descriptor queue
+    err = descq_dequeue(q->rx, region_id, buffer_id,
+                        base, length, misc_flags);
+    if (err_is_fail(err)) {
+        return err;
     }
-    *region_id = q->tx[q->tx_tail].region_id;
-    *base = q->tx[q->tx_tail].base;
-    *length = q->tx[q->tx_tail].length;
-    *buffer_id = q->tx[q->tx_tail].buffer_id;
-    *misc_flags = q->tx[q->tx_tail].misc_flags;
 
-    q->tx_tail = q->tx_tail + 1 % DESCQ_SIZE;
-*/
     // Add buffer to free ones
     err = region_pool_return_buffer_id_to_region(q->pool, *region_id,
                                                  *buffer_id);
     if (err_is_fail(err)) {
-        return DEVQ_ERR_BUFFER_ID;
+        return err;
     }
 
     return SYS_ERR_OK;