Add EPLAN9 to the error list (XCC)
[akaros.git] / kern / include / kref.h
index 27fe63b..7888b7f 100644 (file)
@@ -10,8 +10,7 @@
  *
  * 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>
@@ -25,6 +24,12 @@ struct kref {
        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)
 {
@@ -33,9 +38,9 @@ static void kref_init(struct kref *kref, void (*release)(struct kref *kref),
        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;
 }
@@ -45,13 +50,22 @@ static struct kref *kref_get_not_zero(struct kref *kref, unsigned int inc)
 {
        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;
@@ -59,4 +73,9 @@ static bool kref_put(struct kref *kref)
        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");
+}