object: add functions to track handle allocation
This commit is contained in:
@@ -59,6 +59,8 @@ extern kern_status_t object_type_unregister(struct object_type *p);
|
|||||||
extern struct object *object_create(struct object_type *type);
|
extern struct object *object_create(struct object_type *type);
|
||||||
extern struct object *object_ref(struct object *obj);
|
extern struct object *object_ref(struct object *obj);
|
||||||
extern void object_unref(struct object *obj);
|
extern void object_unref(struct object *obj);
|
||||||
|
extern void object_add_handle(struct object *obj);
|
||||||
|
extern void object_remove_handle(struct object *obj);
|
||||||
extern void object_lock(struct object *obj);
|
extern void object_lock(struct object *obj);
|
||||||
extern void object_unlock(struct object *obj);
|
extern void object_unlock(struct object *obj);
|
||||||
extern void object_lock_irqsave(struct object *obj, unsigned long *flags);
|
extern void object_lock_irqsave(struct object *obj, unsigned long *flags);
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ kern_status_t object_type_register(struct object_type *p)
|
|||||||
|
|
||||||
p->ob_cache.c_name = p->ob_name;
|
p->ob_cache.c_name = p->ob_name;
|
||||||
p->ob_cache.c_obj_size = p->ob_size;
|
p->ob_cache.c_obj_size = p->ob_size;
|
||||||
p->ob_cache.c_page_order = VM_PAGE_16K;
|
|
||||||
|
|
||||||
vm_cache_init(&p->ob_cache);
|
vm_cache_init(&p->ob_cache);
|
||||||
p->ob_flags |= OBJTYPE_INIT;
|
p->ob_flags |= OBJTYPE_INIT;
|
||||||
@@ -71,6 +70,20 @@ struct object *object_ref(struct object *obj)
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void object_cleanup(struct object *obj, unsigned long flags)
|
||||||
|
{
|
||||||
|
if (obj->ob_refcount > 0 || obj->ob_handles > 0) {
|
||||||
|
spin_unlock_irqrestore(&obj->ob_lock, flags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAS_OP(obj, destroy)) {
|
||||||
|
obj->ob_type->ob_ops.destroy(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_cache_free(&obj->ob_type->ob_cache, obj);
|
||||||
|
}
|
||||||
|
|
||||||
void object_unref(struct object *obj)
|
void object_unref(struct object *obj)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@@ -82,17 +95,26 @@ void object_unref(struct object *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
obj->ob_refcount--;
|
obj->ob_refcount--;
|
||||||
|
object_cleanup(obj, flags);
|
||||||
|
}
|
||||||
|
|
||||||
if (obj->ob_refcount > 0) {
|
void object_add_handle(struct object *obj)
|
||||||
|
{
|
||||||
|
obj->ob_handles++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void object_remove_handle(struct object *obj)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
spin_lock_irqsave(&obj->ob_lock, &flags);
|
||||||
|
|
||||||
|
if (obj->ob_handles == 0) {
|
||||||
spin_unlock_irqrestore(&obj->ob_lock, flags);
|
spin_unlock_irqrestore(&obj->ob_lock, flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HAS_OP(obj, destroy)) {
|
obj->ob_handles--;
|
||||||
obj->ob_type->ob_ops.destroy(obj);
|
object_cleanup(obj, flags);
|
||||||
}
|
|
||||||
|
|
||||||
vm_cache_free(&obj->ob_type->ob_cache, obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void object_lock(struct object *obj)
|
void object_lock(struct object *obj)
|
||||||
|
|||||||
Reference in New Issue
Block a user