Subject: [PATCH][2.5] Single linked lists for Linux

This introduces single linked lists, as figured out by us four. Works
fine with userspace test applications, should work fine with e.g. the
scheduler. Breaks nothing. Must get adopted.

--- /dev/null Wed Dec 31 17:00:00 1969
+++ slist-2.5/include/linux/slist.h Wed Sep 25 14:49:24 2002
@@ -0,0 +1,103 @@
+#ifdef __KERNEL__
+#ifndef _LINUX_SLIST_H
+#define _LINUX_SLIST_H
+
+#include <asm/processor.h>
+
+/*
+ * Type-safe single linked list helper-functions.
+ * (originally taken from list.h)
+ *
+ * Thomas 'Dent' Mirlacher, Daniel Phillips, Andreas Borgk,
+ * Thunder from the hill
+ */
+
+/**
+ * slist_add_front - add a new entry at the first slot, moving the old head
+ * to the second slot
+ * @new: new entry to be added
+ * @head: head of the single linked list
+ *
+ * Insert a new entry before the specified head.
+ * This is good for implementing stacks.
+ */
+
+#define slist_add_front(_new, _head) \
+do { \
+ (_new)->next = (_head); \
+ (_head) = (_new); \
+} while (0)
+
+
+
+/**
+ * slist_add - add a new entry
+ * @new: new entry to be added
+ * @head: head of the single linked list
+ *
+ * Insert a new entry before the specified head.
+ * This is good for implementing stacks.
+ *
+ * Careful: if you do this concurrently, _head
+ * might get into nirvana...
+ */
+#define slist_add(_new, _head) \
+do { \
+ (_new)->next = (_head)->next; \
+ (_head)->next = (_new); \
+ (_new) = (_head); \
+} while (0)
+
+/**
+ * slist_del - remove an entry from list
+ * @head: head to remove it from
+ * @entry: entry to be removed
+ */
+#define slist_del(_head, _entry) \
+do { \
+ (_head)->next = (_entry)->next; \
+ (_entry)->next = NULL; \
+}
+
+/**
+ * slist_del_single - untag a list from an entry
+ * @list: list entry to be untagged
+ */
+#define slist_del_single(_list) \
+ (_list)->next = NULL
+
+/**
+ * slist_pop - pop out list entry
+ * @list: entry to be popped out
+ *
+ * Pop out an entry from a list.
+ */
+#define slist_pop(_list) ({ \
+ typeof(_list) _NODE_ = _list; \
+ if (_list) { \
+ (_list) = (_list)->next; \
+ _NODE_->next = NULL; \
+ } \
+ _NODE_; })
+
+/**
+ * slist_for_each - iterate over a list
+ * @pos: the pointer to use as a loop counter.
+ * @head: the head for your list (this is also the first entry).
+ */
+#define slist_for_each(pos, head) \
+ for (pos = head; pos && ({ prefetch(pos->next); 1; }); \
+ pos = pos->next)
+
+/**
+ * slist_for_each_del - iterate over a list, popping off entries
+ * @pos: the pointer to use as a loop counter.
+ * @head: the head for your list (this is also the first entry).
+ */
+#define slist_for_each_del(pos, head) \
+ for (pos = slist_pop(head); pos && \
+ ({ prefetch(pos->next); 1; }); \
+ pos = slist_pop(head))
+
+#endif /* _LINUX_SLIST_H */
+#endif /* __KERNEL__ */

--
Lightweight Patch Manager, without pine.
If you have any objections (apart from who I am), tell me


2002-09-25 21:07:07

by Rik van Riel

[permalink] [raw]
Subject: Re: [PATCH][2.5] Single linked lists for Linux

On Wed, 25 Sep 2002, Lightweight Patch Manager wrote:

> This introduces single linked lists, as figured out by us four. Works
> fine with userspace test applications, should work fine with e.g. the
> scheduler. Breaks nothing. Must get adopted.

Where is the SLIST_HEAD macro and other goodies to be able
to use this thing in the same way we use list.h ?

Rik
--
Bravely reimplemented by the knights who say "NIH".

http://www.surriel.com/ http://distro.conectiva.com/

Spamtraps of the month: [email protected] [email protected]

2002-09-25 21:17:52

by Thunder from the hill

[permalink] [raw]
Subject: Re: [PATCH][2.5] Single linked lists for Linux

Hi,

On Wed, 25 Sep 2002, Rik van Riel wrote:
> Where is the SLIST_HEAD macro and other goodies to be able
> to use this thing in the same way we use list.h ?

To come, once I know what you think about it.

Thunder
--
assert(typeof((fool)->next) == typeof(fool)); /* wrong */

2002-09-25 21:14:21

by Mark Mielke

[permalink] [raw]
Subject: Re: [PATCH][2.5] Single linked lists for Linux

On Wed, Sep 25, 2002 at 08:56:08PM +0000, Lightweight Patch Manager wrote:
> +#define slist_add_front(_new, _head) \
> +do { \
> + (_new)->next = (_head); \
> + (_head) = (_new); \
> +} while (0)

I suppose it isn't a serious issue, but is it necessary to repeat
'_new' and '_head' in #define?

> +/**
> + * slist_del - remove an entry from list
> + * @head: head to remove it from
> + * @entry: entry to be removed
> + */
> +#define slist_del(_head, _entry) \
> +do { \
> + (_head)->next = (_entry)->next; \
> + (_entry)->next = NULL; \
> +}

Did you miss "while (0)"?

> +#define slist_del_single(_list) \
> + (_list)->next = NULL

Perhaps an outer ()?

mark

--
[email protected]/[email protected]/[email protected] __________________________
. . _ ._ . . .__ . . ._. .__ . . . .__ | Neighbourhood Coder
|\/| |_| |_| |/ |_ |\/| | |_ | |/ |_ |
| | | | | \ | \ |__ . | | .|. |__ |__ | \ |__ | Ottawa, Ontario, Canada

One ring to rule them all, one ring to find them, one ring to bring them all
and in the darkness bind them...

http://mark.mielke.cc/