summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2015-07-11 13:27:58 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2015-07-11 13:38:45 +0200
commit2ba043d04468261cc767a3b91cec6df4b2238950 (patch)
tree4162bd71db9d4e4ead209af5d5595805e78abe39
parente59f05e940643350bb3813e5b7f18f9fe54806f6 (diff)
kern: make sure the queue macros are only used on queues
This turns mistakes as the one corrected in e59f05e9 into compile-time errors. * kern/queue.h: Add a new macro, queue_assert, and use it to assert that all arguments given to the queue macros have the correct type. * device/net_io.c (ENQUEUE_DEAD): Adapt to the fact that `queue_next(q)' is no longer an lvalue.
-rw-r--r--device/net_io.c2
-rw-r--r--kern/queue.h31
2 files changed, 27 insertions, 6 deletions
diff --git a/device/net_io.c b/device/net_io.c
index d2928cc..47ef2ea 100644
--- a/device/net_io.c
+++ b/device/net_io.c
@@ -353,7 +353,7 @@ decl_simple_lock_data(,net_hash_header_lock)
/* entry_p must be net_rcv_port_t or net_hash_entry_t */
#define ENQUEUE_DEAD(dead, entry_p, chain) { \
- queue_next(&(entry_p)->chain) = (queue_entry_t) (dead); \
+ (entry_p)->chain.next = (queue_entry_t) (dead); \
(dead) = (queue_entry_t)(entry_p); \
}
diff --git a/kern/queue.h b/kern/queue.h
index 518084d..f0b4002 100644
--- a/kern/queue.h
+++ b/kern/queue.h
@@ -87,6 +87,14 @@ void remqueue(queue_t, queue_entry_t);
void insque(queue_entry_t, queue_entry_t);
/*
+ * Macro: queue_assert
+ * Function:
+ * Used by macros to assert that the given argument is a
+ * queue.
+ */
+#define queue_assert(q) (void) ((void) (q)->next, (q)->prev)
+
+/*
* Macro: queue_init
* Function:
* Initialize the given queue.
@@ -104,7 +112,7 @@ void insque(queue_entry_t, queue_entry_t);
* queue_entry_t queue_first(q)
* queue_t q; *IN*
*/
-#define queue_first(q) ((q)->next)
+#define queue_first(q) (queue_assert(q), (q)->next)
/*
* Macro: queue_next
@@ -114,7 +122,7 @@ void insque(queue_entry_t, queue_entry_t);
* queue_entry_t queue_next(qc)
* queue_t qc;
*/
-#define queue_next(qc) ((qc)->next)
+#define queue_next(qc) (queue_assert(qc), (qc)->next)
/*
* Macro: queue_last
@@ -124,7 +132,7 @@ void insque(queue_entry_t, queue_entry_t);
* queue_entry_t queue_last(q)
* queue_t q; *IN*
*/
-#define queue_last(q) ((q)->prev)
+#define queue_last(q) (queue_assert(q), (q)->prev)
/*
* Macro: queue_prev
@@ -134,7 +142,7 @@ void insque(queue_entry_t, queue_entry_t);
* queue_entry_t queue_prev(qc)
* queue_t qc;
*/
-#define queue_prev(qc) ((qc)->prev)
+#define queue_prev(qc) (queue_assert(qc), (qc)->prev)
/*
* Macro: queue_end
@@ -146,7 +154,8 @@ void insque(queue_entry_t, queue_entry_t);
* queue_t q;
* queue_entry_t qe;
*/
-#define queue_end(q, qe) ((q) == (qe))
+#define queue_end(q, qe) (queue_assert(q), queue_assert(qe), \
+ (q) == (qe))
/*
* Macro: queue_empty
@@ -179,6 +188,8 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_enter(head, elt, type, field) \
{ \
+ queue_assert(head); \
+ queue_assert(&(elt)->field); \
queue_entry_t prev; \
\
prev = (head)->prev; \
@@ -206,6 +217,8 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_enter_first(head, elt, type, field) \
{ \
+ queue_assert(head); \
+ queue_assert(&(elt)->field); \
queue_entry_t next; \
\
next = (head)->next; \
@@ -239,6 +252,8 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_remove(head, elt, type, field) \
{ \
+ queue_assert(head); \
+ queue_assert(&(elt)->field); \
queue_entry_t next, prev; \
\
next = (elt)->field.next; \
@@ -266,6 +281,8 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_remove_first(head, entry, type, field) \
{ \
+ queue_assert(head); \
+ queue_assert(&(entry)->field); \
queue_entry_t next; \
\
(entry) = (type) ((head)->next); \
@@ -289,6 +306,8 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_remove_last(head, entry, type, field) \
{ \
+ queue_assert(head); \
+ queue_assert(&(entry)->field); \
queue_entry_t prev; \
\
(entry) = (type) ((head)->prev); \
@@ -306,6 +325,8 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_assign(to, from, type, field) \
{ \
+ queue_assert(&(to)->field); \
+ queue_assert(&(from)->field); \
((type)((from)->prev))->field.next = (to); \
((type)((from)->next))->field.prev = (to); \
*to = *from; \