Kernel and roslib now use newlib's queue.h
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 9 Jun 2009 03:05:04 +0000 (20:05 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 9 Jun 2009 03:16:06 +0000 (20:16 -0700)
Newlib's queue.h remains unchanged.  The kernel and roslib use a
modified copy (with ivy annotations), but is otherwise the same
(specifically regarding typedefing).  roslib's sys/queue.h is actually a
symlink to the kernel's - can think about changing this.

Note that due to ros/env.h, the kernel and roslib need to have the same
include path to queue.h (sys/queue.h).  The env.h interface will change
shortly.

Also, changed the asynccall to use a TAILQ, and moved the userspace
specific syscall_desc list to userspace.

13 files changed:
include/arch/smp.h
include/env.h
include/pmap.h
include/ros/env.h
include/ros/memlayout.h
include/ros/queue.h [deleted file]
include/ros/syscall.h
include/sys/queue.h [new file with mode: 0644]
user/roslib/inc/lib.h
user/roslib/inc/queue.h [deleted file]
user/roslib/inc/sys/queue.h [new symlink]
user/roslib/inc/syswrapper.h
user/roslib/src/asynccall.c

index b1c8201..f0ddba9 100644 (file)
@@ -5,8 +5,6 @@
 
 #include <arch/types.h>
 
-#include <ros/queue.h>
-
 #include <atomic.h>
 #include <trap.h>
 #include <workqueue.h>
index cb1b577..7efc56a 100644 (file)
@@ -11,7 +11,8 @@ extern env_t *COUNT(NENV) envs;               // All environments
 extern uint32_t num_envs;              // Number of envs
 extern env_t* NORACE curenvs[MAX_NUM_CPUS];
 
-LIST_HEAD(env_list_t, env_t);          // Declares 'struct Env_list'
+LIST_HEAD(env_list, Env);              // Declares 'struct env_list'
+typedef struct env_list env_list_t;
 
 void   env_init(void);
 int            env_alloc(env_t **e, envid_t parent_id);
index f24d756..d9bf9c4 100644 (file)
@@ -6,13 +6,12 @@
 # error "This is a ROS kernel header; user programs should not #include it"
 #endif
 
-#include <arch/multiboot.h>
-
 #include <ros/memlayout.h>
-
+#include <arch/multiboot.h>
 #include <atomic.h>
 #include <env.h>
 #include <assert.h>
+#include <sys/queue.h>
 
 /* This macro takes a kernel virtual address -- an address that points above
  * KERNBASE, where the machine's maximum 256MB of physical memory is mapped --
@@ -50,8 +49,9 @@
 struct Page;
 typedef struct Page page_t;
 
-LIST_HEAD(page_list_t, page_t);
-typedef LIST_ENTRY(page_t) page_list_entry_t;
+LIST_HEAD(page_list, Page);
+typedef struct page_list page_list_t;
+typedef LIST_ENTRY(Page) page_list_entry_t;
 
 struct Page {
        page_list_entry_t pp_link;      /* free list link */
index 81dcf40..03f38e5 100644 (file)
@@ -3,11 +3,11 @@
 #ifndef ROS_INC_ENV_H
 #define ROS_INC_ENV_H
 
-#include <arch/types.h>
-#include <ros/queue.h>
 #include <ros/trap.h>
 #include <ros/memlayout.h>
 #include <ros/syscall.h>
+#include <arch/types.h>
+#include <sys/queue.h>
 
 struct Env;
 typedef struct Env env_t;
@@ -42,7 +42,7 @@ typedef int32_t envid_t;
 #define ENV_DYING                      4
 
 struct Env {
-       LIST_ENTRY(env_t) env_link NOINIT;      // Free list link pointers
+       LIST_ENTRY(Env) env_link NOINIT;        // Free list link pointers
        uint32_t lock;
        trapframe_t env_tf;                     // Saved registers
        envid_t env_id;                         // Unique environment identifier
index 24be641..11043ea 100644 (file)
@@ -4,7 +4,6 @@
 #ifndef __ASSEMBLER__
 #include <arch/types.h>
 #include <arch/mmu.h>
-#include <ros/queue.h>
 #endif /* not __ASSEMBLER__ */
 
 /*
diff --git a/include/ros/queue.h b/include/ros/queue.h
deleted file mode 100644 (file)
index c62fae3..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 1991, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *     @(#)queue.h     8.3 (Berkeley) 12/13/93
- *
- * For Jos, extra comments have been added to this file, and the original
- * TAILQ and CIRCLEQ definitions have been removed.   - August 9, 2005
- */
-
-#ifndef ROS_INC_QUEUE_H
-#define ROS_INC_QUEUE_H
-
-/*
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- */
-
-/*
- * An example using the below functions.
- */
-#if 0
-
-typedef struct Frob
-{
-       int frobozz;
-       LIST_ENTRY(frob_t) frob_link;   /* this contains the list element pointers */
-} frob_t;
-
-LIST_HEAD(frob_list_t, frob_t)         /* defines struct Frob_list as a list of Frob */
-
-frob_list_t flist;                     /* declare a Frob list */
-
-LIST_INIT(&flist);                     /* clear flist (globals are cleared anyway) */
-flist = LIST_HEAD_INITIALIZER(&flist); /* alternate way to clear flist */
-
-if(LIST_EMPTY(&flist))                 /* check whether list is empty */
-       printf("list is empty\n");
-
-frob_t *f = LIST_FIRST(&flist);        /* f is first element in list */
-f = LIST_NEXT(f, frob_link);           /* now f is next (second) element in list */
-f = LIST_NEXT(f, frob_link);           /* now f is next (third) element in list */
-
-for(f=LIST_FIRST(&flist); f != 0;      /* iterate over elements in flist */
-    f = LIST_NEXT(f, frob_link))
-       printf("f %d\n", f->frobozz);
-
-LIST_FOREACH(f, &flist, frob_link)     /* alternate way to say that */
-       printf("f %d\n", f->frobozz);
-
-f = LIST_NEXT(LIST_FIRST(&flist));     /* f is second element in list */
-LIST_INSERT_AFTER(f, g, frob_link);    /* add g right after f in list */
-LIST_REMOVE(g, frob_link);             /* remove g from list (can't insert twice!) */
-LIST_INSERT_BEFORE(f, g, frob_link);   /* add g right before f */
-LIST_REMOVE(g, frob_link);             /* remove g again */
-LIST_INSERT_HEAD(&flist, g, frob_link);        /* add g as first element in list */
-
-#endif
-
-/*
- * List declarations.
- */
-
-/*
- * A list is headed by a structure defined by the LIST_HEAD macro.  This structure con‐
- * tains a single pointer to the first element on the list.  The elements are doubly
- * linked so that an arbitrary element can be removed without traversing the list.  New
- * elements can be added to the list after an existing element or at the head of the list.
- * A LIST_HEAD structure is declared as follows:
- * 
- *       LIST_HEAD(HEADNAME, TYPE) head;
- * 
- * where HEADNAME is the name of the structure to be defined, and TYPE is the type of the
- * elements to be linked into the list.  A pointer to the head of the list can later be
- * declared as:
- * 
- *       HEADNAME *headp;
- * 
- * (The names head and headp are user selectable.)
- */
-#define        LIST_HEAD(name, type)                                   \
-typedef struct {                                                               \
-       type *SAFE lh_first;    /* first element */                     \
-       type *SAFE lh_last;     /* last element */                      \
-} name;
-
-/*
- * Set a list head variable to LIST_HEAD_INITIALIZER(head)
- * to reset it to the empty list.
- */
-#define        LIST_HEAD_INITIALIZER(head)                                     \
-       { NULL, NULL }
-
-/*
- * Use this inside a structure "LIST_ENTRY(type) field" to use
- * x as the list piece.
- *
- * The le_prev points at the pointer to the structure containing
- * this very LIST_ENTRY, so that if we want to remove this list entry,
- * we can do *le_prev = le_next to update the structure pointing at us.
- */
-#define        LIST_ENTRY(type)                                                \
-struct {                                                               \
-       type *le_next NOINIT;   /* next element */                      \
-       type **le_prev NOINIT;  /* ptr to ptr to this element */        \
-}
-
-/*
- * List functions.
- */
-
-/*
- * Is the list named "head" empty?
- */
-#define        LIST_EMPTY(head)        ((head)->lh_first == NULL)
-
-/*
- * Return the first element in the list named "head".
- */
-#define        LIST_FIRST(head)        ((head)->lh_first)
-
-/*
- * Return the last element in the list named "head".
- */
-#define        LIST_LAST(head) ((head)->lh_last)
-
-/*
- * Return the element after "elm" in the list.
- * The "field" name is the link element as above.
- */
-#define        LIST_NEXT(elm, field)   ((elm)->field.le_next)
-
-/*
- * Iterate over the elements in the list named "head".
- * During the loop, assign the list elements to the variable "var"
- * and use the LIST_ENTRY structure member "field" as the link field.
- */
-#define        LIST_FOREACH(var, head, field)                                  \
-       for ((var) = LIST_FIRST((head));                                \
-           (var);                                                      \
-           (var) = LIST_NEXT((var), field))
-
-/*
- * Reset the list named "head" to the empty list.
- */
-#define        LIST_INIT(head) do {                                            \
-       LIST_FIRST((head)) = NULL;                                      \
-       LIST_LAST((head)) = NULL;                                       \
-} while (0)
-
-/*
- * TODO : DON'T USE THIS because of tail pointer issues
- * Insert the element "elm" *after* the element "listelm" which is
- * already in the list.  The "field" name is the link element
- * as above.
-#define        LIST_INSERT_AFTER(listelm, elm, field) do {                     \
-       if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
-               LIST_NEXT((listelm), field)->field.le_prev =            \
-                   &LIST_NEXT((elm), field);                           \
-       LIST_NEXT((listelm), field) = (elm);                            \
-       (elm)->field.le_prev = &LIST_NEXT((listelm), field);            \
-} while (0)
- */
-
-/*
- * TODO : DON'T USE THIS because of tail pointer issues
- * Insert the element "elm" *after* the element "listelm" which is
- * Insert the element "elm" *before* the element "listelm" which is
- * already in the list.  The "field" name is the link element
- * as above.
-#define        LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
-       (elm)->field.le_prev = (listelm)->field.le_prev;                \
-       LIST_NEXT((elm), field) = (listelm);                            \
-       *(listelm)->field.le_prev = (elm);                              \
-       (listelm)->field.le_prev = &LIST_NEXT((elm), field);            \
-} while (0)
- */
-
-/*
- * Insert the element "elm" at the head of the list named "head".
- * The "field" name is the link element as above.
- */
-#define        LIST_INSERT_HEAD(head, elm, field) do {                         \
-       if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)     \
-               LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
-       else                                                       \
-               LIST_LAST((head)) = (elm);                                      \
-       LIST_FIRST((head)) = (elm);                                     \
-       (elm)->field.le_prev = &LIST_FIRST((head));                     \
-} while (0)
-
-/*
- * TODO : DO NOT USE THIS AFTER YOU'VE REMOVED AN ITEM!!
- * Insert the element "elm" at the tail of the list named "head".
- * The "field" name is the link element as above.
- * (you have been warned) ((sorry))
- */
-#define        LIST_INSERT_TAIL(head, elm, field) do {                                            \
-       if (LIST_EMPTY((head)))                                                    \
-               LIST_INSERT_HEAD((head), (elm), field);                                \
-       else {                                                                     \
-               (elm)->field.le_prev = &(LIST_LAST((head))->field.le_next);            \
-               LIST_LAST((head))->field.le_next = (elm);                              \
-               LIST_LAST((head)) = (elm);                                             \
-               (elm)->field.le_next = NULL;                                           \
-       }                                                                          \
-} while (0)
-
-/*
- * Remove the element "elm" from the list.
- * The "field" name is the link element as above.
- */
-#define        LIST_REMOVE(elm, field) do {                                    \
-       if (LIST_NEXT((elm), field) != NULL)                            \
-               LIST_NEXT((elm), field)->field.le_prev =                \
-                   (elm)->field.le_prev;                               \
-       *(elm)->field.le_prev = LIST_NEXT((elm), field);                \
-} while (0)
-
-#endif /* !_SYS_QUEUE_H_ */
index 521acc0..7fbbafc 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <arch/types.h>
 #include <ros/ring_buffer.h>
-#include <ros/queue.h>
 
 /* system call numbers */
 enum
@@ -48,15 +47,4 @@ typedef struct syscall_rsp {
 // Generic Syscall Ring Buffer
 DEFINE_RING_TYPES(syscall, syscall_req_t, syscall_rsp_t);
 
-typedef struct syscall_desc syscall_desc_t;
-struct syscall_desc {
-       LIST_ENTRY(syscall_desc_t) next;
-       syscall_front_ring_t* sysfr;
-       uint32_t idx;
-       // cleanup
-       void (*cleanup)(void* data);
-       void* data;
-};
-LIST_HEAD(syscall_desc_list_t, syscall_desc_t);
-
 #endif /* !ROS_INCLUDE_SYSCALL_H */
diff --git a/include/sys/queue.h b/include/sys/queue.h
new file mode 100644 (file)
index 0000000..205adf0
--- /dev/null
@@ -0,0 +1,482 @@
+/*
+ * Copyright (c) 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)queue.h     8.5 (Berkeley) 8/20/94
+ * $FreeBSD: src/sys/sys/queue.h,v 1.48 2002/04/17 14:00:37 tmm Exp $
+ *
+ * Minor changes for ROS and Ivy annotations (Berkeley: 2009-06-08)
+ */
+
+#ifndef ROS_INCLUDE_SYS_QUEUE_H
+#define ROS_INCLUDE_SYS_QUEUE_H
+
+//#include <machine/ansi.h>    /* for __offsetof */
+#include <arch/types.h>        /* for __offsetof */
+
+/*
+ * This file defines four types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists and tail queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction.  Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ *                     SLIST   LIST    STAILQ  TAILQ
+ * _HEAD               +       +       +       +
+ * _HEAD_INITIALIZER   +       +       +       +
+ * _ENTRY              +       +       +       +
+ * _INIT               +       +       +       +
+ * _EMPTY              +       +       +       +
+ * _FIRST              +       +       +       +
+ * _NEXT               +       +       +       +
+ * _PREV               -       -       -       +
+ * _LAST               -       -       +       +
+ * _FOREACH            +       +       +       +
+ * _FOREACH_REVERSE    -       -       -       +
+ * _INSERT_HEAD                +       +       +       +
+ * _INSERT_BEFORE      -       +       -       +
+ * _INSERT_AFTER       +       +       +       +
+ * _INSERT_TAIL                -       -       +       +
+ * _CONCAT             -       -       +       +
+ * _REMOVE_HEAD                +       -       +       -
+ * _REMOVE             +       +       +       +
+ *
+ */
+
+/*
+ * Ivy Annotations:
+ *     SAFE: pointers that only point to one item, and not an array.
+ *     NOINIT: items that do not need to be initialized in blocks of code that
+ *             initialize items, for which Ivy statically can check.
+ *     These haven't been tested much, just for the current uses of LIST and TAILQ
+ */
+
+/*
+ * Singly-linked List declarations.
+ */
+#define        SLIST_HEAD(name, type)                                          \
+struct name {                                                          \
+       struct type *SAFE slh_first;    /* first element */                     \
+}
+
+#define        SLIST_HEAD_INITIALIZER(head)                                    \
+       { NULL }
+#define        SLIST_ENTRY(type)                                               \
+struct {                                                               \
+       struct type *sle_next NOINIT;   /* next element */                      \
+}
+/*
+ * Singly-linked List functions.
+ */
+#define        SLIST_EMPTY(head)       ((head)->slh_first == NULL)
+
+#define        SLIST_FIRST(head)       ((head)->slh_first)
+
+#define        SLIST_FOREACH(var, head, field)                                 \
+       for ((var) = SLIST_FIRST((head));                               \
+           (var);                                                      \
+           (var) = SLIST_NEXT((var), field))
+
+#define        SLIST_INIT(head) do {                                           \
+       SLIST_FIRST((head)) = NULL;                                     \
+} while (0)
+
+#define        SLIST_INSERT_AFTER(slistelm, elm, field) do {                   \
+       SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);       \
+       SLIST_NEXT((slistelm), field) = (elm);                          \
+} while (0)
+
+#define        SLIST_INSERT_HEAD(head, elm, field) do {                        \
+       SLIST_NEXT((elm), field) = SLIST_FIRST((head));                 \
+       SLIST_FIRST((head)) = (elm);                                    \
+} while (0)
+
+#define        SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
+
+#define        SLIST_REMOVE(head, elm, type, field) do {                       \
+       if (SLIST_FIRST((head)) == (elm)) {                             \
+               SLIST_REMOVE_HEAD((head), field);                       \
+       }                                                               \
+       else {                                                          \
+               struct type *curelm = SLIST_FIRST((head));              \
+               while (SLIST_NEXT(curelm, field) != (elm))              \
+                       curelm = SLIST_NEXT(curelm, field);             \
+               SLIST_NEXT(curelm, field) =                             \
+                   SLIST_NEXT(SLIST_NEXT(curelm, field), field);       \
+       }                                                               \
+} while (0)
+
+#define        SLIST_REMOVE_HEAD(head, field) do {                             \
+       SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);   \
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define        STAILQ_HEAD(name, type)                                         \
+struct name {                                                          \
+       struct type *SAFE stqh_first;/* first element */                        \
+       struct type *SAFE*SAFE stqh_last;/* addr of last next element */                \
+}
+
+#define        STAILQ_HEAD_INITIALIZER(head)                                   \
+       { NULL, &(head).stqh_first }
+
+#define        STAILQ_ENTRY(type)                                              \
+struct {                                                               \
+       struct type *stqe_next NOINIT;  /* next element */                      \
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define        STAILQ_CONCAT(head1, head2) do {                                \
+       if (!STAILQ_EMPTY((head2))) {                                   \
+               *(head1)->stqh_last = (head2)->stqh_first;              \
+               (head1)->stqh_last = (head2)->stqh_last;                \
+               STAILQ_INIT((head2));                                   \
+       }                                                               \
+} while (0)
+
+#define        STAILQ_EMPTY(head)      ((head)->stqh_first == NULL)
+
+#define        STAILQ_FIRST(head)      ((head)->stqh_first)
+
+#define        STAILQ_FOREACH(var, head, field)                                \
+       for((var) = STAILQ_FIRST((head));                               \
+          (var);                                                       \
+          (var) = STAILQ_NEXT((var), field))
+
+#define        STAILQ_INIT(head) do {                                          \
+       STAILQ_FIRST((head)) = NULL;                                    \
+       (head)->stqh_last = &STAILQ_FIRST((head));                      \
+} while (0)
+
+#define        STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {               \
+       if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
+               (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
+       STAILQ_NEXT((tqelm), field) = (elm);                            \
+} while (0)
+
+#define        STAILQ_INSERT_HEAD(head, elm, field) do {                       \
+       if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
+               (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
+       STAILQ_FIRST((head)) = (elm);                                   \
+} while (0)
+
+#define        STAILQ_INSERT_TAIL(head, elm, field) do {                       \
+       STAILQ_NEXT((elm), field) = NULL;                               \
+       *(head)->stqh_last = (elm);                                     \
+       (head)->stqh_last = &STAILQ_NEXT((elm), field);                 \
+} while (0)
+
+#define        STAILQ_LAST(head, type, field)                                  \
+       (STAILQ_EMPTY((head)) ?                                         \
+               NULL :                                                  \
+               ((struct type *)                                        \
+               ((char *)((head)->stqh_last) - __offsetof(struct type, field))))
+
+#define        STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
+
+#define        STAILQ_REMOVE(head, elm, type, field) do {                      \
+       if (STAILQ_FIRST((head)) == (elm)) {                            \
+               STAILQ_REMOVE_HEAD((head), field);                      \
+       }                                                               \
+       else {                                                          \
+               struct type *curelm = STAILQ_FIRST((head));             \
+               while (STAILQ_NEXT(curelm, field) != (elm))             \
+                       curelm = STAILQ_NEXT(curelm, field);            \
+               if ((STAILQ_NEXT(curelm, field) =                       \
+                    STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
+                       (head)->stqh_last = &STAILQ_NEXT((curelm), field);\
+       }                                                               \
+} while (0)
+
+#define        STAILQ_REMOVE_HEAD(head, field) do {                            \
+       if ((STAILQ_FIRST((head)) =                                     \
+            STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)         \
+               (head)->stqh_last = &STAILQ_FIRST((head));              \
+} while (0)
+
+#define        STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {                 \
+       if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
+               (head)->stqh_last = &STAILQ_FIRST((head));              \
+} while (0)
+
+/*
+ * List declarations.
+ */
+#define        LIST_HEAD(name, type)                                           \
+struct name {                                                          \
+       struct type *SAFE lh_first;     /* first element */                     \
+}
+
+#define        LIST_HEAD_INITIALIZER(head)                                     \
+       { NULL }
+
+#define        LIST_ENTRY(type)                                                \
+struct {                                                               \
+       struct type *le_next NOINIT;    /* next element */                      \
+       struct type **le_prev NOINIT;   /* address of previous next element */  \
+}
+
+/*
+ * List functions.
+ */
+
+#define        LIST_EMPTY(head)        ((head)->lh_first == NULL)
+
+#define        LIST_FIRST(head)        ((head)->lh_first)
+
+#define        LIST_FOREACH(var, head, field)                                  \
+       for ((var) = LIST_FIRST((head));                                \
+           (var);                                                      \
+           (var) = LIST_NEXT((var), field))
+
+#define        LIST_INIT(head) do {                                            \
+       LIST_FIRST((head)) = NULL;                                      \
+} while (0)
+
+#define        LIST_INSERT_AFTER(listelm, elm, field) do {                     \
+       if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
+               LIST_NEXT((listelm), field)->field.le_prev =            \
+                   &LIST_NEXT((elm), field);                           \
+       LIST_NEXT((listelm), field) = (elm);                            \
+       (elm)->field.le_prev = &LIST_NEXT((listelm), field);            \
+} while (0)
+
+#define        LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
+       (elm)->field.le_prev = (listelm)->field.le_prev;                \
+       LIST_NEXT((elm), field) = (listelm);                            \
+       *(listelm)->field.le_prev = (elm);                              \
+       (listelm)->field.le_prev = &LIST_NEXT((elm), field);            \
+} while (0)
+
+#define        LIST_INSERT_HEAD(head, elm, field) do {                         \
+       if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)     \
+               LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
+       LIST_FIRST((head)) = (elm);                                     \
+       (elm)->field.le_prev = &LIST_FIRST((head));                     \
+} while (0)
+
+#define        LIST_NEXT(elm, field)   ((elm)->field.le_next)
+
+#define        LIST_REMOVE(elm, field) do {                                    \
+       if (LIST_NEXT((elm), field) != NULL)                            \
+               LIST_NEXT((elm), field)->field.le_prev =                \
+                   (elm)->field.le_prev;                               \
+       *(elm)->field.le_prev = LIST_NEXT((elm), field);                \
+} while (0)
+
+/*
+ * Tail queue declarations.
+ */
+#define        TAILQ_HEAD(name, type)                                          \
+struct name {                                                          \
+       struct type *SAFE tqh_first;    /* first element */                     \
+       struct type *SAFE*SAFE tqh_last;        /* addr of last next element */         \
+}
+
+#define        TAILQ_HEAD_INITIALIZER(head)                                    \
+       { NULL, &(head).tqh_first }
+
+#define        TAILQ_ENTRY(type)                                               \
+struct {                                                               \
+       struct type *tqe_next NOINIT;   /* next element */                      \
+       struct type **tqe_prev NOINIT;  /* address of previous next element */  \
+}
+
+/*
+ * Tail queue functions.
+ */
+#define        TAILQ_CONCAT(head1, head2, field) do {                          \
+       if (!TAILQ_EMPTY(head2)) {                                      \
+               *(head1)->tqh_last = (head2)->tqh_first;                \
+               (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
+               (head1)->tqh_last = (head2)->tqh_last;                  \
+               TAILQ_INIT((head2));                                    \
+       }                                                               \
+} while (0)
+
+#define        TAILQ_EMPTY(head)       ((head)->tqh_first == NULL)
+
+#define        TAILQ_FIRST(head)       ((head)->tqh_first)
+
+#define        TAILQ_FOREACH(var, head, field)                                 \
+       for ((var) = TAILQ_FIRST((head));                               \
+           (var);                                                      \
+           (var) = TAILQ_NEXT((var), field))
+
+#define        TAILQ_FOREACH_REVERSE(var, head, headname, field)               \
+       for ((var) = TAILQ_LAST((head), headname);                      \
+           (var);                                                      \
+           (var) = TAILQ_PREV((var), headname, field))
+
+#define        TAILQ_INIT(head) do {                                           \
+       TAILQ_FIRST((head)) = NULL;                                     \
+       (head)->tqh_last = &TAILQ_FIRST((head));                        \
+} while (0)
+
+#define        TAILQ_INSERT_AFTER(head, listelm, elm, field) do {              \
+       if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
+               TAILQ_NEXT((elm), field)->field.tqe_prev =              \
+                   &TAILQ_NEXT((elm), field);                          \
+       else                                                            \
+               (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
+       TAILQ_NEXT((listelm), field) = (elm);                           \
+       (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);          \
+} while (0)
+
+#define        TAILQ_INSERT_BEFORE(listelm, elm, field) do {                   \
+       (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
+       TAILQ_NEXT((elm), field) = (listelm);                           \
+       *(listelm)->field.tqe_prev = (elm);                             \
+       (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);          \
+} while (0)
+
+#define        TAILQ_INSERT_HEAD(head, elm, field) do {                        \
+       if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)   \
+               TAILQ_FIRST((head))->field.tqe_prev =                   \
+                   &TAILQ_NEXT((elm), field);                          \
+       else                                                            \
+               (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
+       TAILQ_FIRST((head)) = (elm);                                    \
+       (elm)->field.tqe_prev = &TAILQ_FIRST((head));                   \
+} while (0)
+
+#define        TAILQ_INSERT_TAIL(head, elm, field) do {                        \
+       TAILQ_NEXT((elm), field) = NULL;                                \
+       (elm)->field.tqe_prev = (head)->tqh_last;                       \
+       *(head)->tqh_last = (elm);                                      \
+       (head)->tqh_last = &TAILQ_NEXT((elm), field);                   \
+} while (0)
+
+#define        TAILQ_LAST(head, headname)                                      \
+       (*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define        TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define        TAILQ_PREV(elm, headname, field)                                \
+       (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define        TAILQ_REMOVE(head, elm, field) do {                             \
+       if ((TAILQ_NEXT((elm), field)) != NULL)                         \
+               TAILQ_NEXT((elm), field)->field.tqe_prev =              \
+                   (elm)->field.tqe_prev;                              \
+       else                                                            \
+               (head)->tqh_last = (elm)->field.tqe_prev;               \
+       *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);              \
+} while (0)
+
+
+#ifdef _KERNEL
+
+/*
+ * XXX insque() and remque() are an old way of handling certain queues.
+ * They bogusly assumes that all queue heads look alike.
+ */
+
+struct quehead {
+       struct quehead *qh_link;
+       struct quehead *qh_rlink;
+};
+
+#ifdef __GNUC__
+
+static __inline void
+insque(void *a, void *b)
+{
+       struct quehead *element = (struct quehead *)a,
+                *head = (struct quehead *)b;
+
+       element->qh_link = head->qh_link;
+       element->qh_rlink = head;
+       head->qh_link = element;
+       element->qh_link->qh_rlink = element;
+}
+
+static __inline void
+remque(void *a)
+{
+       struct quehead *element = (struct quehead *)a;
+
+       element->qh_link->qh_rlink = element->qh_rlink;
+       element->qh_rlink->qh_link = element->qh_link;
+       element->qh_rlink = 0;
+}
+
+#else /* !__GNUC__ */
+
+void   insque(void *a, void *b);
+void   remque(void *a);
+
+#endif /* __GNUC__ */
+
+#endif /* _KERNEL */
+
+#endif /* ROS_INCLUDE_SYS_QUEUE_H */
index 26ceec0..d9a85da 100644 (file)
 #include <arch/types.h>
 #include <arch/timer.h>
 #include <ros/error.h>
-#include <stdarg.h>
-#include <string.h>
-#include <pool.h>
-
 #include <ros/memlayout.h>
 #include <ros/syscall.h>
 #include <ros/env.h>
 
+#include <stdarg.h>
+#include <string.h>
+#include <pool.h>
+#include <sys/queue.h>
+
 #define USED(x)                (void)(x)
 
 // libos.c or entry.S
@@ -30,6 +31,23 @@ extern volatile uint8_t (COUNT(PGSIZE * UDATA_PAGES) procdata)[];
 extern syscall_front_ring_t sysfrontring;
 void exit(void) __attribute__((noreturn));
 
+/*
+ * Syscall Descriptor: This helps userspace track a specific syscall.  Includes
+ * a cleanup function to be run when this syscall is complete.  Linked list of
+ * these for now. (Tail Queue)
+ */
+typedef struct syscall_desc syscall_desc_t;
+struct syscall_desc {
+       TAILQ_ENTRY(syscall_desc) next;
+       syscall_front_ring_t* sysfr;
+       uint32_t idx;
+       // cleanup
+       void (*cleanup)(void* data);
+       void* data;
+};
+TAILQ_HEAD(syscall_desc_list, syscall_desc);
+typedef struct syscall_desc_list syscall_desc_list_t;
+
 // syscall.c
 void        sys_null();
 error_t     sys_null_async(syscall_desc_t* desc);
diff --git a/user/roslib/inc/queue.h b/user/roslib/inc/queue.h
deleted file mode 100644 (file)
index 1102ed4..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 1991, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *     @(#)queue.h     8.3 (Berkeley) 12/13/93
- *
- * For Jos, extra comments have been added to this file, and the original
- * TAILQ and CIRCLEQ definitions have been removed.   - August 9, 2005
- */
-
-#ifndef ROS_INC_QUEUE_H
-#define ROS_INC_QUEUE_H
-
-/*
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- */
-
-/*
- * An example using the below functions.
- */
-#if 0
-
-typedef struct Frob
-{
-       int frobozz;
-       LIST_ENTRY(frob_t) frob_link;   /* this contains the list element pointers */
-} frob_t;
-
-LIST_HEAD(frob_list_t, frob_t)         /* defines struct Frob_list as a list of Frob */
-
-frob_list_t flist;                     /* declare a Frob list */
-
-LIST_INIT(&flist);                     /* clear flist (globals are cleared anyway) */
-flist = LIST_HEAD_INITIALIZER(&flist); /* alternate way to clear flist */
-
-if(LIST_EMPTY(&flist))                 /* check whether list is empty */
-       printf("list is empty\n");
-
-frob_t *f = LIST_FIRST(&flist);        /* f is first element in list */
-f = LIST_NEXT(f, frob_link);           /* now f is next (second) element in list */
-f = LIST_NEXT(f, frob_link);           /* now f is next (third) element in list */
-
-for(f=LIST_FIRST(&flist); f != 0;      /* iterate over elements in flist */
-    f = LIST_NEXT(f, frob_link))
-       printf("f %d\n", f->frobozz);
-
-LIST_FOREACH(f, &flist, frob_link)     /* alternate way to say that */
-       printf("f %d\n", f->frobozz);
-
-f = LIST_NEXT(LIST_FIRST(&flist));     /* f is second element in list */
-LIST_INSERT_AFTER(f, g, frob_link);    /* add g right after f in list */
-LIST_REMOVE(g, frob_link);             /* remove g from list (can't insert twice!) */
-LIST_INSERT_BEFORE(f, g, frob_link);   /* add g right before f */
-LIST_REMOVE(g, frob_link);             /* remove g again */
-LIST_INSERT_HEAD(&flist, g, frob_link);        /* add g as first element in list */
-
-#endif
-
-/*
- * List declarations.
- */
-
-/*
- * A list is headed by a structure defined by the LIST_HEAD macro.  This structure con‐
- * tains a single pointer to the first element on the list.  The elements are doubly
- * linked so that an arbitrary element can be removed without traversing the list.  New
- * elements can be added to the list after an existing element or at the head of the list.
- * A LIST_HEAD structure is declared as follows:
- * 
- *       LIST_HEAD(HEADNAME, TYPE) head;
- * 
- * where HEADNAME is the name of the structure to be defined, and TYPE is the type of the
- * elements to be linked into the list.  A pointer to the head of the list can later be
- * declared as:
- * 
- *       HEADNAME *headp;
- * 
- * (The names head and headp are user selectable.)
- */
-#define        LIST_HEAD(name, type)                                   \
-typedef struct {                                                               \
-       type *lh_first; /* first element */                     \
-       type *lh_last;  /* last element */                      \
-} name;
-
-/*
- * Set a list head variable to LIST_HEAD_INITIALIZER(head)
- * to reset it to the empty list.
- */
-#define        LIST_HEAD_INITIALIZER(head)                                     \
-       { NULL, NULL }
-
-/*
- * Use this inside a structure "LIST_ENTRY(type) field" to use
- * x as the list piece.
- *
- * The le_prev points at the pointer to the structure containing
- * this very LIST_ENTRY, so that if we want to remove this list entry,
- * we can do *le_prev = le_next to update the structure pointing at us.
- */
-#define        LIST_ENTRY(type)                                                \
-struct {                                                               \
-       type *le_next;  /* next element */                      \
-       type **le_prev; /* ptr to ptr to this element */        \
-}
-
-/*
- * List functions.
- */
-
-/*
- * Is the list named "head" empty?
- */
-#define        LIST_EMPTY(head)        ((head)->lh_first == NULL)
-
-/*
- * Return the first element in the list named "head".
- */
-#define        LIST_FIRST(head)        ((head)->lh_first)
-
-/*
- * Return the last element in the list named "head".
- */
-#define        LIST_LAST(head) ((head)->lh_last)
-
-/*
- * Return the element after "elm" in the list.
- * The "field" name is the link element as above.
- */
-#define        LIST_NEXT(elm, field)   ((elm)->field.le_next)
-
-/*
- * Iterate over the elements in the list named "head".
- * During the loop, assign the list elements to the variable "var"
- * and use the LIST_ENTRY structure member "field" as the link field.
- */
-#define        LIST_FOREACH(var, head, field)                                  \
-       for ((var) = LIST_FIRST((head));                                \
-           (var);                                                      \
-           (var) = LIST_NEXT((var), field))
-
-/*
- * Reset the list named "head" to the empty list.
- */
-#define        LIST_INIT(head) do {                                            \
-       LIST_FIRST((head)) = NULL;                                      \
-       LIST_LAST((head)) = NULL;                                       \
-} while (0)
-
-/*
- * TODO : DON'T USE THIS because of tail pointer issues
- * Insert the element "elm" *after* the element "listelm" which is
- * already in the list.  The "field" name is the link element
- * as above.
-#define        LIST_INSERT_AFTER(listelm, elm, field) do {                     \
-       if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
-               LIST_NEXT((listelm), field)->field.le_prev =            \
-                   &LIST_NEXT((elm), field);                           \
-       LIST_NEXT((listelm), field) = (elm);                            \
-       (elm)->field.le_prev = &LIST_NEXT((listelm), field);            \
-} while (0)
- */
-
-/*
- * TODO : DON'T USE THIS because of tail pointer issues
- * Insert the element "elm" *after* the element "listelm" which is
- * Insert the element "elm" *before* the element "listelm" which is
- * already in the list.  The "field" name is the link element
- * as above.
-#define        LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
-       (elm)->field.le_prev = (listelm)->field.le_prev;                \
-       LIST_NEXT((elm), field) = (listelm);                            \
-       *(listelm)->field.le_prev = (elm);                              \
-       (listelm)->field.le_prev = &LIST_NEXT((elm), field);            \
-} while (0)
- */
-
-/*
- * Insert the element "elm" at the head of the list named "head".
- * The "field" name is the link element as above.
- */
-#define        LIST_INSERT_HEAD(head, elm, field) do {                         \
-       if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)     \
-               LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
-       else                                                       \
-               LIST_LAST((head)) = (elm);                                      \
-       LIST_FIRST((head)) = (elm);                                     \
-       (elm)->field.le_prev = &LIST_FIRST((head));                     \
-} while (0)
-
-/*
- * TODO : DO NOT USE THIS AFTER YOU'VE REMOVED AN ITEM!!
- * Insert the element "elm" at the tail of the list named "head".
- * The "field" name is the link element as above.
- * (you have been warned) ((sorry))
- */
-#define        LIST_INSERT_TAIL(head, elm, field) do {                                            \
-       if (LIST_EMPTY((head)))                                                    \
-               LIST_INSERT_HEAD((head), (elm), field);                                \
-       else {                                                                     \
-               (elm)->field.le_prev = &(LIST_LAST((head))->field.le_next);            \
-               LIST_LAST((head))->field.le_next = (elm);                              \
-               LIST_LAST((head)) = (elm);                                             \
-               (elm)->field.le_next = NULL;                                           \
-       }                                                                          \
-} while (0)
-
-/*
- * Remove the element "elm" from the list.
- * The "field" name is the link element as above.
- */
-#define        LIST_REMOVE(elm, field) do {                                    \
-       if (LIST_NEXT((elm), field) != NULL)                            \
-               LIST_NEXT((elm), field)->field.le_prev =                \
-                   (elm)->field.le_prev;                               \
-       *(elm)->field.le_prev = LIST_NEXT((elm), field);                \
-} while (0)
-
-#endif /* !_SYS_QUEUE_H_ */
diff --git a/user/roslib/inc/sys/queue.h b/user/roslib/inc/sys/queue.h
new file mode 120000 (symlink)
index 0000000..b10dea5
--- /dev/null
@@ -0,0 +1 @@
+../../../../include/sys/queue.h
\ No newline at end of file
index 4cc24d7..509c7e5 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef ROS_INC_NULL_H
 #define ROS_INC_NULL_H
 
+#include <lib.h>
+
 void null();
 error_t null_async(async_desc_t** desc);
 void cache_buster(uint32_t num_writes, uint32_t num_pages, uint32_t flags);
index ff03896..688c70f 100644 (file)
@@ -3,7 +3,6 @@
 #endif
 
 #include <lib.h>
-#include <queue.h>
 #include <ros/syscall.h>
 
 // Wait on all syscalls within this async call.  TODO - timeout or something?
@@ -14,8 +13,8 @@ error_t waiton_async_call(async_desc_t* desc, async_rsp_t* rsp)
        error_t err = 0;
        if (!desc)
                return -E_INVAL;
-       while (!(LIST_EMPTY(&desc->syslist))) {
-               d = LIST_FIRST(&desc->syslist);
+       while (!(TAILQ_EMPTY(&desc->syslist))) {
+               d = TAILQ_FIRST(&desc->syslist);
                err = MIN(waiton_syscall(d, &syscall_rsp), err);
                // TODO: processing the retval out of rsp here.  might be specific to
                // the async call.  do we want to accumulate?  return any negative
@@ -25,7 +24,7 @@ error_t waiton_async_call(async_desc_t* desc, async_rsp_t* rsp)
                //rsp->retval += syscall_rsp.retval; // For example
                rsp->retval = MIN(rsp->retval, syscall_rsp.retval);
                // remove from the list and free the syscall desc
-               LIST_REMOVE(d, next);
+               TAILQ_REMOVE(&desc->syslist, d, next);
                POOL_PUT(&syscall_desc_pool, d);
        }
        // run a cleanup function for this desc, if available
@@ -40,9 +39,11 @@ error_t waiton_async_call(async_desc_t* desc, async_rsp_t* rsp)
 async_desc_t* get_async_desc(void)
 {
        async_desc_t* desc = POOL_GET(&async_desc_pool);
-       if (desc)
+       if (desc) {
                // Clear out any data that was in the old desc
                memset(desc, 0, sizeof(*desc));
+               TAILQ_INIT(&desc->syslist);
+       }
        return desc;
 }
 
@@ -54,7 +55,7 @@ syscall_desc_t* get_sys_desc(async_desc_t* desc)
        if (d) {
                // Clear out any data that was in the old desc
                memset(d, 0, sizeof(*d));
-       LIST_INSERT_TAIL(&desc->syslist, d, next);
+       TAILQ_INSERT_TAIL(&desc->syslist, d, next);
        }
        return d;
 }