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:08 UTC
[1/9] git commit: Implement iterator for LockFreeRegistry
Repository: lucy-clownfish
Updated Branches:
refs/heads/clone_class_registry [created] 859ee7e1b
Implement iterator for LockFreeRegistry
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/bfde91c3
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/bfde91c3
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/bfde91c3
Branch: refs/heads/clone_class_registry
Commit: bfde91c3a34fcfbf4965046f0ceb9955f7c17118
Parents: c1d89c3
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sun Aug 3 16:06:05 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sun Aug 3 17:38:04 2014 +0200
----------------------------------------------------------------------
runtime/core/Clownfish/LockFreeRegistry.c | 51 ++++++++++++++++++++++++
runtime/core/Clownfish/LockFreeRegistry.cfh | 17 ++++++++
2 files changed, 68 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/bfde91c3/runtime/core/Clownfish/LockFreeRegistry.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/LockFreeRegistry.c b/runtime/core/Clownfish/LockFreeRegistry.c
index fab4f54..577ecb0 100644
--- a/runtime/core/Clownfish/LockFreeRegistry.c
+++ b/runtime/core/Clownfish/LockFreeRegistry.c
@@ -15,6 +15,7 @@
*/
#define C_CFISH_LOCKFREEREGISTRY
+#define C_CFISH_LFREGITERATOR
#define CFISH_USE_SHORT_NAMES
#include "Clownfish/LockFreeRegistry.h"
@@ -148,4 +149,54 @@ LFReg_Destroy_IMP(LockFreeRegistry *self) {
SUPER_DESTROY(self, LOCKFREEREGISTRY);
}
+/**********************************************************************/
+
+LFRegIterator*
+LFRegIter_new(LockFreeRegistry *registry) {
+ LFRegIterator *self = (LFRegIterator*)Class_Make_Obj(LFREGITERATOR);
+ return LFRegIter_init(self, registry);
+}
+
+LFRegIterator*
+LFRegIter_init(LFRegIterator *self, LockFreeRegistry *registry) {
+ self->registry = (LockFreeRegistry*)INCREF(registry);
+ self->tick = 0; // Next tick.
+ self->entry = NULL; // Previous entry.
+ return self;
+}
+
+bool
+LFRegIter_Next_IMP(LFRegIterator *self, Obj **key, Obj**value) {
+ size_t tick = self->tick;
+ LFRegEntry *entry = (LFRegEntry*)self->entry;
+
+ if (entry) {
+ entry = entry->next;
+ }
+
+ LockFreeRegistry *registry = self->registry;
+ size_t capacity = registry->capacity;
+ LFRegEntry **entries = registry->entries;
+
+ while (!entry && tick < capacity) {
+ entry = entries[tick++];
+ }
+
+ self->tick = tick;
+ self->entry = entry;
+
+ if (!entry) { return false; }
+
+ if (key) { *key = entry->key; }
+ if (value) { *value = entry->value; }
+
+ return true;
+}
+
+void
+LFRegIter_Destroy_IMP(LFRegIterator *self) {
+ DECREF(self->registry);
+
+ SUPER_DESTROY(self, LFREGITERATOR);
+}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/bfde91c3/runtime/core/Clownfish/LockFreeRegistry.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/LockFreeRegistry.cfh b/runtime/core/Clownfish/LockFreeRegistry.cfh
index 2061a23..cc8be8e 100644
--- a/runtime/core/Clownfish/LockFreeRegistry.cfh
+++ b/runtime/core/Clownfish/LockFreeRegistry.cfh
@@ -45,4 +45,21 @@ class Clownfish::LockFreeRegistry nickname LFReg inherits Clownfish::Obj {
Destroy(LockFreeRegistry *self);
}
+class Clownfish::LFRegIterator nickname LFRegIter inherits Clownfish::Obj {
+ LockFreeRegistry *registry;
+ size_t tick;
+ void *entry;
+
+ inert incremented LFRegIterator*
+ new(LockFreeRegistry *registry);
+
+ inert LFRegIterator*
+ init(LFRegIterator *self, LockFreeRegistry *registry);
+
+ public bool
+ Next(LFRegIterator *self, Obj **key, Obj**value);
+
+ public void
+ Destroy(LFRegIterator *self);
+}
[7/9] git commit: Make String#Clone create a new String object
Posted by nw...@apache.org.
Make String#Clone create a new String object
In order to allow thread-safe cloning of strings, String#Clone must
create a new String object.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/a360af7d
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/a360af7d
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/a360af7d
Branch: refs/heads/clone_class_registry
Commit: a360af7d27a1d528efaf6b8655b386aeb19de307
Parents: 9eb42ea
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sun Aug 3 14:07:22 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sun Aug 3 17:38:04 2014 +0200
----------------------------------------------------------------------
runtime/core/Clownfish/String.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a360af7d/runtime/core/Clownfish/String.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/String.c b/runtime/core/Clownfish/String.c
index c23314c..7527f48 100644
--- a/runtime/core/Clownfish/String.c
+++ b/runtime/core/Clownfish/String.c
@@ -310,7 +310,7 @@ Str_To_Utf8_IMP(String *self) {
String*
Str_Clone_IMP(String *self) {
- return (String*)INCREF(self);
+ return Str_new_from_trusted_utf8(self->ptr, self->size);
}
String*
[4/9] git commit: Store class registry in a host-specific location
Posted by nw...@apache.org.
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
[9/9] git commit: Cease sharing Class and LFReg between Perl threads
Posted by nw...@apache.org.
Cease sharing Class and LFReg between Perl threads
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/859ee7e1
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/859ee7e1
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/859ee7e1
Branch: refs/heads/clone_class_registry
Commit: 859ee7e1b43bed64c8312f6cd4f8d8f43e3ece6d
Parents: b46a446
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sun Aug 3 17:36:24 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sun Aug 3 17:46:02 2014 +0200
----------------------------------------------------------------------
runtime/c/src/Clownfish/Class.c | 7 ------
runtime/c/src/Clownfish/LockFreeRegistry.c | 32 ------------------------
runtime/core/Clownfish/Class.cfh | 3 ---
runtime/core/Clownfish/LockFreeRegistry.cfh | 3 ---
runtime/perl/xs/XSBind.c | 26 -------------------
5 files changed, 71 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/859ee7e1/runtime/c/src/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/c/src/Clownfish/Class.c b/runtime/c/src/Clownfish/Class.c
index 4c626d9..61aec84 100644
--- a/runtime/c/src/Clownfish/Class.c
+++ b/runtime/c/src/Clownfish/Class.c
@@ -81,10 +81,3 @@ Class_find_parent_class(String *class_name) {
UNREACHABLE_RETURN(String*);
}
-void*
-Class_To_Host_IMP(Class *self) {
- UNUSED_VAR(self);
- THROW(ERR, "TODO");
- UNREACHABLE_RETURN(void*);
-}
-
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/859ee7e1/runtime/c/src/Clownfish/LockFreeRegistry.c
----------------------------------------------------------------------
diff --git a/runtime/c/src/Clownfish/LockFreeRegistry.c b/runtime/c/src/Clownfish/LockFreeRegistry.c
deleted file mode 100644
index 396b78b..0000000
--- a/runtime/c/src/Clownfish/LockFreeRegistry.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define C_CFISH_LOCKFREEREGISTRY
-#define CFISH_USE_SHORT_NAMES
-
-#include "charmony.h"
-
-#include "Clownfish/LockFreeRegistry.h"
-#include "Clownfish/Err.h"
-
-void*
-LFReg_To_Host_IMP(LockFreeRegistry *self) {
- UNUSED_VAR(self);
- THROW(ERR, "TODO");
- UNREACHABLE_RETURN(void*);
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/859ee7e1/runtime/core/Clownfish/Class.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.cfh b/runtime/core/Clownfish/Class.cfh
index 4229ff2..968c512 100644
--- a/runtime/core/Clownfish/Class.cfh
+++ b/runtime/core/Clownfish/Class.cfh
@@ -147,9 +147,6 @@ class Clownfish::Class inherits Clownfish::Obj {
uint32_t
Get_RefCount(Class *self);
- void*
- To_Host(Class *self);
-
public void
Destroy(Class *self);
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/859ee7e1/runtime/core/Clownfish/LockFreeRegistry.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/LockFreeRegistry.cfh b/runtime/core/Clownfish/LockFreeRegistry.cfh
index cc8be8e..4defbcf 100644
--- a/runtime/core/Clownfish/LockFreeRegistry.cfh
+++ b/runtime/core/Clownfish/LockFreeRegistry.cfh
@@ -38,9 +38,6 @@ class Clownfish::LockFreeRegistry nickname LFReg inherits Clownfish::Obj {
public incremented LockFreeRegistry*
Clone(LockFreeRegistry *self);
- void*
- To_Host(LockFreeRegistry *self);
-
public void
Destroy(LockFreeRegistry *self);
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/859ee7e1/runtime/perl/xs/XSBind.c
----------------------------------------------------------------------
diff --git a/runtime/perl/xs/XSBind.c b/runtime/perl/xs/XSBind.c
index 8807c86..07ab582 100644
--- a/runtime/perl/xs/XSBind.c
+++ b/runtime/perl/xs/XSBind.c
@@ -775,18 +775,6 @@ cfish_Class_find_parent_class(cfish_String *class_name) {
return parent_class;
}
-void*
-CFISH_Class_To_Host_IMP(cfish_Class *self) {
- bool first_time = self->ref.count & XSBIND_REFCOUNT_FLAG ? true : false;
- CFISH_Class_To_Host_t to_host
- = CFISH_SUPER_METHOD_PTR(CFISH_CLASS, CFISH_Class_To_Host);
- SV *host_obj = (SV*)to_host(self);
- if (first_time) {
- SvSHARE((SV*)self->ref.host_obj);
- }
- return host_obj;
-}
-
/*************************** Clownfish::Method ******************************/
@@ -964,17 +952,3 @@ cfish_Err_trap(CFISH_Err_Attempt_t routine, void *context) {
return error;
}
-/*********************** Clownfish::LockFreeRegistry ************************/
-
-void*
-CFISH_LFReg_To_Host_IMP(cfish_LockFreeRegistry *self) {
- bool first_time = self->ref.count & XSBIND_REFCOUNT_FLAG ? true : false;
- CFISH_LFReg_To_Host_t to_host
- = CFISH_SUPER_METHOD_PTR(CFISH_LOCKFREEREGISTRY, CFISH_LFReg_To_Host);
- SV *host_obj = (SV*)to_host(self);
- if (first_time) {
- SvSHARE((SV*)self->ref.host_obj);
- }
- return host_obj;
-}
-
[8/9] git commit: Clone class registry in new Perl threads
Posted by nw...@apache.org.
Clone class registry in new Perl threads
Define a CLONE method in Clownfish::Class which gets invoked when a new
Perl thread is created.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/b46a4465
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/b46a4465
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/b46a4465
Branch: refs/heads/clone_class_registry
Commit: b46a4465c8bf630eef7d2bfa4fdb5d3407d0b234
Parents: bfde91c
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sun Aug 3 17:31:51 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sun Aug 3 17:46:02 2014 +0200
----------------------------------------------------------------------
runtime/core/Clownfish/Class.c | 26 ++++++++
runtime/core/Clownfish/Class.cfh | 3 +
.../perl/buildlib/Clownfish/Build/Binding.pm | 24 +++++++
runtime/perl/lib/Clownfish.pm | 2 +
runtime/perl/t/binding/600-threads.t | 70 ++++++++++++++++++++
5 files changed, 125 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b46a4465/runtime/core/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index a60aca9..8070fc1 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -355,6 +355,32 @@ Class_fetch_class(String *class_name) {
return (Class*)LFReg_Fetch(registry, (Obj*)class_name);
}
+LockFreeRegistry*
+Class_clone_registry(LockFreeRegistry *registry) {
+ LockFreeRegistry *twin = LFReg_Clone(registry);
+ LFRegIterator *iter = LFRegIter_new(twin);
+ Obj *value = NULL;
+
+ // Fix up parent pointers.
+ while (LFRegIter_Next(iter, NULL, &value)) {
+ Class *klass = (Class*)value;
+ Class *orig_parent = klass->parent;
+
+ if (orig_parent) {
+ String *parent_name = Class_Get_Name(orig_parent);
+ Class *twin_parent = (Class*)LFReg_Fetch(twin, (Obj*)parent_name);
+ if (!twin_parent) {
+ THROW(ERR, "Class '%o' not found in cloned registry",
+ parent_name);
+ }
+ klass->parent = twin_parent;
+ }
+ }
+ DECREF(iter);
+
+ return twin;
+}
+
void
Class_Add_Host_Method_Alias_IMP(Class *self, const char *alias,
const char *meth_name) {
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b46a4465/runtime/core/Clownfish/Class.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.cfh b/runtime/core/Clownfish/Class.cfh
index 69dc5a4..4229ff2 100644
--- a/runtime/core/Clownfish/Class.cfh
+++ b/runtime/core/Clownfish/Class.cfh
@@ -79,6 +79,9 @@ class Clownfish::Class inherits Clownfish::Obj {
inert nullable Class*
fetch_class(String *class_name);
+ inert LockFreeRegistry*
+ clone_registry(LockFreeRegistry *registry);
+
/** Given a class name, return the name of a parent class which descends
* from Clownfish::Obj, or NULL if such a class can't be found.
*/
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b46a4465/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 1b1d3c5..9b1d12e 100644
--- a/runtime/perl/buildlib/Clownfish/Build/Binding.pm
+++ b/runtime/perl/buildlib/Clownfish/Build/Binding.pm
@@ -616,6 +616,30 @@ CODE:
RETVAL = (SV*)CFISH_Class_To_Host(singleton);
}
OUTPUT: RETVAL
+
+void
+CLONE(class_sv, ...)
+ SV *class_sv;
+PPCODE:
+{
+ const char *class_name = SvPV_nolen(class_sv);
+
+ if (strcmp(class_name, "Clownfish::Class") == 0) {
+ SV *registry_sv = get_sv("Clownfish::Class::_registry", 0);
+
+ if (registry_sv) {
+ cfish_LockFreeRegistry *registry;
+ SV *new_sv;
+
+ registry = (cfish_LockFreeRegistry*)XSBind_sv_to_cfish_obj(
+ registry_sv, CFISH_LOCKFREEREGISTRY, NULL);
+ registry = cfish_Class_clone_registry(registry);
+ new_sv = CFISH_Obj_To_Host((cfish_Obj*)registry);
+ sv_setsv(registry_sv, new_sv);
+ SvREFCNT_dec(new_sv);
+ }
+ }
+}
END_XS_CODE
my $binding = Clownfish::CFC::Binding::Perl::Class->new(
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b46a4465/runtime/perl/lib/Clownfish.pm
----------------------------------------------------------------------
diff --git a/runtime/perl/lib/Clownfish.pm b/runtime/perl/lib/Clownfish.pm
index 5f1bdd1..4109004 100644
--- a/runtime/perl/lib/Clownfish.pm
+++ b/runtime/perl/lib/Clownfish.pm
@@ -77,6 +77,8 @@ sub error {$Clownfish::Err::error}
our $VERSION = '0.003000';
$VERSION = eval $VERSION;
no warnings 'redefine';
+ # Clone LFReg manually.
+ sub CLONE_SKIP { 0; }
sub DESTROY { } # leak all
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b46a4465/runtime/perl/t/binding/600-threads.t
----------------------------------------------------------------------
diff --git a/runtime/perl/t/binding/600-threads.t b/runtime/perl/t/binding/600-threads.t
new file mode 100644
index 0000000..42e11d7
--- /dev/null
+++ b/runtime/perl/t/binding/600-threads.t
@@ -0,0 +1,70 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+use strict;
+use warnings;
+
+use threads;
+
+use Clownfish;
+use Test::More tests => 7;
+
+sub cf_addr {
+ my $obj = shift;
+ return 0 + $$obj;
+}
+
+my $obj = Clownfish::String->new('A string.');
+my $registry_addr = cf_addr(Clownfish::Class->_get_registry);
+my $class = Clownfish::Class->fetch_class('Clownfish::Hash');
+my $class_addr = cf_addr($class);
+my $parent = $class->get_parent;
+my $parent_addr = cf_addr($parent);
+
+my ($thread) = threads->create(sub {
+ my $thr_registry = Clownfish::Class->_get_registry;
+ my $thr_class = Clownfish::Class->fetch_class('Clownfish::Hash');
+ my $thr_parent = $thr_class->get_parent;
+ my $thr_other_parent
+ = Clownfish::Class->fetch_class($thr_parent->get_name);
+ return (
+ defined($$obj),
+ cf_addr($thr_registry),
+ cf_addr($thr_class),
+ cf_addr($thr_parent),
+ cf_addr($thr_other_parent),
+ );
+});
+my (
+ $thr_obj_defined,
+ $thr_registry_addr,
+ $thr_class_addr,
+ $thr_parent_addr,
+ $thr_other_parent_addr,
+) = $thread->join;
+
+ok( !$thr_obj_defined, "Object is undefined in other thread" );
+
+my $other_registry_addr = cf_addr(Clownfish::Class->_get_registry);
+my $other_class = Clownfish::Class->fetch_class('Clownfish::Hash');
+my $other_class_addr = cf_addr($class);
+
+is( $other_registry_addr, $registry_addr, "Same registry in same thread" );
+is( $other_class_addr, $class_addr, "Same class in same thread" );
+isnt( $thr_registry_addr, $registry_addr, "Cloned registry in other thread" );
+isnt( $thr_class_addr, $class_addr, "Cloned class in other thread" );
+isnt( $thr_parent_addr, $parent_addr, "Cloned parent class in other thread" );
+is( $thr_parent_addr, $thr_other_parent_addr, "Parent classes fixed up" );
+
[3/9] git commit: Special case String hash keys
Posted by nw...@apache.org.
Special case String hash keys
For immutable strings, it's enough to incref the hash key.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/a081f6b5
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/a081f6b5
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/a081f6b5
Branch: refs/heads/clone_class_registry
Commit: a081f6b590653b3e3fc3ca5cba1d4cc356c426a9
Parents: a360af7
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sun Aug 3 14:11:46 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sun Aug 3 17:38:04 2014 +0200
----------------------------------------------------------------------
runtime/core/Clownfish/Hash.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a081f6b5/runtime/core/Clownfish/Hash.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Hash.c b/runtime/core/Clownfish/Hash.c
index 987631c..70181c0 100644
--- a/runtime/core/Clownfish/Hash.c
+++ b/runtime/core/Clownfish/Hash.c
@@ -16,6 +16,7 @@
#define C_CFISH_HASH
#define C_CFISH_HASHTOMBSTONE
+#define C_CFISH_OBJ
#define CFISH_USE_SHORT_NAMES
#include <string.h>
@@ -166,7 +167,13 @@ Obj*
Hash_Make_Key_IMP(Hash *self, Obj *key, int32_t hash_sum) {
UNUSED_VAR(self);
UNUSED_VAR(hash_sum);
- return Obj_Clone(key);
+ if (key->klass == STRING || key->klass == STACKSTRING) {
+ // Strings are immutable.
+ return INCREF(key);
+ }
+ else {
+ return Obj_Clone(key);
+ }
}
Obj*
[6/9] git commit: Make sure to clone a Class's methods
Posted by nw...@apache.org.
Make sure to clone a Class's methods
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/fd30d706
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/fd30d706
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/fd30d706
Branch: refs/heads/clone_class_registry
Commit: fd30d706d5e06019c36c744d3023954d73614f75
Parents: 8598709
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sun Aug 3 14:32:07 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sun Aug 3 17:38:04 2014 +0200
----------------------------------------------------------------------
runtime/core/Clownfish/Class.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/fd30d706/runtime/core/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index 6a3ce9d..a60aca9 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -180,7 +180,8 @@ Class_Clone_IMP(Class *self) {
memcpy(twin, self, self->class_alloc_size);
Class_Init_Obj(self->klass, twin); // Set refcount.
- twin->name = Str_Clone(self->name);
+ twin->name = Str_Clone(self->name);
+ twin->methods = VA_Clone(self->methods);
return twin;
}
[2/9] git commit: Implement Method#Clone
Posted by nw...@apache.org.
Implement Method#Clone
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/8598709b
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/8598709b
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/8598709b
Branch: refs/heads/clone_class_registry
Commit: 8598709b6b163f795df1f2b0a4a5de4a7f6b3335
Parents: a081f6b
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sun Aug 3 14:19:35 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sun Aug 3 17:38:04 2014 +0200
----------------------------------------------------------------------
runtime/core/Clownfish/Method.c | 15 ++++++++++++++-
runtime/core/Clownfish/Method.cfh | 3 +++
2 files changed, 17 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8598709b/runtime/core/Clownfish/Method.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Method.c b/runtime/core/Clownfish/Method.c
index d7a7327..52ecd0d 100644
--- a/runtime/core/Clownfish/Method.c
+++ b/runtime/core/Clownfish/Method.c
@@ -31,7 +31,7 @@ Method_new(String *name, cfish_method_t callback_func, size_t offset) {
Method*
Method_init(Method *self, String *name, cfish_method_t callback_func,
size_t offset) {
- self->name = Str_Clone(name);
+ self->name = (String*)INCREF(name);
self->host_alias = NULL;
self->callback_func = callback_func;
self->offset = offset;
@@ -39,6 +39,19 @@ Method_init(Method *self, String *name, cfish_method_t callback_func,
return self;
}
+Method*
+Method_Clone_IMP(Method *self) {
+ String *name = Str_Clone(self->name);
+ Method *twin = Method_new(name, self->callback_func, self->offset);
+ DECREF(name);
+
+ if (self->host_alias) {
+ twin->host_alias = Str_Clone(self->host_alias);
+ }
+
+ return twin;
+}
+
void
Method_Destroy_IMP(Method *self) {
THROW(ERR, "Insane attempt to destroy Method '%o'", self->name);
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8598709b/runtime/core/Clownfish/Method.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Method.cfh b/runtime/core/Clownfish/Method.cfh
index feab12f..1294a7c 100644
--- a/runtime/core/Clownfish/Method.cfh
+++ b/runtime/core/Clownfish/Method.cfh
@@ -46,6 +46,9 @@ class Clownfish::Method inherits Clownfish::Obj {
incremented String*
Host_Name(Method *self);
+ public incremented Method*
+ Clone(Method *self);
+
incremented Obj*
Inc_RefCount(Method *self);
[5/9] git commit: Implement LFReg#Clone
Posted by nw...@apache.org.
Implement LFReg#Clone
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/c1d89c3a
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/c1d89c3a
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/c1d89c3a
Branch: refs/heads/clone_class_registry
Commit: c1d89c3a3ab7c152da1165ae190ead024aafb9d5
Parents: fd30d70
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sun Aug 3 14:53:13 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sun Aug 3 17:38:04 2014 +0200
----------------------------------------------------------------------
runtime/core/Clownfish/LockFreeRegistry.c | 23 ++++++++++++++++++++
runtime/core/Clownfish/LockFreeRegistry.cfh | 9 +++++---
.../core/Clownfish/Test/TestLockFreeRegistry.c | 9 +++++++-
3 files changed, 37 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c1d89c3a/runtime/core/Clownfish/LockFreeRegistry.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/LockFreeRegistry.c b/runtime/core/Clownfish/LockFreeRegistry.c
index c95a791..fab4f54 100644
--- a/runtime/core/Clownfish/LockFreeRegistry.c
+++ b/runtime/core/Clownfish/LockFreeRegistry.c
@@ -106,6 +106,29 @@ LFReg_Fetch_IMP(LockFreeRegistry *self, Obj *key) {
return NULL;
}
+LockFreeRegistry*
+LFReg_Clone_IMP(LockFreeRegistry *self) {
+ size_t capacity = self->capacity;
+ LFRegEntry **entries = (LFRegEntry**)self->entries;
+ LockFreeRegistry *twin = LFReg_new(capacity);
+
+ for (size_t i = 0; i < capacity; ++i) {
+ LFRegEntry *entry = entries[i];
+
+ while (entry) {
+ Obj *key = Obj_Clone(entry->key);
+ Obj *value = Obj_Clone(entry->value);
+ LFReg_Register(twin, key, value);
+ DECREF(key);
+ DECREF(value);
+
+ entry = entry->next;
+ }
+ }
+
+ return twin;
+}
+
void
LFReg_Destroy_IMP(LockFreeRegistry *self) {
LFRegEntry **entries = (LFRegEntry**)self->entries;
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c1d89c3a/runtime/core/Clownfish/LockFreeRegistry.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/LockFreeRegistry.cfh b/runtime/core/Clownfish/LockFreeRegistry.cfh
index bb41fbd..2061a23 100644
--- a/runtime/core/Clownfish/LockFreeRegistry.cfh
+++ b/runtime/core/Clownfish/LockFreeRegistry.cfh
@@ -29,17 +29,20 @@ class Clownfish::LockFreeRegistry nickname LFReg inherits Clownfish::Obj {
inert LockFreeRegistry*
init(LockFreeRegistry *self, size_t capacity);
- public void
- Destroy(LockFreeRegistry *self);
-
bool
Register(LockFreeRegistry *self, Obj *key, Obj *value);
nullable Obj*
Fetch(LockFreeRegistry *self, Obj *key);
+ public incremented LockFreeRegistry*
+ Clone(LockFreeRegistry *self);
+
void*
To_Host(LockFreeRegistry *self);
+
+ public void
+ Destroy(LockFreeRegistry *self);
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c1d89c3a/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestLockFreeRegistry.c b/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
index 46d725e..fb69065 100644
--- a/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
+++ b/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
@@ -66,6 +66,13 @@ test_all(TestBatchRunner *runner) {
TEST_TRUE(runner, LFReg_Fetch(registry, (Obj*)baz) == NULL,
"Fetch() non-existent key returns NULL");
+ LockFreeRegistry *twin = LFReg_Clone(registry);
+ Obj *twin_entry = LFReg_Fetch(twin, (Obj*)foo);
+ TEST_TRUE(runner, twin_entry != NULL, "Fetch() from clone");
+ TEST_TRUE(runner, Obj_Equals(twin_entry, (Obj*)foo),
+ "Fetch() from clone returns equal entry");
+ TEST_TRUE(runner, twin_entry != (Obj*)foo, "Clone() performs deep clone");
+
DECREF(foo_dupe);
DECREF(baz);
DECREF(bar);
@@ -75,7 +82,7 @@ test_all(TestBatchRunner *runner) {
void
TestLFReg_Run_IMP(TestLockFreeRegistry *self, TestBatchRunner *runner) {
- TestBatchRunner_Plan(runner, (TestBatch*)self, 6);
+ TestBatchRunner_Plan(runner, (TestBatch*)self, 9);
test_all(runner);
}