KObj extension stage I/III
authorJoerg Sonnenberger <joerg@dragonflybsd.org>
Thu, 1 Apr 2004 08:41:24 +0000 (08:41 +0000)
committerJoerg Sonnenberger <joerg@dragonflybsd.org>
Thu, 1 Apr 2004 08:41:24 +0000 (08:41 +0000)
Isolate the reference counting for kobj classes in special functions to
allow clean locking in the next step.

Merge all calls of kobj_class_compile either into the new
kobj_class_instantiate or into kobj_init and make it static. Same for
kobj_class_free.

Remove kobj_class_compile_static, it wasn't used and is pretty pointless
since the kobj framework is not used before the VM subsystem has been
initialized.

sys/kern/subr_bus.c
sys/kern/subr_kobj.c
sys/libiconv/iconv.c
sys/sys/kobj.h

index 8166aa2..81963be 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/kern/subr_bus.c,v 1.54.2.9 2002/10/10 15:13:32 jhb Exp $
- * $DragonFly: src/sys/kern/subr_bus.c,v 1.15 2004/03/31 16:39:20 joerg Exp $
+ * $DragonFly: src/sys/kern/subr_bus.c,v 1.16 2004/04/01 08:41:24 joerg Exp $
  */
 
 #include "opt_bus.h"
@@ -166,7 +166,7 @@ devclass_add_driver(devclass_t dc, driver_t *driver)
         * goes. This means we can safely use static methods and avoids a
         * double-free in devclass_delete_driver.
         */
-       kobj_class_compile((kobj_class_t) driver);
+       kobj_class_instantiate(driver);
 
        /*
         * Make sure the devclass which the driver is implementing exists.
@@ -175,7 +175,6 @@ devclass_add_driver(devclass_t dc, driver_t *driver)
 
        dl->driver = driver;
        TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
-       driver->refs++;
 
        /*
         * Call BUS_DRIVER_ADDED for any existing busses in this class.
@@ -237,9 +236,7 @@ devclass_delete_driver(devclass_t busclass, driver_t *driver)
        TAILQ_REMOVE(&busclass->drivers, dl, link);
        free(dl, M_BUS);
 
-       driver->refs--;
-       if (driver->refs == 0)
-               kobj_class_free((kobj_class_t) driver);
+       kobj_class_uninstantiate(driver);
 
        return(0);
 }
@@ -2252,7 +2249,6 @@ root_bus_module_handler(module_t mod, int what, void* arg)
 {
        switch (what) {
        case MOD_LOAD:
-               kobj_class_compile((kobj_class_t) &root_driver);
                root_bus = make_device(NULL, "root", 0);
                root_bus->desc = "System root bus";
                kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);
index 5e76b1e..76c3d2d 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/kern/subr_kobj.c,v 1.4.2.1 2001/02/02 19:49:13 cg Exp $
- * $DragonFly: src/sys/kern/subr_kobj.c,v 1.4 2004/03/31 16:39:20 joerg Exp $
+ * $DragonFly: src/sys/kern/subr_kobj.c,v 1.5 2004/04/01 08:41:24 joerg Exp $
  */
 
 #include <sys/param.h>
@@ -79,10 +79,9 @@ kobj_unregister_method(struct kobjop_desc *desc)
 }
 
 static void
-kobj_class_compile_common(kobj_class_t cls, kobj_ops_t ops)
+kobj_class_compile(kobj_class_t cls)
 {
        kobj_method_t *m;
-       int i;
 
        /*
         * Don't do anything if we are already compiled.
@@ -90,42 +89,19 @@ kobj_class_compile_common(kobj_class_t cls, kobj_ops_t ops)
        if (cls->ops)
                return;
 
-       /*
-        * First register any methods which need it.
-        */
-       for (i = 0, m = cls->methods; m->desc; i++, m++)
-               kobj_register_method(m->desc);
-
-       /*
-        * Then initialise the ops table.
-        */
-       bzero(ops, sizeof(struct kobj_ops));
-       ops->cls = cls;
-       cls->ops = ops;
-}
-
-void
-kobj_class_compile(kobj_class_t cls)
-{
-       kobj_ops_t ops;
-
        /*
         * Allocate space for the compiled ops table.
         */
-       ops = malloc(sizeof(struct kobj_ops), M_KOBJ, M_INTWAIT);
-       if (!ops)
+       cls->ops = malloc(sizeof(struct kobj_ops), M_KOBJ, M_INTWAIT | M_ZERO);
+       if (!cls->ops)
                panic("kobj_compile_methods: out of memory");
-       kobj_class_compile_common(cls, ops);
-}
+       cls->ops->cls = cls;
 
-void
-kobj_class_compile_static(kobj_class_t cls, kobj_ops_t ops)
-{
        /*
-        * Increment refs to make sure that the ops table is not freed.
+        * Afterwards register any methods which need it.
         */
-       cls->refs++;
-       kobj_class_compile_common(cls, ops);
+       for (m = cls->methods; m->desc; m++)
+               kobj_register_method(m->desc);
 }
 
 void
@@ -147,7 +123,7 @@ kobj_lookup_method(kobj_method_t *methods,
        return;
 }
 
-void
+static void
 kobj_class_free(kobj_class_t cls)
 {
        int i;
@@ -166,6 +142,22 @@ kobj_class_free(kobj_class_t cls)
        cls->ops = 0;
 }
 
+void
+kobj_class_instantiate(kobj_class_t cls)
+{
+       if (!cls->ops)
+               kobj_class_compile(cls);
+       cls->refs++;
+}
+
+void
+kobj_class_uninstantiate(kobj_class_t cls)
+{
+       cls->refs--;
+       if (cls->refs == 0)
+               kobj_class_free(cls);
+}
+
 kobj_t
 kobj_create(kobj_class_t cls,
            struct malloc_type *mtype,
@@ -187,14 +179,8 @@ kobj_create(kobj_class_t cls,
 void
 kobj_init(kobj_t obj, kobj_class_t cls)
 {
-       /*
-        * Consider compiling the class' method table.
-        */
-       if (!cls->ops)
-               kobj_class_compile(cls);
-
+       kobj_class_instantiate(cls);
        obj->ops = cls->ops;
-       cls->refs++;
 }
 
 void
@@ -202,14 +188,7 @@ kobj_delete(kobj_t obj, struct malloc_type *mtype)
 {
        kobj_class_t cls = obj->ops->cls;
 
-       /*
-        * Consider freeing the compiled method table for the class
-        * after its last instance is deleted. As an optimisation, we
-        * should defer this for a short while to avoid thrashing.
-        */
-       cls->refs--;
-       if (!cls->refs)
-               kobj_class_free(cls);
+       kobj_class_uninstantiate(cls);
 
        obj->ops = 0;
        if (mtype)
index 30ff470..6c320ed 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/libkern/iconv.c,v 1.1.2.1 2001/05/21 08:28:07 bp Exp $
- * $DragonFly: src/sys/libiconv/iconv.c,v 1.3 2004/03/18 18:27:47 dillon Exp $
+ * $DragonFly: src/sys/libiconv/iconv.c,v 1.4 2004/04/01 08:41:24 joerg Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -118,8 +118,7 @@ DECLARE_MODULE(iconv, iconv_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
 static int
 iconv_register_converter(struct iconv_converter_class *dcp)
 {
-       kobj_class_compile((struct kobj_class*)dcp);
-       dcp->refs++;
+       kobj_class_instantiate((kobj_class_t)dcp);
        TAILQ_INSERT_TAIL(&iconv_converters, dcp, cc_link);
        return 0;
 }
@@ -127,12 +126,12 @@ iconv_register_converter(struct iconv_converter_class *dcp)
 static int
 iconv_unregister_converter(struct iconv_converter_class *dcp)
 {
-       if (dcp->refs > 1) {
+       if (dcp->refs != 1) {
                ICDEBUG("converter have %d referenses left\n", dcp->refs);
                return EBUSY;
        }
        TAILQ_REMOVE(&iconv_converters, dcp, cc_link);
-       kobj_class_free((struct kobj_class*)dcp);
+       kobj_class_uninstantiate((kobj_class_t)dcp);
        return 0;
 }
 
index b6f9c8a..562171a 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/sys/kobj.h,v 1.8 2003/09/22 21:32:49 peter Exp $
- * $DragonFly: src/sys/sys/kobj.h,v 1.5 2004/02/29 17:18:32 joerg Exp $
+ * $DragonFly: src/sys/sys/kobj.h,v 1.6 2004/04/01 08:41:24 joerg Exp $
  */
 
 #ifndef _SYS_KOBJ_H_
@@ -101,20 +101,14 @@ struct kobj_class name ## _class = {              \
 }
 
 /*
- * Compile the method table in a class.
+ * Compile class for the first instance and add a reference.
  */
-void           kobj_class_compile(kobj_class_t cls);
+void           kobj_class_instantiate(kobj_class_t cls);
 
 /*
- * Compile the method table, with the caller providing the space for
- * the ops table.(for use before malloc is initialised).
+ * Remove a reference and free method table with the last instance.
  */
-void           kobj_class_compile_static(kobj_class_t cls, kobj_ops_t ops);
-
-/*
- * Free the compiled method table in a class.
- */
-void           kobj_class_free(kobj_class_t cls);
+void           kobj_class_uninstantiate(kobj_class_t cls);
 
 /*
  * Allocate memory for and initialise a new object.