Nucleus
Barry Object magic and ObjectList iteration d5bd261 (3 years, 3 months ago)
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);
}