BarryServer : Git

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

// Related

Nucleus

Barry Object magic and ObjectList iteration d5bd261 (3 years, 2 months ago)
diff --git a/include/nucleus/object.h b/include/nucleus/object.h
index c380cbd..f7e9cf9 100644
--- a/include/nucleus/object.h
+++ b/include/nucleus/object.h
@@ -9,14 +9,13 @@ typedef struct Spinlock Spinlock;
 typedef struct ObjectType ObjectType;
 typedef struct Object Object;
 typedef struct ObjectList ObjectList;
+typedef struct Iterator Iterator;
 
 typedef struct Task Task;
 
-typedef int (*iterate_callback_t)(void *object, void *data);
-
 /* Spinlock */
 struct Spinlock {
-	char locked;
+	_Atomic char locked;
 	refcount_t usage;
 	union {
 		Task *owner;
@@ -39,15 +38,18 @@ struct ObjectType {
 
 /* Object */
 struct Object {
+	uint32_t magic;
 	ObjectType *type;
 	refcount_t usage;
 	Spinlock lock;
 };
+#define OBJECT_MAGIC 0x10032004
 
 void *get(void *addr);
 void put(void *addr);
 void *new(ObjectType *type);
 void *copy(void *addr);
+refcount_t usage(void *addr);
 void lock(void *addr);
 void unlock(void *addr);
 
@@ -59,8 +61,17 @@ void *pop_from_start(ObjectList *list);
 void *pop_from_end(ObjectList *list);
 size_t count(ObjectList *list);
 void *get_nth_item(ObjectList *list, off_t n);
-void iterate(ObjectList *list, iterate_callback_t callback, void *data);
 ObjectList *copy_list(ObjectList *list);
 void concat_list(ObjectList *src, ObjectList *dest);
 
+Iterator *iterate(ObjectList *list);
+void *first(Iterator *iter);
+void *last(Iterator *iter);
+void *next(Iterator *iter);
+void *prev(Iterator *iter);
+int done_iterating(Iterator *iter);
+#define foreach(l,i) for (Iterator *(__l_ ## i) = iterate(l); (__l_ ## i); \
+                          done_iterating(__l_ ## i), (__l_ ## i) = NULL) \
+                     for (i = first(__l_ ## i); i; i = next(__l_ ## i))
+
 #endif
diff --git a/object/list.c b/object/list.c
index 4b3f3c7..e1b2d08 100644
--- a/object/list.c
+++ b/object/list.c
@@ -8,6 +8,7 @@
 
 #include <nucleus/object.h>
 #include <nucleus/memory.h>
+#include <nucleus/panic.h>
 
 /* Structure for a List Entry */
 struct ListEntry {
@@ -21,6 +22,12 @@ struct ObjectList {
 	ObjectType *type;
 	Spinlock lock;
 };
+/* Iterator */
+struct Iterator {
+	ObjectList *list;
+	struct ListEntry *prev, *entry, *next;
+	off_t pos;
+};
 
 void init_lock(Spinlock *lock);
 void acquire(Spinlock *lock);
@@ -49,6 +56,7 @@ void
 add(ObjectList *list, void *addr)
 {
 	Object *obj = addr;
+	ASSERT(obj->magic == OBJECT_MAGIC);
 	if (list->type && obj->type != list->type)
 		return;
 
@@ -70,6 +78,7 @@ void
 remove(ObjectList *list, void *addr)
 {
 	Object *obj = addr;
+	ASSERT(obj->magic == OBJECT_MAGIC);
 	if (!list->start)
 		return;
 	if (list->type && obj->type != list->type)
@@ -159,21 +168,6 @@ get_nth_item(ObjectList *list, off_t n)
 	return entry->obj;
 }
 
-/* Iterate a List with a callback */
-void
-iterate(ObjectList *list, iterate_callback_t callback, void *data)
-{
-	acquire(&list->lock);
-	struct ListEntry *entry;
-	for (entry = list->start; entry; entry = entry->next) {
-		get(entry->obj);
-		if (callback(entry->obj, data))
-			break;
-		put(entry->obj);
-	}
-	release(&list->lock);
-}
-
 /* Copy list */
 ObjectList *
 copy_list(ObjectList *list)
@@ -197,3 +191,74 @@ concat_list(ObjectList *src, ObjectList *dest)
 		add(dest, entry->obj);
 	release(&src->lock);
 }
+
+/* Iterate a List */
+Iterator *
+iterate(ObjectList *list)
+{
+	Iterator *i = kmalloc(sizeof(Iterator));
+	i->list = list;
+	return i;
+}
+
+/* Get first iteratable element */
+void *
+first(Iterator *iter)
+{
+	iter->entry = iter->list->start;
+	if (iter->entry) {
+		iter->next = iter->entry->next;
+		iter->pos = 0;
+		return iter->entry->obj;
+	}
+	return NULL;
+}
+
+/* Get last iteratable element */
+void *
+last(Iterator *iter)
+{
+	iter->entry = iter->list->end;
+	if (iter->entry) {
+		iter->prev = iter->entry->prev;
+		iter->pos = iter->list->entries - 1;
+		return iter->entry->obj;
+	}
+	return NULL;
+}
+
+/* Get next iteratable element */
+void *
+next(Iterator *iter)
+{
+	iter->entry = iter->next;
+	if (iter->entry) {
+		iter->prev = iter->entry->prev;
+		iter->next = iter->entry->next;
+		iter->pos++;
+		return iter->entry->obj;
+	}
+	return NULL;
+}
+
+/* Get previous iteratable element */
+void *
+prev(Iterator *iter)
+{
+	iter->entry = iter->prev;
+	if (iter->entry) {
+		iter->prev = iter->entry->prev;
+		iter->next = iter->entry->next;
+		iter->pos--;
+		return iter->entry->obj;
+	}
+	return NULL;
+}
+
+/* End iteration */
+int
+done_iterating(Iterator *iter)
+{
+	kfree(iter);
+	return 0;
+}
diff --git a/object/manager.c b/object/manager.c
index 74b833d..85f5360 100644
--- a/object/manager.c
+++ b/object/manager.c
@@ -19,6 +19,7 @@ void *
 get(void *addr)
 {
 	Object *obj = addr;
+	ASSERT(obj->magic == OBJECT_MAGIC);
 	__atomic_add_fetch(&obj->type->usage, 1, __ATOMIC_RELAXED);
 	__atomic_add_fetch(&obj->usage, 1, __ATOMIC_RELAXED);
 	return addr;
@@ -29,6 +30,7 @@ void
 put(void *addr)
 {
 	Object *obj = addr;
+	ASSERT(obj->magic == OBJECT_MAGIC);
 	__atomic_sub_fetch(&obj->type->usage, 1, __ATOMIC_RELAXED);
 	if (__atomic_sub_fetch(&obj->usage, 1, __ATOMIC_RELAXED))
 		return;
@@ -51,6 +53,7 @@ new(ObjectType *type)
 	else
 		obj = kmalloc(type->size);
 	init_lock(&obj->lock);
+	obj->magic = OBJECT_MAGIC;
 	obj->type = type;
 	if (type->new)
 		type->new(obj);
@@ -67,6 +70,7 @@ copy(void *addr)
 {
 	Object *parent = addr;
 	Object *child = NULL;
+	ASSERT(parent->magic == OBJECT_MAGIC);
 	if (parent->type->copy) {
 		child = new(parent->type);
 		parent->type->copy(parent, child);
@@ -74,11 +78,20 @@ copy(void *addr)
 	return child;
 }
 
+refcount_t
+usage(void *addr)
+{
+	Object *obj = addr;
+	ASSERT(obj->magic == OBJECT_MAGIC);
+	return obj->usage;
+}
+
 /* Lock an object */
 void
 lock(void *addr)
 {
 	Object *obj = addr;
+	ASSERT(obj->magic == OBJECT_MAGIC);
 	acquire(&obj->lock);
 }
 
@@ -87,5 +100,6 @@ void
 unlock(void *addr)
 {
 	Object *obj = addr;
+	ASSERT(obj->magic == OBJECT_MAGIC);
 	release(&obj->lock);
 }