You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2014/08/03 17:47:11 UTC

[4/9] git commit: Store class registry in a host-specific location

Store class registry in a host-specific location

For Perl, store the class registry in $Clownfish::Class::_registry. For
C, store it in a global variable.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/9eb42eaa
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/9eb42eaa
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/9eb42eaa

Branch: refs/heads/clone_class_registry
Commit: 9eb42eaa1ee7f05ab95bd89d4eea076012b34720
Parents: 165f9ff
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sun Aug 3 14:03:58 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sun Aug 3 17:38:04 2014 +0200

----------------------------------------------------------------------
 runtime/c/src/Clownfish/Class.c                 | 12 ++++
 runtime/core/Clownfish/Class.c                  | 61 ++++++++------------
 runtime/core/Clownfish/Class.cfh                | 11 ++--
 .../perl/buildlib/Clownfish/Build/Binding.pm    |  7 +--
 runtime/perl/xs/XSBind.c                        | 19 ++++++
 5 files changed, 62 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9eb42eaa/runtime/c/src/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/c/src/Clownfish/Class.c b/runtime/c/src/Clownfish/Class.c
index 82a5892..4c626d9 100644
--- a/runtime/c/src/Clownfish/Class.c
+++ b/runtime/c/src/Clownfish/Class.c
@@ -23,9 +23,21 @@
 #include "Clownfish/Class.h"
 #include "Clownfish/String.h"
 #include "Clownfish/Err.h"
+#include "Clownfish/LockFreeRegistry.h"
 #include "Clownfish/Util/Memory.h"
 #include "Clownfish/VArray.h"
 
+static LockFreeRegistry *class_registry = NULL;
+
+LockFreeRegistry*
+Class_get_registry() {
+    if (class_registry == NULL) {
+        class_registry = LFReg_new(256);
+    }
+
+    return class_registry;
+}
+
 Obj*
 Class_Make_Obj_IMP(Class *self) {
     Obj *obj = (Obj*)Memory_wrapped_calloc(self->obj_alloc_size, 1);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9eb42eaa/runtime/core/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index 0220b3a..6a3ce9d 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -50,8 +50,6 @@ S_find_method(Class *self, const char *meth_name);
 static int32_t
 S_claim_parcel_id(void);
 
-LockFreeRegistry *Class_registry = NULL;
-
 void
 Class_bootstrap(const ClassSpec *specs, size_t num_specs)
 {
@@ -140,7 +138,6 @@ Class_bootstrap(const ClassSpec *specs, size_t num_specs)
      *
      * Pass 3:
      * - Inititalize name and method array.
-     * - Register class.
      */
     for (size_t i = 0; i < num_specs; ++i) {
         const ClassSpec *spec = &specs[i];
@@ -157,8 +154,17 @@ Class_bootstrap(const ClassSpec *specs, size_t num_specs)
             VA_Push(klass->methods, (Obj*)method);
             DECREF(name);
         }
+    }
 
-        Class_add_to_registry(klass);
+    /* Pass 4:
+     * - Register class.
+     */
+    LockFreeRegistry *registry = Class_get_registry();
+    for (size_t i = 0; i < num_specs; ++i) {
+        const ClassSpec *spec = &specs[i];
+        Class *klass = *spec->klass;
+
+        LFReg_Register(registry, (Obj*)klass->name, (Obj*)klass);
     }
 }
 
@@ -235,24 +241,11 @@ Class_Get_Methods_IMP(Class *self) {
     return self->methods;
 }
 
-void
-Class_init_registry() {
-    LockFreeRegistry *reg = LFReg_new(256);
-    if (Atomic_cas_ptr((void*volatile*)&Class_registry, NULL, reg)) {
-        return;
-    }
-    else {
-        DECREF(reg);
-    }
-}
-
 Class*
 Class_singleton(String *class_name, Class *parent) {
-    if (Class_registry == NULL) {
-        Class_init_registry();
-    }
+    LockFreeRegistry *registry = Class_get_registry();
 
-    Class *singleton = (Class*)LFReg_Fetch(Class_registry, (Obj*)class_name);
+    Class *singleton = (Class*)LFReg_Fetch(registry, (Obj*)class_name);
     if (singleton == NULL) {
         VArray *fresh_host_methods;
         uint32_t num_fresh;
@@ -311,7 +304,7 @@ Class_singleton(String *class_name, Class *parent) {
         }
         else {
             DECREF(singleton);
-            singleton = (Class*)LFReg_Fetch(Class_registry, (Obj*)class_name);
+            singleton = (Class*)LFReg_Fetch(registry, (Obj*)class_name);
             if (!singleton) {
                 THROW(ERR, "Failed to either insert or fetch Class for '%o'",
                       class_name);
@@ -324,16 +317,14 @@ Class_singleton(String *class_name, Class *parent) {
 
 bool
 Class_add_to_registry(Class *klass) {
-    if (Class_registry == NULL) {
-        Class_init_registry();
-    }
-    if (LFReg_Fetch(Class_registry, (Obj*)klass->name)) {
+    LockFreeRegistry *registry = Class_get_registry();
+
+    if (LFReg_Fetch(registry, (Obj*)klass->name)) {
         return false;
     }
     else {
         String *class_name = Str_Clone(klass->name);
-        bool retval
-            = LFReg_Register(Class_registry, (Obj*)class_name, (Obj*)klass);
+        bool retval = LFReg_Register(registry, (Obj*)class_name, (Obj*)klass);
         DECREF(class_name);
         return retval;
     }
@@ -342,17 +333,15 @@ Class_add_to_registry(Class *klass) {
 bool
 Class_add_alias_to_registry(Class *klass, const char *alias_ptr,
                              size_t alias_len) {
-    if (Class_registry == NULL) {
-        Class_init_registry();
-    }
+    LockFreeRegistry *registry = Class_get_registry();
+
     StackString *alias = SSTR_WRAP_UTF8(alias_ptr, alias_len);
-    if (LFReg_Fetch(Class_registry, (Obj*)alias)) {
+    if (LFReg_Fetch(registry, (Obj*)alias)) {
         return false;
     }
     else {
         String *class_name = SStr_Clone(alias);
-        bool retval
-            = LFReg_Register(Class_registry, (Obj*)class_name, (Obj*)klass);
+        bool retval = LFReg_Register(registry, (Obj*)class_name, (Obj*)klass);
         DECREF(class_name);
         return retval;
     }
@@ -360,11 +349,9 @@ Class_add_alias_to_registry(Class *klass, const char *alias_ptr,
 
 Class*
 Class_fetch_class(String *class_name) {
-    Class *klass = NULL;
-    if (Class_registry != NULL) {
-        klass = (Class*)LFReg_Fetch(Class_registry, (Obj*)class_name);
-    }
-    return klass;
+    LockFreeRegistry *registry = Class_get_registry();
+
+    return (Class*)LFReg_Fetch(registry, (Obj*)class_name);
 }
 
 void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9eb42eaa/runtime/core/Clownfish/Class.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.cfh b/runtime/core/Clownfish/Class.cfh
index 3bab408..69dc5a4 100644
--- a/runtime/core/Clownfish/Class.cfh
+++ b/runtime/core/Clownfish/Class.cfh
@@ -34,7 +34,6 @@ class Clownfish::Class inherits Clownfish::Obj {
     VArray            *methods;
     cfish_method_t[1]  vtable; /* flexible array */
 
-    inert LockFreeRegistry *registry;
     inert size_t offset_of_parent;
 
     inert void
@@ -51,6 +50,11 @@ class Clownfish::Class inherits Clownfish::Obj {
     inert Class*
     singleton(String *class_name, Class *parent);
 
+    /* Return the global class registry, creating it if necessary.
+     */
+    inert LockFreeRegistry*
+    get_registry();
+
     /** Register a class, so that it can be retrieved by class name.
      *
      * TODO: Move this functionality to some kind of class loader.
@@ -64,11 +68,6 @@ class Clownfish::Class inherits Clownfish::Obj {
     add_alias_to_registry(Class *klass, const char *alias_ptr,
                           size_t alias_len);
 
-    /** Initialize the registry.
-     */
-    inert void
-    init_registry();
-
     /** Tell the host about the new class.
      */
     inert void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9eb42eaa/runtime/perl/buildlib/Clownfish/Build/Binding.pm
----------------------------------------------------------------------
diff --git a/runtime/perl/buildlib/Clownfish/Build/Binding.pm b/runtime/perl/buildlib/Clownfish/Build/Binding.pm
index ccfaeca..1b1d3c5 100644
--- a/runtime/perl/buildlib/Clownfish/Build/Binding.pm
+++ b/runtime/perl/buildlib/Clownfish/Build/Binding.pm
@@ -572,12 +572,9 @@ sub bind_class {
 MODULE = Clownfish   PACKAGE = Clownfish::Class
 
 SV*
-_get_registry()
+_get_registry(...)
 CODE:
-    if (cfish_Class_registry == NULL) {
-        cfish_Class_init_registry();
-    }
-    RETVAL = (SV*)CFISH_Obj_To_Host((cfish_Obj*)cfish_Class_registry);
+    RETVAL = SvREFCNT_inc(get_sv("Clownfish::Class::_registry", GV_ADD));
 OUTPUT: RETVAL
 
 SV*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9eb42eaa/runtime/perl/xs/XSBind.c
----------------------------------------------------------------------
diff --git a/runtime/perl/xs/XSBind.c b/runtime/perl/xs/XSBind.c
index d7c5e88..8807c86 100644
--- a/runtime/perl/xs/XSBind.c
+++ b/runtime/perl/xs/XSBind.c
@@ -675,6 +675,25 @@ CFISH_Obj_To_Host_IMP(cfish_Obj *self) {
 
 /*************************** Clownfish::Class ******************************/
 
+cfish_LockFreeRegistry*
+cfish_Class_get_registry() {
+    SV *registry_sv = get_sv("Clownfish::Class::_registry", GV_ADD);
+    cfish_LockFreeRegistry *registry;
+
+    if (!SvOK(registry_sv)) {
+        registry = cfish_LFReg_new(256);
+        SV *new_sv = CFISH_Obj_To_Host((cfish_Obj*)registry);
+        sv_setsv(registry_sv, new_sv);
+        SvREFCNT_dec(new_sv);
+    }
+    else {
+        registry = (cfish_LockFreeRegistry*)XSBind_sv_to_cfish_obj(registry_sv, 
+                CFISH_LOCKFREEREGISTRY, NULL);
+    }
+
+    return registry;
+}
+
 cfish_Obj*
 CFISH_Class_Make_Obj_IMP(cfish_Class *self) {
     cfish_Obj *obj