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);
     }