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 2016/03/19 18:27:16 UTC
[06/14] lucy-clownfish git commit: Start to make Class_bootstrap
thread-safe
Start to make Class_bootstrap thread-safe
Use Atomic_cas_ptr to write
- global class pointer
- class name
- class method array
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/ce1fe99c
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/ce1fe99c
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/ce1fe99c
Branch: refs/heads/master
Commit: ce1fe99cf3f45045af77bf717da3b17cb6549ffd
Parents: dc56c14
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Thu Mar 10 18:34:33 2016 +0100
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Thu Mar 10 21:22:50 2016 +0100
----------------------------------------------------------------------
runtime/core/Clownfish/Class.c | 40 ++++++++++++++++++++++++++++++-------
1 file changed, 33 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/ce1fe99c/runtime/core/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index 1ab7523..a96bf96 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -78,7 +78,7 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t num_specs,
+ spec->num_novel_meths
* sizeof(cfish_method_t);
- Class *klass = (Class*)Memory_wrapped_calloc(class_alloc_size, 1);
+ Class *klass = (Class*)CALLOCATE(class_alloc_size, 1);
// Needed to calculate size of subclasses.
klass->class_alloc_size = class_alloc_size;
@@ -92,7 +92,10 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t num_specs,
}
// Initialize the global pointer to the Class.
- *spec->klass = klass;
+ if (!Atomic_cas_ptr((void**)spec->klass, NULL, klass)) {
+ // Another thread beat us to it.
+ FREEMEM(klass);
+ }
}
/* Pass 2:
@@ -203,9 +206,24 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t num_specs,
const ClassSpec *spec = &specs[i];
Class *klass = *spec->klass;
- S_set_name(klass, spec->name, strlen(spec->name));
- klass->methods = (Method**)MALLOCATE((spec->num_novel_meths + 1)
- * sizeof(Method*));
+ String *name_internal
+ = Str_new_from_trusted_utf8(spec->name, strlen(spec->name));
+ if (!Atomic_cas_ptr((void**)&klass->name_internal, NULL,
+ name_internal)
+ ) {
+ DECREF(name_internal);
+ name_internal = klass->name_internal;
+ }
+
+ String *name = Str_new_wrap_trusted_utf8(Str_Get_Ptr8(name_internal),
+ Str_Get_Size(name_internal));
+ if (!Atomic_cas_ptr((void**)&klass->name, NULL, name)) {
+ DECREF(name);
+ name = klass->name;
+ }
+
+ Method **methods = (Method**)MALLOCATE((spec->num_novel_meths + 1)
+ * sizeof(Method*));
// Only store novel methods for now.
for (size_t i = 0; i < spec->num_novel_meths; ++i) {
@@ -213,10 +231,18 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t num_specs,
String *name = SSTR_WRAP_C(mspec->name);
Method *method = Method_new(name, mspec->callback_func,
*mspec->offset);
- klass->methods[i] = method;
+ methods[i] = method;
}
- klass->methods[spec->num_novel_meths] = NULL;
+ methods[spec->num_novel_meths] = NULL;
+
+ if (!Atomic_cas_ptr((void**)&klass->methods, NULL, methods)) {
+ // Another thread beat us to it.
+ for (size_t i = 0; i < spec->num_novel_meths; ++i) {
+ Method_Destroy(methods[i]);
+ }
+ FREEMEM(methods);
+ }
Class_add_to_registry(klass);
}