From 89ad07fefc886c765a51ee414de529bcb36d4c53 Mon Sep 17 00:00:00 2001 From: Juan Jose Garcia Ripoll Date: Sun, 24 Oct 2010 00:00:22 +0200 Subject: [PATCH] The list of packages to be created is now thread-local and its manipulation is thus thread safe. --- src/c/main.d | 6 ++++-- src/c/package.d | 50 +++++++++++++++++++++++++++++++++++------------- src/c/read.d | 24 +++++++++-------------- src/h/external.h | 7 +++++-- src/h/internal.h | 4 ++++ 5 files changed, 59 insertions(+), 32 deletions(-) diff --git a/src/c/main.d b/src/c/main.d index 385c45488..c37144d48 100644 --- a/src/c/main.d +++ b/src/c/main.d @@ -177,6 +177,9 @@ ecl_init_env(cl_env_ptr env) } env->trap_fpe_bits = 0; + + env->packages_to_be_created = Cnil; + env->packages_to_be_created_p = Cnil; } void @@ -382,8 +385,6 @@ struct cl_core_struct cl_core = { #endif Cnil, /* mp_package */ Cnil, /* c_package */ - Cnil, /* packages_to_be_created */ - Cnil, /* packages_to_be_created_p */ Cnil, /* pathname_translations */ Cnil, /* library_pathname */ @@ -538,6 +539,7 @@ cl_boot(int argc, char **argv) cl_core.path_max = MAXPATHLEN; #endif + env->packages_to_be_created = Cnil; cl_core.lisp_package = ecl_make_package(str_common_lisp, cl_list(2, str_cl, str_LISP), diff --git a/src/c/package.d b/src/c/package.d index 4a6de2685..b40953f25 100644 --- a/src/c/package.d +++ b/src/c/package.d @@ -120,9 +120,41 @@ make_package_hashtable() Cnil); /* lockable */ } +static cl_object +alloc_package(cl_object name) +{ + cl_object p = ecl_alloc_object(t_package); + p->pack.internal = make_package_hashtable(); + p->pack.external = make_package_hashtable(); + p->pack.name = name; + p->pack.nicknames = Cnil; + p->pack.shadowings = Cnil; + p->pack.uses = Cnil; + p->pack.usedby = Cnil; + p->pack.locked = FALSE; + return p; +} + +cl_object +_ecl_package_to_be_created(cl_env_ptr env, cl_object name) +{ + cl_object package = ecl_assoc(name, env->packages_to_be_created); + if (Null(package)) { + const cl_env_ptr env = ecl_process_env(); + package = alloc_package(name); + env->packages_to_be_created = + cl_acons(name, package, env->packages_to_be_created); + } else { + package = ECL_CONS_CDR(package); + } + return package; +} + + cl_object ecl_make_package(cl_object name, cl_object nicknames, cl_object use_list) { + const cl_env_ptr env = ecl_process_env(); cl_object x, y, other; name = cl_string(name); @@ -133,8 +165,8 @@ ecl_make_package(cl_object name, cl_object nicknames, cl_object use_list) * created and use it. */ PACKAGE_OP_LOCK(); - { - cl_object l = cl_core.packages_to_be_created; + if (ecl_get_option(ECL_OPT_BOOTED)) { + cl_object l = env->packages_to_be_created; while (!Null(l)) { cl_object pair = ECL_CONS_CAR(l); cl_object other_name = ECL_CONS_CAR(pair); @@ -143,9 +175,9 @@ ecl_make_package(cl_object name, cl_object nicknames, cl_object use_list) @':test', @'string=') != Cnil) { x = ECL_CONS_CDR(pair); - cl_core.packages_to_be_created = + env->packages_to_be_created = ecl_remove_eq(pair, - cl_core.packages_to_be_created); + env->packages_to_be_created); goto INTERN; } l = ECL_CONS_CDR(l); @@ -160,16 +192,8 @@ ecl_make_package(cl_object name, cl_object nicknames, cl_object use_list) other, 1, name); return other; } - x = ecl_alloc_object(t_package); - x->pack.internal = make_package_hashtable(); - x->pack.external = make_package_hashtable(); + x = alloc_package(name); INTERN: - x->pack.name = name; - x->pack.nicknames = Cnil; - x->pack.shadowings = Cnil; - x->pack.uses = Cnil; - x->pack.usedby = Cnil; - x->pack.locked = FALSE; loop_for_in(nicknames) { cl_object nick = cl_string(ECL_CONS_CAR(nicknames)); if ((other = ecl_find_package_nolock(nick)) != Cnil) { diff --git a/src/c/read.d b/src/c/read.d index 24f0e120e..2db82ce5d 100644 --- a/src/c/read.d +++ b/src/c/read.d @@ -252,17 +252,11 @@ LOOP: all referenced packages have been properly built. */ cl_object name = cl_copy_seq(token); - unlikely_if (cl_core.packages_to_be_created_p == Cnil) { + unlikely_if (Null(the_env->packages_to_be_created_p)) { FEerror("There is no package with the name ~A.", 1, name); - } else if (!Null(p = ecl_assoc(name, cl_core.packages_to_be_created))) { - p = CDR(p); - } else { - p = ecl_make_package(name,Cnil,Cnil); - cl_core.packages = CDR(cl_core.packages); - cl_core.packages_to_be_created = - cl_acons(name, p, cl_core.packages_to_be_created); } + p = _ecl_package_to_be_created(the_env, name); } TOKEN_STRING_FILLP(token) = length = 0; upcase = count = colon = 0; @@ -2154,7 +2148,7 @@ cl_object read_VV(cl_object block, void (*entry_point)(cl_object)) { const cl_env_ptr env = ecl_process_env(); - volatile cl_object old_eptbc = cl_core.packages_to_be_created; + volatile cl_object old_eptbc = env->packages_to_be_created; volatile cl_object x; cl_index i, len, perm_len, temp_len; cl_object in; @@ -2188,7 +2182,7 @@ read_VV(cl_object block, void (*entry_point)(cl_object)) cl_object progv_list; ecl_bds_bind(env, @'si::*cblock*', block); - cl_core.packages_to_be_created_p = Ct; + env->packages_to_be_created_p = Ct; /* Communicate the library which Cblock we are using, and get * back the amount of data to be processed. @@ -2266,7 +2260,7 @@ read_VV(cl_object block, void (*entry_point)(cl_object)) "binary file", in, 0); #endif NO_DATA_LABEL: - cl_core.packages_to_be_created_p = Cnil; + env->packages_to_be_created_p = Cnil; for (i = 0; i < block->cblock.cfuns_size; i++) { const struct ecl_cfun *prototype = block->cblock.cfuns+i; @@ -2290,8 +2284,8 @@ read_VV(cl_object block, void (*entry_point)(cl_object)) } /* Execute top-level code */ (*entry_point)(MAKE_FIXNUM(0)); - x = cl_set_difference(2, cl_core.packages_to_be_created, old_eptbc); - old_eptbc = cl_core.packages_to_be_created; + x = cl_set_difference(2, env->packages_to_be_created, old_eptbc); + old_eptbc = env->packages_to_be_created; unlikely_if (!Null(x)) { CEerror(Ct, Null(ECL_CONS_CDR(x))? @@ -2310,8 +2304,8 @@ read_VV(cl_object block, void (*entry_point)(cl_object)) } CL_UNWIND_PROTECT_EXIT { if (in != OBJNULL) cl_close(1,in); - cl_core.packages_to_be_created = old_eptbc; - cl_core.packages_to_be_created_p = Cnil; + env->packages_to_be_created = old_eptbc; + env->packages_to_be_created_p = Cnil; } CL_UNWIND_PROTECT_END; return block; diff --git a/src/h/external.h b/src/h/external.h index 36dbabbc2..a8d1e0a5c 100755 --- a/src/h/external.h +++ b/src/h/external.h @@ -135,6 +135,11 @@ struct cl_env_struct { /* Old exception filter. Needed by windows. */ void *old_exception_filter; + + /* List of packages interned when loading a FASL but which have + * to be explicitely created by the compiled code itself. */ + cl_object packages_to_be_created; + cl_object packages_to_be_created_p; }; #ifndef __GNUC__ @@ -173,8 +178,6 @@ struct cl_core_struct { #endif cl_object mp_package; cl_object c_package; - cl_object packages_to_be_created; - cl_object packages_to_be_created_p; cl_object pathname_translations; cl_object library_pathname; diff --git a/src/h/internal.h b/src/h/internal.h index a5d52bfba..07854ee4a 100644 --- a/src/h/internal.h +++ b/src/h/internal.h @@ -341,6 +341,10 @@ extern void cl_write_object(cl_object x, cl_object stream); #define RTABSIZE CHAR_CODE_LIMIT /* read table size */ #endif +/* package.d */ + +extern cl_object _ecl_package_to_be_created(const cl_env_ptr env, cl_object name); + /* sequence.d */ typedef struct { cl_index start, end, length; } cl_index_pair; extern ECL_API cl_index_pair ecl_sequence_start_end(cl_object fun, cl_object s, cl_object start, cl_object end);