Commit ce6f95a6 authored by Niels Möller's avatar Niels Möller
Browse files

* src/queue.c (object_queue_init): New function.

(object_queue_is_empty): New function.
(object_queue_add_head): Update length.
(object_queue_add_tail): -"-
(object_queue_remove_head): -"-
(object_queue_remove_tail): -"-
(queue_to_list): New function.
(object_queue_kill): New function.

* src/queue.h (object_queue): Added length attribute.
(FOR_OBJECT_QUEUE_REMOVE): Update length.

Rev: src/queue.c:1.7
Rev: src/queue.h:1.6
parent c4fcd356
......@@ -32,7 +32,7 @@
/* Prototypes */
static void do_object_queue_mark(struct lsh_queue *q,
void (*mark)(struct lsh_object *o));
void (*mark)(struct lsh_object *o));
static void do_object_queue_free(struct lsh_queue *q);
#define GABA_DEFINE
......@@ -47,23 +47,37 @@ static void do_object_queue_free(struct lsh_queue *q);
#define tail ht_links[LSH_QUEUE_TAIL]
#define tailprev ht_links[LSH_QUEUE_TAILPREV]
#define EMPTYP(q) ((q)->tailprev == (struct lsh_queue_node *) (q))
#define EMPTYP(q) ((q)->tailprev == (struct lsh_queue_node *) &(q)->head)
/* #define EMPTYP(q) (!(q)->length) */
#if DEBUG_ALLOC
static void sanity_check_queue(struct lsh_queue *q)
{
struct lsh_queue_node *n;
#if 0
UINT32 count;
#endif
#if 0
debug("sanity_check_queue: q = %xi\n", (UINT32) q);
#endif
#if 0
if (EMPTYP(q) != EMPTYP_1(q))
fatal("inconsistent emptyness!\n");
count = 0;
#endif
if (q->tail)
fatal("sanity_check_queue: q->tail not NULL!\n");
n = q->head;
if (n->prev != (struct lsh_queue_node *) q)
fatal("sanity_check_queue: head->next != &q->head !\n");
if (n->prev != (struct lsh_queue_node *) &q->head)
fatal("sanity_check_queue: head->prev != &q->head !\n");
while (n->next)
{
......@@ -74,9 +88,18 @@ static void sanity_check_queue(struct lsh_queue *q)
fatal("n->prev->next != n !\n");
n = n->next;
#if 0
count++;
#endif
}
if (n != (struct lsh_queue_node *) &(q->tail))
fatal("n != n &t->tail!\n");
#if 0
if (count != (q->length + 1))
fatal("incorrect length!\n");
#endif
}
#else
#define sanity_check_queue(x)
......@@ -103,6 +126,7 @@ void lsh_queue_add_head(struct lsh_queue *q, struct lsh_queue_node *n)
n->prev = (struct lsh_queue_node *) &(q->head);
n->prev->next = n;
n->next->prev = n;
sanity_check_queue(q);
}
......@@ -113,6 +137,7 @@ void lsh_queue_add_tail(struct lsh_queue *q, struct lsh_queue_node *n)
n->prev = q->tailprev;
n->prev->next = n;
n->next->prev = n;
sanity_check_queue(q);
}
......@@ -158,6 +183,8 @@ struct lsh_queue_node *lsh_queue_peek_tail(struct lsh_queue *q)
return EMPTYP(q) ? NULL : q->tailprev;
}
/* object_queue */
static struct object_queue_node *
make_object_queue_node(struct lsh_object *o)
{
......@@ -169,14 +196,29 @@ make_object_queue_node(struct lsh_object *o)
return n;
}
void object_queue_init(struct object_queue *q)
{
lsh_queue_init(&q->q);
q->length = 0;
}
int object_queue_is_empty(struct object_queue *q)
{
assert(EMPTYP(&q->q) == !q->length);
return !q->length;
}
void object_queue_add_head(struct object_queue *q, struct lsh_object *o)
{
lsh_queue_add_head(&q->q, &make_object_queue_node(o)->header);
q->length++;
}
void object_queue_add_tail(struct object_queue *q, struct lsh_object *o)
{
lsh_queue_add_tail(&q->q, &make_object_queue_node(o)->header);
q->length++;
}
static struct lsh_object *
......@@ -198,11 +240,13 @@ object_queue_peek(struct lsh_queue_node *n)
struct lsh_object *object_queue_remove_head(struct object_queue *q)
{
q->length--;
return object_queue_get_contents(lsh_queue_remove_head(&q->q));
}
struct lsh_object *object_queue_remove_tail(struct object_queue *q)
{
q->length--;
return object_queue_get_contents(lsh_queue_remove_tail(&q->q));
}
......@@ -216,6 +260,20 @@ struct lsh_object *object_queue_peek_tail(struct object_queue *q)
return EMPTYP(&q->q) ? NULL : object_queue_peek(q->q.tailprev);
}
struct object_list *queue_to_list(struct object_queue *q)
{
struct object_list *l = alloc_object_list(q->length);
UINT32 i = 0;
FOR_OBJECT_QUEUE(q, n)
{
LIST(l)[i++] = n;
}
assert(i == q->length);
return l;
}
/* For gc */
static void do_object_queue_mark(struct lsh_queue *q,
void (*mark)(struct lsh_object *o))
......@@ -230,4 +288,9 @@ static void do_object_queue_free(struct lsh_queue *q)
lsh_space_free(n);
}
void object_queue_kill(struct object_queue *q)
{
do_object_queue_free(&q->q);
}
......@@ -28,6 +28,8 @@
#include "lsh.h"
#include "list.h"
/* Layout taken from AmigaOS lists... The first node uses a prev
* pointer that points to the queue's HEAD. The last node uses a next
* pointer that points to the queue's TAIL field. The TAIL field is
......@@ -84,12 +86,18 @@ struct object_queue_node
(struct
(name object_queue)
(vars
(length . UINT32)
(q special-struct "struct lsh_queue"
do_object_queue_mark do_object_queue_free)))
*/
#if 0
#define object_queue_is_empty(x) (lsh_queue_is_empty(&(x)->q))
#define object_queue_init(x) (lsh_queue_init(&(x)->q))
#endif
void object_queue_init(struct object_queue *q);
int object_queue_is_empty(struct object_queue *q);
void object_queue_add_head(struct object_queue *q, struct lsh_object *o);
void object_queue_add_tail(struct object_queue *q, struct lsh_object *o);
......@@ -99,6 +107,14 @@ struct lsh_object *object_queue_remove_tail(struct object_queue *q);
struct lsh_object *object_queue_peek_head(struct object_queue *q);
struct lsh_object *object_queue_peek_tail(struct object_queue *q);
/* For explicitly allocated object queues, which are not included in a
* garbage collected object. */
void object_queue_kill(struct object_queue *q);
#define KILL_OBJECT_QUEUE(q) object_queue_kill((q))
struct object_list *queue_to_list(struct object_queue *q);
#define FOR_OBJECT_QUEUE(oq, n) \
struct lsh_queue_node *n##_this, *n##_next; \
struct lsh_object *n; \
......@@ -110,6 +126,7 @@ struct lsh_object *object_queue_peek_tail(struct object_queue *q);
/* NOTE: You should probably use break or perhaps continue after removing the current node. */
/* FIXME: This name is rather ugly. */
#define FOR_OBJECT_QUEUE_REMOVE(n) (lsh_queue_remove(n##_this))
#define FOR_OBJECT_QUEUE_REMOVE(q, n) \
do { (q)->length--; lsh_queue_remove(n##_this); } while(0)
#endif /* LSH_QUEUE_H_INCLUDED */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment