*
* See our Documentation/kref.txt for more info. */
-#ifndef ROS_KERN_KREF_H
-#define ROS_KERN_KREF_H
+#pragma once
#include <atomic.h>
#include <assert.h>
void (*release)(struct kref *kref);
};
+/* Helper for some debugging situations */
+static long kref_refcnt(struct kref *kref)
+{
+ return atomic_read(&kref->refcount);
+}
+
static void kref_init(struct kref *kref, void (*release)(struct kref *kref),
unsigned int init)
{
kref->release = release;
}
-static struct kref *kref_get(struct kref *kref, unsigned int inc)
+/* Will blindly incref */
+static struct kref *__kref_get(struct kref *kref, unsigned int inc)
{
- assert(atomic_read(&kref->refcount));
atomic_add(&kref->refcount, inc);
return kref;
}
{
if (atomic_add_not_zero(&kref->refcount, inc))
return kref;
- else return 0;
+ else
+ return 0;
+}
+
+/* Will panic on zero */
+static struct kref *kref_get(struct kref *kref, unsigned int inc)
+{
+ kref = kref_get_not_zero(kref, inc);
+ assert(kref);
+ return kref;
}
/* Returns True if we hit 0 and executed 'release', False otherwise */
static bool kref_put(struct kref *kref)
{
- assert(atomic_read(&kref->refcount) > 0); /* catch some bugs */
+ assert(kref_refcnt(kref) > 0); /* catch some bugs */
if (atomic_sub_and_test(&kref->refcount, 1)) {
kref->release(kref);
return TRUE;
return FALSE;
}
-#endif /* ROS_KERN_KREF_H */
+/* Dev / debugging function to catch the attempted freeing of objects we don't
+ * know how to free yet. */
+static void fake_release(struct kref *kref)
+{
+ panic("Cleaning up this object is not supported!\n");
+}