Nucleus
Barry Doubly-linked object lists and copying 7a0d3ef (3 years, 3 months ago)
diff --git a/object/list.c b/object/list.c
index 3e9b96b..8581330 100644
--- a/object/list.c
+++ b/object/list.c
@@ -11,7 +11,7 @@
/* Structure for a List Entry */
struct ListEntry {
- struct ListEntry *next;
+ struct ListEntry *prev, *next;
Object *obj;
};
/* Structure for an Object List */
@@ -58,6 +58,7 @@ add(ObjectList *list, void *addr)
list->start = entry;
else
list->end->next = entry;
+ entry->prev = list->end;
list->end = entry;
entry->obj = get(obj);
list->entries++;
@@ -75,30 +76,32 @@ remove(ObjectList *list, void *addr)
return;
acquire(&list->lock);
- /* Start of list */
- struct ListEntry *entry, *prev = NULL;
- if (list->start->obj == obj) {
- entry = list->start;
- list->start = entry->next;
- goto found;
+ /* Search for object */
+ struct ListEntry *entry;
+ for (entry = list->start;
+ entry && entry->obj != obj;
+ entry = entry->next);
+ if (!entry) {
+ release(&list->lock);
+ return;
}
- /* Search for object */
- for (prev = list->start; prev->next; prev = prev->next)
- if (prev->next->obj == obj)
- break;
- if (!prev->next)
- goto end;
- entry = prev->next;
- prev->next = entry->next;
-
-found:
- if (list->end->obj == obj)
- list->end = prev;
+ /* Unlink list */
+ if (list->start == entry)
+ list->start = entry->next;
+ if (list->end == entry)
+ list->end == entry->prev;
+
+ /* Unlink neighbours */
+ if (entry->prev)
+ entry->prev->next = entry->next;
+ if (entry->next)
+ entry->next->prev = entry->prev;
+
+ /* Release resources */
put(obj);
list->entries--;
kfree(entry);
-end:
release(&list->lock);
}
@@ -137,7 +140,7 @@ count(ObjectList *list)
/* Iterate a List with a callback */
void
-iterate(ObjectList *list, callback_t callback, void *data)
+iterate(ObjectList *list, iterate_callback_t callback, void *data)
{
acquire(&list->lock);
struct ListEntry *entry;
@@ -146,3 +149,16 @@ iterate(ObjectList *list, callback_t callback, void *data)
break;
release(&list->lock);
}
+
+/* Copy list */
+ObjectList *
+copy_list(ObjectList *list)
+{
+ ObjectList *newlist = create_list(list->type);
+ acquire(&list->lock);
+ struct ListEntry *entry;
+ for (entry = list->start; entry; entry = entry->next)
+ add(newlist, entry->obj);
+ release(&list->lock);
+ return newlist;
+}