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 <[email protected]> Authored: Sun Aug 3 14:03:58 2014 +0200 Committer: Nick Wellnhofer <[email protected]> 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
