diff --git a/src/c/Makefile.in b/src/c/Makefile.in index 5bf8a7757..2ea344ada 100644 --- a/src/c/Makefile.in +++ b/src/c/Makefile.in @@ -67,7 +67,7 @@ OBJS = main.o symbol.o package.o cons.o list.o\ time.o unixint.o\ mapfun.o multival.o hash.o format.o pathname.o\ structure.o load.o unixfsys.o unixsys.o \ - serialize.o ffi.o sse2.o @EXTRA_OBJS@ + serialize.o ffi.o sse2.o @EXTRA_OBJS@ threads/atomic.o .SUFFIXES: .c .o .d .s .PHONY: all diff --git a/src/c/threads/atomic.d b/src/c/threads/atomic.d index d53711e94..7cbbdcf84 100644 --- a/src/c/threads/atomic.d +++ b/src/c/threads/atomic.d @@ -20,23 +20,38 @@ #ifdef ECL_THREADS -cl_object +void ecl_atomic_push(cl_object *slot, cl_object c) { - cl_object cons = ecl_list1(c); - cl_object car; + cl_object cons = ecl_list1(c), car; do { - car = AO_load(slot); + car = (cl_object)AO_load((AO_t*)slot); ECL_RPLACD(cons, car); - } while (!AO_compare_and_swap_full(slot, car, cons)); + } while (!AO_compare_and_swap_full((AO_t*)slot, (AO_t)car, (AO_t)cons)); return cons; } -bool -ecl_compare_and_swap(cl_object *slot, cl_object old, cl_object new) +cl_object +ecl_atomic_pop(cl_object *slot) { - return AO_compare_and_swap_full(slot, car, cons); + cl_object cons, rest; + do { + cons = (cl_object)AO_load((AO_t*)slot); + rest = CDR(cons); + } while (!AO_compare_and_swap_full((AO_t*)slot, (AO_t)cons, (AO_t)rest)); + return cons; } +cl_index +ecl_atomic_index_incf(cl_index *slot) +{ + AO_t old; + AO_t next; + do { + old = AO_load((AO_t*)slot); + next = old+1; + } while (!AO_compare_and_swap_full((AO_t*)slot, (AO_t)old, (AO_t)next)); + return (cl_index)next; +} #endif /* ECL_THREADS */ diff --git a/src/h/external.h b/src/h/external.h index bfdd8ae2c..246917b99 100755 --- a/src/h/external.h +++ b/src/h/external.h @@ -1732,8 +1732,17 @@ extern ECL_API void mp_semaphore_signal(cl_object); extern ECL_API void mp_semaphore_close(cl_object); # endif -/* threads_mutex.c */ +/* threads/atomic.c */ +#ifdef ECL_THREADS +extern ECL_API void ecl_atomic_push(cl_object *slot, cl_object o); +extern ECL_API cl_object ecl_atomic_pop(cl_object *slot); +extern ECL_API cl_index ecl_atomic_index_incf(cl_index *slot); +#endif + +/* threads/mutex.c */ + +#ifdef ECL_THREADS extern ECL_API cl_object mp_make_lock _ARGS((cl_narg narg, ...)); extern ECL_API cl_object mp_recursive_lock_p(cl_object lock); extern ECL_API cl_object mp_lock_name(cl_object lock); @@ -1745,6 +1754,7 @@ extern ECL_API cl_object mp_get_lock_nowait(cl_object lock); extern ECL_API cl_object mp_giveup_lock(cl_object lock); extern ECL_API cl_object ecl_make_lock(cl_object lock, bool recursive); +#endif /* threads/rwlock.d */