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:17 UTC

[07/14] lucy-clownfish git commit: Make bootstrap_parcel thread-safe

Make bootstrap_parcel thread-safe

Remove bootstrap_inheritance.

Add bootstrap_internal which invokes Class_bootstrap and parcel_init only
for a single parcel.

Detect inheritance cycles in Class_bootstrap.


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

Branch: refs/heads/master
Commit: d7c863b92dae97fd8a7eea93364941607e4921e1
Parents: ce1fe99
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Thu Mar 10 19:06:53 2016 +0100
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Thu Mar 10 21:23:57 2016 +0100

----------------------------------------------------------------------
 compiler/src/CFCBindCore.c     | 56 +++++++++----------------------------
 runtime/core/Clownfish/Class.c | 12 +++++++-
 2 files changed, 24 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d7c863b9/compiler/src/CFCBindCore.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindCore.c b/compiler/src/CFCBindCore.c
index e5b23ce..4b2d3c6 100644
--- a/compiler/src/CFCBindCore.c
+++ b/compiler/src/CFCBindCore.c
@@ -362,13 +362,13 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
         "\n"
         "%s" // Extra definitions.
         "%sVISIBLE void\n"
-        "%sbootstrap_inheritance();\n"
+        "%sbootstrap_internal(void);\n"
         "\n"
         "%sVISIBLE void\n"
-        "%sbootstrap_parcel();\n"
+        "%sbootstrap_parcel(void);\n"
         "\n"
         "void\n"
-        "%sinit_parcel();\n"
+        "%sinit_parcel(void);\n"
         "\n"
         "#ifdef __cplusplus\n"
         "}\n"
@@ -439,30 +439,12 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
     char *spec_init_func = CFCBindSpecs_init_func_def(specs);
     FREEMEM(ordered);
 
-    // Bootstrapping code for prerequisite parcels.
-    //
-    // bootstrap_inheritance() first calls bootstrap_inheritance() for all
-    // parcels from which classes are inherited. Then the Classes of the parcel
-    // are initialized. It aborts on recursive invocation.
-    //
-    // bootstrap_parcel() first calls bootstrap_inheritance() of its own
-    // parcel. Then it calls bootstrap_parcel() for all prerequisite parcels.
-    // Finally, it calls init_parcel(). Recursive invocation is allowed.
-
-    char *inh_bootstrap    = CFCUtil_strdup("");
     char *prereq_bootstrap = CFCUtil_strdup("");
-    CFCParcel **inh_parcels = CFCParcel_inherited_parcels(parcel);
-    for (size_t i = 0; inh_parcels[i]; ++i) {
-        const char *inh_prefix = CFCParcel_get_prefix(inh_parcels[i]);
-        inh_bootstrap = CFCUtil_cat(inh_bootstrap, "    ", inh_prefix,
-                                    "bootstrap_inheritance();\n", NULL);
-    }
-    FREEMEM(inh_parcels);
     CFCParcel **prereq_parcels = CFCParcel_prereq_parcels(parcel);
     for (size_t i = 0; prereq_parcels[i]; ++i) {
         const char *prereq_prefix = CFCParcel_get_prefix(prereq_parcels[i]);
         prereq_bootstrap = CFCUtil_cat(prereq_bootstrap, "    ", prereq_prefix,
-                                       "bootstrap_parcel();\n", NULL);
+                                       "bootstrap_internal();\n", NULL);
     }
     FREEMEM(prereq_parcels);
 
@@ -490,37 +472,26 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
         "\n"
         "%s" // spec_init_func
         "\n"
-        "static int bootstrap_state = 0;\n"
-        "\n"
         "void\n"
-        "%sbootstrap_inheritance() {\n"
-        "    if (bootstrap_state == 1) {\n"
-        "        fprintf(stderr, \"Cycle in class inheritance between\"\n"
-        "                        \" parcels detected.\\n\");\n"
-        "        abort();\n"
-        "    }\n"
-        "    if (bootstrap_state >= 2) { return; }\n"
-        "    bootstrap_state = 1;\n"
-        "%s" // Bootstrap inherited parcels.
+        "%sbootstrap_internal() {\n"
+        "    static int bootstrapped = 0;\n"
+        "    if (bootstrapped) { return; }\n"
         "    S_bootstrap_specs();\n"
-        "    bootstrap_state = 2;\n"
+        "    %sinit_parcel();\n"
+        "    bootstrapped = 1;\n"
         "}\n"
         "\n"
         "void\n"
         "%sbootstrap_parcel() {\n"
-        "    if (bootstrap_state >= 3) { return; }\n"
-        "    %sbootstrap_inheritance();\n"
-        "    bootstrap_state = 3;\n"
-        "%s" // Finish bootstrapping of all prerequisite parcels.
-        "    %sinit_parcel();\n"
+        "%s" // Bootstrap prerequisite parcels.
+        "    %sbootstrap_internal();\n"
         "}\n"
         "\n"
         "%s\n";
     char *file_content
         = CFCUtil_sprintf(pattern, self->c_header, privacy_syms, includes,
-                          c_data, spec_defs, spec_init_func, prefix,
-                          inh_bootstrap, prefix, prefix, prereq_bootstrap,
-                          prefix, self->c_footer);
+                          c_data, spec_defs, spec_init_func, prefix, prefix,
+                          prefix, prereq_bootstrap, prefix, self->c_footer);
 
     // Unlink then open file.
     const char *src_dest = CFCHierarchy_get_source_dest(hierarchy);
@@ -536,7 +507,6 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
     FREEMEM(c_data);
     FREEMEM(spec_defs);
     FREEMEM(spec_init_func);
-    FREEMEM(inh_bootstrap);
     FREEMEM(prereq_bootstrap);
     FREEMEM(file_content);
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d7c863b9/runtime/core/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index a96bf96..bfa9978 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -69,7 +69,17 @@ Class_bootstrap(const cfish_ClassSpec *specs, size_t num_specs,
      */
     for (size_t i = 0; i < num_specs; ++i) {
         const ClassSpec *spec = &specs[i];
-        Class *parent = spec->parent ? *spec->parent : NULL;
+        Class *parent = NULL;
+
+        if (spec->parent) {
+            parent = *spec->parent;
+            if (!parent) {
+                // Wrong order of class specs or inheritance cycle.
+                fprintf(stderr, "Parent class of '%s' not initialized\n",
+                        spec->name);
+                abort();
+            }
+        }
 
         uint32_t novel_offset = parent
                                 ? parent->class_alloc_size