Hash tables are no longer implicitly locked

This commit is contained in:
Juan Jose Garcia Ripoll 2011-07-31 15:24:50 +02:00
parent ac26a9db1f
commit cc2b0901f9
6 changed files with 14 additions and 51 deletions

View file

@ -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 ***

View file

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

View file

@ -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;

View file

@ -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)

View file

@ -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)

View file

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