Nucleus
Barry Ordered object lists 74ee43c (3 years, 2 months ago)
diff --git a/object/list.c b/object/list.c
index e1b2d08..914a303 100644
--- a/object/list.c
+++ b/object/list.c
@@ -6,6 +6,7 @@
* routines to be used on them.
*/
+#include <stdarg.h>
#include <nucleus/object.h>
#include <nucleus/memory.h>
#include <nucleus/panic.h>
@@ -20,6 +21,8 @@ struct ObjectList {
struct ListEntry *start, *end;
size_t entries;
ObjectType *type;
+ enum ListMode mode;
+ compare_callback_t compare;
Spinlock lock;
};
/* Iterator */
@@ -35,11 +38,20 @@ void release(Spinlock *lock);
/* Create an Object List */
ObjectList *
-create_list(ObjectType *type)
+create_list(ObjectType *type, enum ListMode mode, ...)
{
ObjectList *list = kmalloc(sizeof(ObjectList));
init_lock(&list->lock);
list->type = type;
+ list->mode = mode;
+
+ if (mode == LIST_ORDERED) {
+ va_list args;
+ va_start(args, mode);
+ list->compare = va_arg(args, compare_callback_t);
+ va_end(args);
+ }
+
return list;
}
@@ -61,15 +73,39 @@ add(ObjectList *list, void *addr)
return;
acquire(&list->lock);
- struct ListEntry *entry = kmalloc(sizeof(struct ListEntry));
- if (!list->start)
- list->start = entry;
- else
- list->end->next = entry;
- entry->prev = list->end;
- list->end = entry;
+
+ struct ListEntry *entry, *next;
+ entry = kmalloc(sizeof(struct ListEntry));
entry->obj = get(obj);
list->entries++;
+
+ if (!list->start) {
+ /* Only item in list */
+ list->start = list->end = entry;
+ } else if (list->compare) {
+ /* Find next item */
+ for (next = list->start; next; next = next->next) {
+ if (list->compare(next->obj, obj) > 0)
+ break;
+ }
+ if (!next)
+ goto end;
+ /* Add in */
+ entry->prev = next->prev;
+ entry->next = next;
+ next->prev = entry;
+ if (entry->prev)
+ entry->prev->next = entry;
+ else
+ list->start = entry;
+ } else {
+end:
+ /* Add to end of list */
+ list->end->next = entry;
+ entry->prev = list->end;
+ list->end = entry;
+ }
+
release(&list->lock);
}
@@ -172,7 +208,8 @@ get_nth_item(ObjectList *list, off_t n)
ObjectList *
copy_list(ObjectList *list)
{
- ObjectList *newlist = create_list(list->type);
+ ObjectList *newlist = create_list(list->type, list->mode,
+ list->compare);
acquire(&list->lock);
struct ListEntry *entry;
for (entry = list->start; entry; entry = entry->next)
diff --git a/object/manager.c b/object/manager.c
index 85f5360..a274408 100644
--- a/object/manager.c
+++ b/object/manager.c
@@ -58,7 +58,7 @@ new(ObjectType *type)
if (type->new)
type->new(obj);
if (!type->objects)
- type->objects = create_list(type);
+ type->objects = create_list(type, LIST_NORMAL);
add(type->objects, obj);
/* No need to get() since it's in the global list */
return obj;