/* * This is the Object Manager. It implements the basic operations each object * needs and leaves the rest up to the respective subsystem that implements that * object. The object manager is a resource manager which should help improve * memory safety within the kernel. It reference counts each object and * controls their instantiation and deletion. */ #include #include #include void init_lock(Spinlock *lock); void acquire(Spinlock *lock); void release(Spinlock *lock); /* Obtain a reference to an object */ void * get(void *addr) { Object *obj = addr; __atomic_add_fetch(&obj->type->usage, 1, __ATOMIC_RELAXED); __atomic_add_fetch(&obj->usage, 1, __ATOMIC_RELAXED); return addr; } /* Release a reference to an object */ void put(void *addr) { Object *obj = addr; __atomic_sub_fetch(&obj->type->usage, 1, __ATOMIC_RELAXED); if (__atomic_sub_fetch(&obj->usage, 1, __ATOMIC_RELAXED)) return; if (obj->type->delete) obj->type->delete(obj); remove(obj->type->objects, obj); if (obj->type->free) obj->type->free(obj); else kfree(obj); } /* Create a new instance of an object */ void * new(ObjectType *type) { Object *obj; if (type->alloc && type->free) obj = type->alloc(); else obj = kmalloc(type->size); init_lock(&obj->lock); obj->type = type; if (type->new) type->new(obj); if (!type->objects) type->objects = create_list(type); add(type->objects, obj); /* No need to get() since it's in the global list */ return obj; } /* Copy an instance of an object */ void * copy(void *addr) { Object *parent = addr; Object *child = NULL; if (parent->type->copy) { child = new(parent->type); parent->type->copy(parent, child); } return child; } /* Lock an object */ void lock(void *addr) { Object *obj = addr; acquire(&obj->lock); } /* Unlock an object */ void unlock(void *addr) { Object *obj = addr; release(&obj->lock); }