BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 74ee43c3216e1f3c3b33a2b6afe70b52b62e5465

// Related

Nucleus

Barry Ordered object lists 74ee43c (3 years, 2 months ago)
diff --git a/include/nucleus/object.h b/include/nucleus/object.h
index f7e9cf9..b86a86f 100644
--- a/include/nucleus/object.h
+++ b/include/nucleus/object.h
@@ -10,7 +10,7 @@ typedef struct ObjectType ObjectType;
 typedef struct Object Object;
 typedef struct ObjectList ObjectList;
 typedef struct Iterator Iterator;
-
+typedef int (*compare_callback_t)(void *, void *);
 typedef struct Task Task;
 
 /* Spinlock */
@@ -45,6 +45,12 @@ struct Object {
 };
 #define OBJECT_MAGIC 0x10032004
 
+/* Object List modes */
+enum ListMode {
+	LIST_NORMAL,
+	LIST_ORDERED,
+};
+
 void *get(void *addr);
 void put(void *addr);
 void *new(ObjectType *type);
@@ -53,7 +59,7 @@ refcount_t usage(void *addr);
 void lock(void *addr);
 void unlock(void *addr);
 
-ObjectList *create_list(ObjectType *type);
+ObjectList *create_list(ObjectType *type, enum ListMode mode, ...);
 void destroy_list(ObjectList *list);
 void add(ObjectList *list, void *addr);
 void remove(ObjectList *list, void *addr);
diff --git a/memory/region.c b/memory/region.c
index 3cf9fa4..bea28ca 100644
--- a/memory/region.c
+++ b/memory/region.c
@@ -38,7 +38,7 @@ static void
 vm_new(Object *obj)
 {
 	VirtualMemory *vm = (void *) obj;
-	vm->regions = create_list(&vmRegionType);
+	vm->regions = create_list(&vmRegionType, LIST_NORMAL);
 }
 
 /* Destroy a Virtual Memory object */
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;
diff --git a/task/scheduler.c b/task/scheduler.c
index 3a9605c..dc7551f 100644
--- a/task/scheduler.c
+++ b/task/scheduler.c
@@ -95,5 +95,5 @@ init_scheduler(void)
 {
 	enum Priority p;
 	for (p = 0; p < PRIORITY_COUNT; p++)
-		readyQueue[p] = create_list(&taskType);
+		readyQueue[p] = create_list(&taskType, LIST_NORMAL);
 }
diff --git a/vfs/inode.c b/vfs/inode.c
index e4ed8a8..8197127 100644
--- a/vfs/inode.c
+++ b/vfs/inode.c
@@ -33,8 +33,8 @@ static void
 inode_new(Object *obj)
 {
 	Inode *inode = (void *) obj;
-	inode->dirEntries = create_list(&dirEntryType);
-	inode->pages = create_list(&pageType);
+	inode->dirEntries = create_list(&dirEntryType, LIST_NORMAL);
+	inode->pages = create_list(&pageType, LIST_NORMAL);
 }
 
 /* Destroy an Inode */
diff --git a/vfs/namespace.c b/vfs/namespace.c
index 638453f..1b102af 100644
--- a/vfs/namespace.c
+++ b/vfs/namespace.c
@@ -25,7 +25,7 @@ static void
 file_system_new(Object *obj)
 {
 	FileSystem *fs = (void *) obj;
-	fs->cwdPath = create_list(&dirEntryType);
+	fs->cwdPath = create_list(&dirEntryType, LIST_NORMAL);
 }
 
 /* Destory a File System object */
diff --git a/vfs/open.c b/vfs/open.c
index ff7fd01..9dd8978 100644
--- a/vfs/open.c
+++ b/vfs/open.c
@@ -32,7 +32,7 @@ lookup(const char *path, ObjectList *newcustody)
 	if (*p == '/') {
 		inode = current->fs->root;
 		while (*++p == '/');
-		custody = create_list(&dirEntryType);
+		custody = create_list(&dirEntryType, LIST_NORMAL);
 	} else {
 		inode = current->fs->cwd;
 		custody = copy_list(current->fs->cwdPath);
@@ -125,7 +125,7 @@ open(const char *name, int flags, ...)
 		return -EMFILE;
 
 	/* Find inode */
-	ObjectList *custody = create_list(&dirEntryType);
+	ObjectList *custody = create_list(&dirEntryType, LIST_NORMAL);
 	Inode *inode = lookup(name, custody);
 	DirEntry *entry;
 	va_list args;
@@ -197,7 +197,7 @@ mkdir(const char *pathname, mode_t mode)
 	if (!verify_access(pathname, strnlen(pathname, PATH_MAX), PROT_READ))
 		return -EFAULT;
 	int err;
-	ObjectList *custody = create_list(&dirEntryType);
+	ObjectList *custody = create_list(&dirEntryType, LIST_NORMAL);
 	Inode *inode = lookup(pathname, custody);
 	if (inode) {
 		err = -EEXIST;
@@ -235,7 +235,7 @@ mknod(const char *pathname, mode_t mode, dev_t dev)
 	if (!verify_access(pathname, strnlen(pathname, PATH_MAX), PROT_READ))
 		return -EFAULT;
 	int err;
-	ObjectList *custody = create_list(&dirEntryType);
+	ObjectList *custody = create_list(&dirEntryType, LIST_NORMAL);
 	Inode *inode = lookup(pathname, custody);
 	if (inode) {
 		err = -EEXIST;
diff --git a/vfs/superblock.c b/vfs/superblock.c
index 6c3776f..94100aa 100644
--- a/vfs/superblock.c
+++ b/vfs/superblock.c
@@ -25,7 +25,7 @@ static void
 super_block_new(Object *obj)
 {
 	SuperBlock *sb = (void *) obj;
-	sb->inodes = create_list(&inodeType);
+	sb->inodes = create_list(&inodeType, LIST_NORMAL);
 }
 
 /* Destroy SuperBlock object */