mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-04-22 09:40:38 -07:00
Hash tables are no longer implicitly locked
This commit is contained in:
parent
ac26a9db1f
commit
cc2b0901f9
6 changed files with 14 additions and 51 deletions
|
|
@ -75,6 +75,11 @@ ECL 11.7.1:
|
|||
libraries to be linked with other programs. The name of the function typically
|
||||
begins with main_dll or main_lib but it is output by ECL on screen.
|
||||
|
||||
- Hash tables do no longer have implicit locking. All complex structures in
|
||||
ECL (arrays, hash tables, objects) should be dealt with sufficient care on
|
||||
the user side, just as in other programming languages, making use of
|
||||
WITH-LOCK and similar facilities.
|
||||
|
||||
;;; Local Variables: ***
|
||||
;;; mode:text ***
|
||||
;;; fill-column:79 ***
|
||||
|
|
|
|||
38
src/c/hash.d
38
src/c/hash.d
|
|
@ -401,9 +401,7 @@ ecl_gethash(cl_object key, cl_object hashtable)
|
|||
cl_object output;
|
||||
|
||||
assert_type_hash_table(@[gethash], 2, hashtable);
|
||||
HASH_TABLE_LOCK(hashtable);
|
||||
output = hashtable->hash.get(key, hashtable)->value;
|
||||
HASH_TABLE_UNLOCK(hashtable);
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
@ -413,11 +411,9 @@ ecl_gethash_safe(cl_object key, cl_object hashtable, cl_object def)
|
|||
struct ecl_hashtable_entry *e;
|
||||
|
||||
assert_type_hash_table(@[gethash], 2, hashtable);
|
||||
HASH_TABLE_LOCK(hashtable);
|
||||
e = hashtable->hash.get(key, hashtable);
|
||||
if (e->key != OBJNULL)
|
||||
def = e->value;
|
||||
HASH_TABLE_UNLOCK(hashtable);
|
||||
return def;
|
||||
}
|
||||
|
||||
|
|
@ -431,9 +427,7 @@ cl_object
|
|||
ecl_sethash(cl_object key, cl_object hashtable, cl_object value)
|
||||
{
|
||||
assert_type_hash_table(@[si::hash-set], 2, hashtable);
|
||||
HASH_TABLE_LOCK(hashtable);
|
||||
hashtable = hashtable->hash.set(key, hashtable, value);
|
||||
HASH_TABLE_UNLOCK(hashtable);
|
||||
return hashtable;
|
||||
}
|
||||
|
||||
|
|
@ -492,11 +486,9 @@ ecl_extend_hashtable(cl_object hashtable)
|
|||
@(defun make_hash_table (&key (test @'eql')
|
||||
(size MAKE_FIXNUM(1024))
|
||||
(rehash_size cl_core.rehash_size)
|
||||
(rehash_threshold cl_core.rehash_threshold)
|
||||
(lockable Cnil))
|
||||
(rehash_threshold cl_core.rehash_threshold))
|
||||
@
|
||||
@(return cl__make_hash_table(test, size, rehash_size, rehash_threshold,
|
||||
lockable))
|
||||
@(return cl__make_hash_table(test, size, rehash_size, rehash_threshold))
|
||||
@)
|
||||
|
||||
static void
|
||||
|
|
@ -519,7 +511,7 @@ ecl_def_ct_single_float(min_threshold, 0.1, static, const);
|
|||
|
||||
cl_object
|
||||
cl__make_hash_table(cl_object test, cl_object size, cl_object rehash_size,
|
||||
cl_object rehash_threshold, cl_object lockable)
|
||||
cl_object rehash_threshold)
|
||||
{
|
||||
int htt;
|
||||
cl_index hsize;
|
||||
|
|
@ -609,14 +601,6 @@ cl__make_hash_table(cl_object test, cl_object size, cl_object rehash_size,
|
|||
h->hash.data = (struct ecl_hashtable_entry *)
|
||||
ecl_alloc(hsize * sizeof(struct ecl_hashtable_entry));
|
||||
do_clrhash(h);
|
||||
|
||||
#ifdef ECL_THREADS
|
||||
if (!Null(lockable)) {
|
||||
h->hash.lock = mp_make_lock(2, @':recursive', Ct);
|
||||
} else {
|
||||
h->hash.lock = Cnil;
|
||||
}
|
||||
#endif
|
||||
return h;
|
||||
}
|
||||
|
||||
|
|
@ -630,9 +614,7 @@ cl_hash_table_p(cl_object ht)
|
|||
struct ecl_hashtable_entry e;
|
||||
@
|
||||
assert_type_hash_table(@[gethash], 2, ht);
|
||||
HASH_TABLE_LOCK(ht);
|
||||
e = *(ht->hash.get(key, ht));
|
||||
HASH_TABLE_UNLOCK(ht);
|
||||
if (e.key != OBJNULL)
|
||||
@(return e.value Ct)
|
||||
else
|
||||
|
|
@ -654,7 +636,6 @@ ecl_remhash(cl_object key, cl_object hashtable)
|
|||
bool output;
|
||||
|
||||
assert_type_hash_table(@[remhash], 2, hashtable);
|
||||
HASH_TABLE_LOCK(hashtable);
|
||||
e = hashtable->hash.get(key, hashtable);
|
||||
if (e->key == OBJNULL) {
|
||||
output = FALSE;
|
||||
|
|
@ -664,7 +645,6 @@ ecl_remhash(cl_object key, cl_object hashtable)
|
|||
hashtable->hash.entries--;
|
||||
output = TRUE;
|
||||
}
|
||||
HASH_TABLE_UNLOCK(hashtable);
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
@ -680,9 +660,7 @@ cl_clrhash(cl_object ht)
|
|||
{
|
||||
assert_type_hash_table(@[clrhash], 1, ht);
|
||||
if (ht->hash.entries) {
|
||||
HASH_TABLE_LOCK(ht);
|
||||
do_clrhash(ht);
|
||||
HASH_TABLE_UNLOCK(ht);
|
||||
}
|
||||
@(return ht)
|
||||
}
|
||||
|
|
@ -821,20 +799,12 @@ cl_object
|
|||
si_copy_hash_table(cl_object orig)
|
||||
{
|
||||
cl_object hash;
|
||||
#ifdef ECL_THREADS
|
||||
cl_object lockable = orig->hash.lock;
|
||||
#else
|
||||
cl_object lockable = Cnil;
|
||||
#endif
|
||||
hash = cl__make_hash_table(cl_hash_table_test(orig),
|
||||
cl_hash_table_size(orig),
|
||||
cl_hash_table_rehash_size(orig),
|
||||
cl_hash_table_rehash_threshold(orig),
|
||||
lockable);
|
||||
HASH_TABLE_LOCK(hash);
|
||||
cl_hash_table_rehash_threshold(orig));
|
||||
memcpy(hash->hash.data, orig->hash.data,
|
||||
orig->hash.size * sizeof(*orig->hash.data));
|
||||
hash->hash.entries = orig->hash.entries;
|
||||
HASH_TABLE_UNLOCK(hash);
|
||||
@(return hash)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,8 +311,7 @@ init_pool(pool_t pool, cl_object root)
|
|||
MAKE_FIXNUM(0));
|
||||
pool->hash = cl__make_hash_table(@'eql', MAKE_FIXNUM(256),
|
||||
cl_core.rehash_size,
|
||||
cl_core.rehash_threshold,
|
||||
Cnil);
|
||||
cl_core.rehash_threshold);
|
||||
ecl_sethash(root, pool->hash, MAKE_FIXNUM(0));
|
||||
pool->queue = ecl_list1(root);
|
||||
pool->last = pool->queue;
|
||||
|
|
|
|||
|
|
@ -777,7 +777,7 @@ extern ECL_API cl_object _ecl_standard_dispatch(cl_object frame, cl_object fun);
|
|||
|
||||
/* hash.c */
|
||||
|
||||
extern ECL_API cl_object cl__make_hash_table(cl_object test, cl_object size, cl_object rehash_size, cl_object rehash_threshold, cl_object lockable);
|
||||
extern ECL_API cl_object cl__make_hash_table(cl_object test, cl_object size, cl_object rehash_size, cl_object rehash_threshold);
|
||||
extern ECL_API cl_object cl_hash_table_p(cl_object ht);
|
||||
extern ECL_API cl_object si_hash_set(cl_object key, cl_object ht, cl_object val);
|
||||
extern ECL_API cl_object cl_remhash(cl_object key, cl_object ht);
|
||||
|
|
@ -1530,7 +1530,7 @@ extern ECL_API int ecl_current_read_base(void);
|
|||
extern ECL_API char ecl_current_read_default_float_format(void);
|
||||
#define ecl_read_from_cstring(s) si_string_to_object(1,make_constant_base_string(s))
|
||||
#define ecl_read_from_cstring_safe(s,v) si_string_to_object(2,make_constant_base_string(s),(v))
|
||||
extern ECL_API cl_object read_VV(cl_object block, void (*entry)(cl_object));
|
||||
extern ECL_API cl_object ecl_init_module(cl_object block, void (*entry)(cl_object));
|
||||
|
||||
/* reference.c */
|
||||
|
||||
|
|
@ -2158,6 +2158,8 @@ extern ECL_API cl_object clos_standard_instance_set _ARGS((cl_narg narg, cl_obje
|
|||
|
||||
#define ecl_search_hash _ecl_gethash
|
||||
|
||||
#define ecl_init_module read_VV
|
||||
|
||||
#endif
|
||||
|
||||
#define make_simple_base_string(s) ecl_make_simple_base_string((s),-1)
|
||||
|
|
|
|||
|
|
@ -341,14 +341,6 @@ extern void cl_write_object(cl_object x, cl_object stream);
|
|||
/* global locks */
|
||||
|
||||
#ifdef ECL_THREADS
|
||||
# define HASH_TABLE_LOCK(h) do { \
|
||||
cl_object lock = (h)->hash.lock; \
|
||||
if (lock != Cnil) mp_get_lock_wait(lock); \
|
||||
} while (0);
|
||||
# define HASH_TABLE_UNLOCK(h) do { \
|
||||
cl_object lock = (h)->hash.lock; \
|
||||
if (lock != Cnil) mp_giveup_lock(lock); \
|
||||
} while (0);
|
||||
# define ECL_WITH_GLOBAL_LOCK_BEGIN(the_env) \
|
||||
ECL_WITH_LOCK_BEGIN(the_env, cl_core.global_lock)
|
||||
# define ECL_WITH_GLOBAL_LOCK_END \
|
||||
|
|
@ -379,8 +371,6 @@ extern void cl_write_object(cl_object x, cl_object stream);
|
|||
ecl_enable_interrupts_env(__ecl_the_env); \
|
||||
} CL_UNWIND_PROTECT_END; }
|
||||
#else
|
||||
# define HASH_TABLE_LOCK(h)
|
||||
# define HASH_TABLE_UNLOCK(h)
|
||||
# define ECL_WITH_GLOBAL_LOCK_BEGIN(the_env)
|
||||
# define ECL_WITH_GLOBAL_LOCK_END
|
||||
# define ECL_WITH_PACKAGE_RDLOCK_BEGIN(the_env)
|
||||
|
|
|
|||
|
|
@ -380,9 +380,6 @@ struct ecl_hashtable { /* hash table header */
|
|||
cl_object rehash_size; /* rehash size */
|
||||
cl_object threshold; /* rehash threshold */
|
||||
double factor; /* cached value of threshold */
|
||||
#ifdef ECL_THREADS
|
||||
cl_object lock; /* mutex to prevent race conditions */
|
||||
#endif
|
||||
struct ecl_hashtable_entry *(*get)(cl_object, cl_object);
|
||||
cl_object (*set)(cl_object, cl_object, cl_object);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue