From 0fecb887e0a248bbebb56876d4b615dcd0c67097 Mon Sep 17 00:00:00 2001 From: Juanjo Garcia-Ripoll Date: Mon, 2 Apr 2012 17:12:50 +0200 Subject: [PATCH] Implemented semaphores using atomic operations --- src/aclocal.m4 | 25 +--- src/c/symbols_list.h | 20 +-- src/c/symbols_list2.h | 20 +-- src/c/threads/semaphore.d | 280 ++++++++++++-------------------------- src/configure | 79 +---------- src/configure.in | 1 - src/h/config.h.in | 2 - src/h/external.h | 21 ++- src/h/object.h | 17 ++- 9 files changed, 123 insertions(+), 342 deletions(-) diff --git a/src/aclocal.m4 b/src/aclocal.m4 index d771f5d22..b5de79c4f 100644 --- a/src/aclocal.m4 +++ b/src/aclocal.m4 @@ -248,7 +248,7 @@ THREAD_CFLAGS='' THREAD_LIBS='' THREAD_GC_FLAGS='--enable-threads=posix' INSTALL_TARGET='install' -THREAD_OBJ="$THREAD_OBJ threads/process threads/queue threads/mutex threads/condition_variable" +THREAD_OBJ="$THREAD_OBJ threads/process threads/queue threads/mutex threads/condition_variable threads/semaphore" clibs='' SONAME='' SONAME_LDFLAGS='' @@ -827,29 +827,6 @@ _mm_getcsr();]])],[sse_included=yes],[sse_included=no]) fi ]) -dnl ---------------------------------------------------------------------- -dnl Check whether we have unnamed POSIX semaphores available -AC_DEFUN([ECL_POSIX_SEMAPHORES],[ -AC_MSG_CHECKING(working sem_init()) -if test -z "$ECL_WORKING_SEM_INIT"; then - AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include -int main() { - sem_t aux; - if (sem_init(&aux, 0, 0)) - exit(1); - exit(0); -}]])],[ECL_WORKING_SEM_INIT=yes],[ECL_WORKING_SEM_INIT=no],[]) -fi -AC_MSG_RESULT([$ECL_WORKING_SEM_INIT]) -if test $ECL_WORKING_SEM_INIT = yes ; then - AC_DEFINE(ECL_SEMAPHORES) - AC_DEFINE(HAVE_SEM_INIT) - THREAD_OBJ="$THREAD_OBJ threads/semaphore" - echo $THREAD_OBJ -fi -]) - dnl ---------------------------------------------------------------------- dnl Check whether we have POSIX read/write locks are available AC_DEFUN([ECL_POSIX_RWLOCK],[ diff --git a/src/c/symbols_list.h b/src/c/symbols_list.h index 3f7b993df..811d418c2 100755 --- a/src/c/symbols_list.h +++ b/src/c/symbols_list.h @@ -66,11 +66,6 @@ typedef struct { #else # define IF_SSE2(x) NULL #endif -#if defined(ECL_SEMAPHORE) && defined(ECL_THREADS) -# define IF_SEM(x) x -#else -# define IF_SEM(x) NULL -#endif #if defined(HAVE_LIBFFI) || defined(ECL_DYNAMIC_FFI) # define IF_DFFI(x) x #else @@ -1607,17 +1602,16 @@ cl_symbols[] = { {MP_ "GIVEUP-RWLOCK-WRITE", MP_ORDINARY, IF_MP(mp_giveup_rwlock_write), 1, OBJNULL}, {MP_ "GLOBAL-LOCK", MP_ORDINARY, NULL, -1, OBJNULL}, {MP_ "ERROR-LOCK", MP_ORDINARY, NULL, -1, OBJNULL}, -/* #endif ECL_THREADS */ -/* #if defined(ECL_SEMAPHORES) && defined(ECL_THREADS) */ {MP_ "SEMAPHORE", MP_ORDINARY, NULL, -1, OBJNULL}, -{MP_ "MAKE-SEMAPHORE", MP_ORDINARY, IF_SEM(mp_make_semaphore), -1, OBJNULL}, -{MP_ "SEMAPHORE-WAIT", MP_ORDINARY, IF_SEM(mp_semaphore_wait), 1, OBJNULL}, -{MP_ "SEMAPHORE-TRYWAIT", MP_ORDINARY, IF_SEM(mp_semaphore_trywait), 1, OBJNULL}, -{MP_ "SEMAPHORE-SIGNAL", MP_ORDINARY, IF_SEM(mp_semaphore_signal), 1, OBJNULL}, -{MP_ "SEMAPHORE-CLOSE", MP_ORDINARY, IF_SEM(mp_semaphore_close), 1, OBJNULL}, +{MP_ "MAKE-SEMAPHORE", MP_ORDINARY, IF_MP(mp_make_semaphore), -1, OBJNULL}, +{MP_ "SIGNAL-SEMAPHORE", MP_ORDINARY, IF_MP(mp_signal_semaphore), -1, OBJNULL}, +{MP_ "WAIT-ON-SEMAPHORE", MP_ORDINARY, IF_MP(mp_wait_on_semaphore), 1, OBJNULL}, +{MP_ "SEMAPHORE-COUNT", MP_ORDINARY, IF_MP(mp_semaphore_count), 1, OBJNULL}, +{MP_ "SEMAPHORE-NAME", MP_ORDINARY, IF_MP(mp_semaphore_name), 1, OBJNULL}, +{MP_ "SEMAPHORE-WAIT-COUNT", MP_ORDINARY, IF_MP(mp_semaphore_wait_count), 1, OBJNULL}, {KEY_ "COUNT", KEYWORD, NULL, -1, OBJNULL}, -/* #endif defined(ECL_SEMAPHORES) && defined(ECL_THREADS) */ +/* #endif defined(ECL_THREADS) */ {SYS_ "WHILE", SI_ORDINARY, NULL, -1, OBJNULL}, {SYS_ "UNTIL", SI_ORDINARY, NULL, -1, OBJNULL}, diff --git a/src/c/symbols_list2.h b/src/c/symbols_list2.h index a0773b1a3..e8eb1e1cc 100644 --- a/src/c/symbols_list2.h +++ b/src/c/symbols_list2.h @@ -66,11 +66,6 @@ typedef struct { #else # define IF_SSE2(x) NULL #endif -#if defined(ECL_SEMAPHORE) && defined(ECL_THREADS) -# define IF_SEM(x) x -#else -# define IF_SEM(x) NULL -#endif #if defined(HAVE_LIBFFI) || defined(ECL_DYNAMIC_FFI) # define IF_DFFI(x) x #else @@ -1607,17 +1602,16 @@ cl_symbols[] = { {MP_ "GIVEUP-RWLOCK-WRITE",IF_MP("mp_giveup_rwlock_write")}, {MP_ "GLOBAL-LOCK",NULL}, {MP_ "ERROR-LOCK",NULL}, -/* #endif ECL_THREADS */ -/* #if defined(ECL_SEMAPHORES) && defined(ECL_THREADS) */ {MP_ "SEMAPHORE",NULL}, -{MP_ "MAKE-SEMAPHORE",IF_SEM("mp_make_semaphore")}, -{MP_ "SEMAPHORE-WAIT",IF_SEM("mp_semaphore_wait")}, -{MP_ "SEMAPHORE-TRYWAIT",IF_SEM("mp_semaphore_trywait")}, -{MP_ "SEMAPHORE-SIGNAL",IF_SEM("mp_semaphore_signal")}, -{MP_ "SEMAPHORE-CLOSE",IF_SEM("mp_semaphore_close")}, +{MP_ "MAKE-SEMAPHORE",IF_MP("mp_make_semaphore")}, +{MP_ "SIGNAL-SEMAPHORE",IF_MP("mp_signal_semaphore")}, +{MP_ "WAIT-ON-SEMAPHORE",IF_MP("mp_wait_on_semaphore")}, +{MP_ "SEMAPHORE-COUNT",IF_MP("mp_semaphore_count")}, +{MP_ "SEMAPHORE-NAME",IF_MP("mp_semaphore_name")}, +{MP_ "SEMAPHORE-WAIT-COUNT",IF_MP("mp_semaphore_wait_count")}, {KEY_ "COUNT",NULL}, -/* #endif defined(ECL_SEMAPHORES) && defined(ECL_THREADS) */ +/* #endif defined(ECL_THREADS) */ {SYS_ "WHILE",NULL}, {SYS_ "UNTIL",NULL}, diff --git a/src/c/threads/semaphore.d b/src/c/threads/semaphore.d index 59ea9d908..95b787d46 100644 --- a/src/c/threads/semaphore.d +++ b/src/c/threads/semaphore.d @@ -1,9 +1,9 @@ /* -*- mode: c; c-basic-offset: 8 -*- */ /* - semaphores.d -- POSIX semaphores + semaphore.d -- POSIX-like semaphores */ /* - Copyright (c) 2003, Juan Jose Garcia Ripoll. + Copyright (c) 2011, Juan Jose Garcia Ripoll. ECL is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -13,219 +13,115 @@ See file '../Copyright' for full details. */ -#ifndef __sun__ /* See unixinit.d for this */ -#define _XOPEN_SOURCE 600 /* For pthread mutex attributes */ -#endif -#include -#include -#include -#define ECL_INCLUDE_MATH_H +#define AO_ASSUME_WINDOWS98 /* We need this for CAS */ #include -#ifdef ECL_WINDOWS_THREADS -# include -#else -# include -#endif -#ifdef HAVE_GETTIMEOFDAY -# include -#endif #include -#include /*---------------------------------------------------------------------- - * SEMAPHORES + * LOCKS or MUTEX */ -#ifdef ECL_SEMAPHORES +#if !defined(AO_HAVE_fetch_and_add_full) +#error "Cannot implement semaphores without AO_fetch_and_add_full" +#endif -# ifdef ECL_MACH_SEMAPHORES -struct ecl_semaphore_inner { - task_t owner; - semaphore_t counter[1]; -}; -# endif +static ECL_INLINE void +FEerror_not_a_semaphore(cl_object semaphore) +{ + FEwrong_type_argument(@'mp::semaphore', semaphore); +} -@(defun mp::make-semaphore (max &key name ((:count count) MAKE_FIXNUM(0))) - cl_object output; - cl_index initial_count, max_count; +cl_object +ecl_make_semaphore(cl_object name, cl_fixnum count) +{ + cl_object output = ecl_alloc_object(t_semaphore); + output->semaphore.name = name; + output->semaphore.counter = count; + output->semaphore.queue_list = Cnil; + output->semaphore.queue_spinlock = Cnil; + return output; +} + +@(defun mp::make-semaphore (&key name (count MAKE_FIXNUM(0))) @ { - output = ecl_alloc_object(t_semaphore); - ecl_disable_interrupts_env(the_env); - output->semaphore.name = name; - output->semaphore.handle = NULL; - ecl_set_finalizer_unprotected(output, Ct); - if (ecl_unlikely(!ECL_FIXNUMP(max) || - ecl_fixnum_minusp(max) || - ecl_fixnum_greaterp(max, MAKE_FIXNUM(0xFFFF)))) { - FEwrong_type_nth_arg(@[mp::make-semaphore], 1, max, - ecl_make_integer_type(MAKE_FIXNUM(0), - MAKE_FIXNUM(0xFFFF))); - } - max_count = fix(max); - if (ecl_unlikely(!ECL_FIXNUMP(count) || - ((initial_count = fix(count)) < 0) || - initial_count > max_count)) { - FEwrong_type_key_arg(@[mp::make-semaphore], @[:count], count, - ecl_make_integer_type(MAKE_FIXNUM(0), - max)); - } -#ifdef ECL_WINDOWS_THREADS - { - HANDLE h = CreateSemaphore(NULL, - initial_count, - 0xFFFF, - NULL); - output->semaphore.handle = h; - ecl_enable_interrupts_env(the_env); - if (h == NULL) - FEwin32_error("Unable to create semaphore object.", 0); - } -#else -# ifdef HAVE_SEM_INIT - { - sem_t *h = ecl_alloc_atomic(sizeof(sem_t)); - int rc = sem_init(h, 0, initial_count); - if (!rc) - output->semaphore.handle = h; - ecl_enable_interrupts(); - if (rc) - FEerror("Unable to create semaphore object.", 0); - } -# endif /* HAVE_SEM_INIT */ -#endif /* ECL_WINDOWS_THREADS */ - @(return output) + @(return ecl_make_semaphore(name, fixnnint(count))) } @) cl_object -mp_semaphore_trywait(cl_object sem) +mp_semaphore_name(cl_object semaphore) { - cl_object output; - if (ecl_unlikely(typeof(sem) != t_semaphore)) { - FEwrong_type_only_arg(@[mp::semaphore-trywait], sem, @[mp::semaphore]); - } - AGAIN: -#ifdef ECL_WINDOWS_THREADS - { - HANDLE h = (HANDLE)(sem->semaphore.handle); - switch (WaitForSingleObject(h, 0)) { - case WAIT_OBJECT_0: - output = Ct; - break; - case WAIT_TIMEOUT: - output = Cnil; - break; - default: - FEwin32_error("Unable to wait on semaphore", 0); - output = Cnil; - } - } -#else -# ifdef HAVE_SEM_INIT - { - sem_t *h = (sem_t *)(sem->semaphore.handle); - int rc = sem_trywait(h); - if (sem_trywait(h)) { - if (errno != EAGAIN) { - FElibc_error("Unable to wait on semaphore", 0); - } - output = Cnil; - } else { - output = Ct; - } - } -# endif /* HAVE_SEM_INIT */ -#endif /* ECL_WINDOWS_THREADS */ - @(return output) -} - - -cl_object -mp_semaphore_wait(cl_object sem) -{ - cl_object output; - if (ecl_unlikely(typeof(sem) != t_semaphore)) { - FEwrong_type_only_arg(@[mp::semaphore-wait], sem, @[mp::semaphore]); - } - AGAIN: -#ifdef ECL_WINDOWS_THREADS - { - HANDLE h = (HANDLE)(sem->semaphore.handle); - if (WaitForSingleObject(h, INFINITE) != WAIT_OBJECT_0) { - FEwin32_error("Unable to wait on semaphore", 0); - } - } -#else -# ifdef HAVE_SEM_INIT - { - sem_t *h = (sem_t *)(sem->semaphore.handle); - int rc = sem_wait(h); - if (sem_wait(h)) { - if (errno == EINTR) { - ecl_check_pending_interrupts(); - goto AGAIN; - } - FElibc_error("Unable to wait on semaphore", 0); - } - } -# endif /* HAVE_SEM_INIT */ -#endif /* ECL_WINDOWS_THREADS */ - @(return Ct) + cl_env_ptr env = ecl_process_env(); + unlikely_if (type_of(semaphore) != t_semaphore) { + FEerror_not_a_semaphore(semaphore); + } + ecl_return1(env, semaphore->semaphore.name); } cl_object -mp_semaphore_signal(cl_object sem) +mp_semaphore_count(cl_object semaphore) { - if (ecl_unlikely(typeof(sem) != t_semaphore)) { - FEwrong_type_only_arg(@[mp::semaphore-signal], sem, @[mp::semaphore]); - } - AGAIN: -#ifdef ECL_WINDOWS_THREADS - { - HANDLE h = (HANDLE)(sem->semaphore.handle); - if (!ReleaseSemaphore(h, 1, NULL)) { - FEwin32_error("Unable to post on semaphore ~A" 1, sem); - } - } -#else -# ifdef HAVE_SEM_INIT - { - sem_t *h = (sem_t *)(sem->semaphore.handle); - int rc = sem_wait(h); - if (sem_wait(h)) { - if (errno == EINTR) { - ecl_check_pending_interrupts(); - goto AGAIN; - } - FElibc_error("Unable to post on semaphore ~A", 1, sem); - } - } -# endif /* HAVE_SEM_INIT */ -#endif /* ECL_WINDOWS_THREADS */ - @(return Ct) + cl_env_ptr env = ecl_process_env(); + unlikely_if (type_of(semaphore) != t_semaphore) { + FEerror_not_a_semaphore(semaphore); + } + ecl_return1(env, MAKE_FIXNUM(semaphore->semaphore.counter)); } cl_object -mp_semaphore_close(cl_object sem) +mp_semaphore_wait_count(cl_object semaphore) { - if (ecl_unlikely(typeof(sem) != t_semaphore)) { - FEwrong_type_only_arg(@[mp::semaphore-close], sem, @[mp::semaphore]); - } -#ifdef ECL_WINDOWS_THREADS - { - HANDLE h = (HANDLE)(sem->semaphore.handle); - if (h) CloseHandle(h); - } -#else -# ifdef HAVE_SEM_INIT - /* - * No need for closing. - */ -# endif /* HAVE_SEM_INIT */ -#endif /* ECL_WINDOWS_THREADS */ - @(return Ct) + cl_env_ptr env = ecl_process_env(); + unlikely_if (type_of(semaphore) != t_semaphore) { + FEerror_not_a_semaphore(semaphore); + } + ecl_return1(env, cl_length(semaphore->semaphore.queue_list)); } -#endif /* ECL_SEMAPHORES */ +@(defun mp::signal-semaphore (semaphore &optional (count MAKE_FIXNUM(1))) +@ +{ + cl_fixnum n = fixnnint(count); + cl_env_ptr env = ecl_process_env(); + cl_object own_process = env->own_process; + unlikely_if (type_of(semaphore) != t_semaphore) { + FEerror_not_a_semaphore(semaphore); + } + AO_fetch_and_add((AO_t*)&semaphore->semaphore.counter, 1); + while (n-- && semaphore->semaphore.queue_list != Cnil) { + ecl_wakeup_waiters(env, semaphore, ECL_WAKEUP_ONE); + } + @(return) +} +@) +static cl_object +get_semaphore_inner(cl_env_ptr env, cl_object semaphore) +{ + cl_fixnum counter; + cl_object output; + ecl_disable_interrupts_env(env); + if ((counter = semaphore->semaphore.counter) && + AO_compare_and_swap_full((AO_t*)&(semaphore->semaphore.counter), + (AO_t)counter, (AO_t)(counter-1))) { + output = Ct; + } else { + output = Cnil; + } + ecl_enable_interrupts_env(env); + return output; +} + +cl_object +mp_wait_on_semaphore(cl_object semaphore) +{ + cl_env_ptr env = ecl_process_env(); + unlikely_if (type_of(semaphore) != t_semaphore) { + FEerror_not_a_semaphore(semaphore); + } + if (get_semaphore_inner(env, semaphore) == Cnil) { + ecl_wait_on(env, get_semaphore_inner, semaphore); + } + @(return Ct) +} diff --git a/src/configure b/src/configure index 77f73590c..0351f2398 100755 --- a/src/configure +++ b/src/configure @@ -4524,7 +4524,7 @@ THREAD_CFLAGS='' THREAD_LIBS='' THREAD_GC_FLAGS='--enable-threads=posix' INSTALL_TARGET='install' -THREAD_OBJ="$THREAD_OBJ threads/process threads/queue threads/mutex threads/condition_variable" +THREAD_OBJ="$THREAD_OBJ threads/process threads/queue threads/mutex threads/condition_variable threads/semaphore" clibs='' SONAME='' SONAME_LDFLAGS='' @@ -5938,81 +5938,6 @@ echo "$as_me: error: Threads aren't supported on this system." >&2;} LIBS="${THREAD_LIBS} ${LIBS}" CFLAGS="${CFLAGS} ${THREAD_CFLAGS}" -{ echo "$as_me:$LINENO: checking working sem_init()" >&5 -echo $ECHO_N "checking working sem_init()... $ECHO_C" >&6; } -if test -z "$ECL_WORKING_SEM_INIT"; then - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run test program while cross compiling -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -int main() { - sem_t aux; - if (sem_init(&aux, 0, 0)) - exit(1); - exit(0); -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ECL_WORKING_SEM_INIT=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ECL_WORKING_SEM_INIT=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -{ echo "$as_me:$LINENO: result: $ECL_WORKING_SEM_INIT" >&5 -echo "${ECHO_T}$ECL_WORKING_SEM_INIT" >&6; } -if test $ECL_WORKING_SEM_INIT = yes ; then - cat >>confdefs.h <<\_ACEOF -#define ECL_SEMAPHORES 1 -_ACEOF - - cat >>confdefs.h <<\_ACEOF -#define HAVE_SEM_INIT 1 -_ACEOF - - THREAD_OBJ="$THREAD_OBJ threads/semaphore" - echo $THREAD_OBJ -fi - - { echo "$as_me:$LINENO: checking for pthread_rwlock_init" >&5 echo $ECHO_N "checking for pthread_rwlock_init... $ECHO_C" >&6; } if test "${ac_cv_func_pthread_rwlock_init+set}" = set; then @@ -15758,7 +15683,7 @@ do cat >>$CONFIG_STATUS <<_ACEOF # First, check the format of the line: cat >"\$tmp/defines.sed" <<\\CEOF -/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*/b def /^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def b :def diff --git a/src/configure.in b/src/configure.in index 3de7cbc36..6c74c33c9 100644 --- a/src/configure.in +++ b/src/configure.in @@ -502,7 +502,6 @@ if test "${enable_threads}" = "yes" ; then else LIBS="${THREAD_LIBS} ${LIBS}" CFLAGS="${CFLAGS} ${THREAD_CFLAGS}" - ECL_POSIX_SEMAPHORES ECL_POSIX_RWLOCK boehm_configure_flags="${boehm_configure_flags} ${THREAD_GC_FLAGS}" for k in $THREAD_OBJ; do EXTRA_OBJS="$EXTRA_OBJS ${k}.${OBJEXT}"; done diff --git a/src/h/config.h.in b/src/h/config.h.in index f0571e593..15f167e9b 100644 --- a/src/h/config.h.in +++ b/src/h/config.h.in @@ -396,8 +396,6 @@ typedef unsigned char ecl_base_char; #undef HAVE_COPYSIGNL /* whether we have sched_yield() that gives priority to other threads */ #undef HAVE_SCHED_YIELD -/* whether we semaphore.h */ -#undef HAVE_SEMAPHORE_H /* whether we have a working sem_init() */ #undef HAVE_SEM_INIT /* whether we have read/write locks */ diff --git a/src/h/external.h b/src/h/external.h index 11d52ddd1..babc02294 100755 --- a/src/h/external.h +++ b/src/h/external.h @@ -1724,26 +1724,26 @@ extern ECL_API cl_object mp_restore_signals(cl_object sigmask); extern ECL_API bool ecl_import_current_thread(cl_object process_name, cl_object process_binding); extern ECL_API void ecl_release_current_thread(void); -# ifdef ECL_SEMAPHORES -extern ECL_API void mp_make_semaphore _ARGS((cl_narg, cl_object, ...)); -extern ECL_API void mp_semaphore_trywait(cl_object); -extern ECL_API void mp_semaphore_wait(cl_object); -extern ECL_API void mp_semaphore_signal(cl_object); -extern ECL_API void mp_semaphore_close(cl_object); -# endif + +/* threads/semaphore.d */ + +extern ECL_API cl_object mp_make_semaphore _ARGS((cl_narg, ...)); +extern ECL_API cl_object mp_semaphore_count(cl_object); +extern ECL_API cl_object mp_semaphore_name(cl_object); +extern ECL_API cl_object mp_semaphore_wait_count(cl_object); +extern ECL_API cl_object mp_wait_on_semaphore(cl_object); +extern ECL_API cl_object mp_signal_semaphore _ARGS((cl_narg, cl_object, ...)); +extern ECL_API cl_object ecl_make_semaphore(cl_object name, cl_fixnum count); /* threads/atomic.c */ -#ifdef ECL_THREADS extern ECL_API cl_object ecl_atomic_get(cl_object *slot); 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); @@ -1755,7 +1755,6 @@ 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 */ diff --git a/src/h/object.h b/src/h/object.h index 5cb2f956d..c2bae1b5d 100644 --- a/src/h/object.h +++ b/src/h/object.h @@ -81,9 +81,7 @@ typedef enum { t_lock, t_rwlock, t_condition_variable, -# ifdef ECL_SEMAPHORES t_semaphore, -# endif #endif t_codeblock, t_foreign, @@ -909,6 +907,14 @@ struct ecl_queue { cl_object spinlock; }; +struct ecl_semaphore { + HEADER; + cl_object queue_list; + cl_object queue_spinlock; + cl_object name; + cl_fixnum counter; +}; + struct ecl_lock { HEADER1(recursive); cl_object queue_list; @@ -934,11 +940,6 @@ struct ecl_condition_variable { cl_object queue_spinlock; cl_object lock; }; - -struct ecl_semaphore { - HEADER; - void *handle; -}; #endif /* ECL_THREADS */ #ifdef CLOS @@ -1046,9 +1047,7 @@ union cl_lispunion { struct ecl_rwlock rwlock; /* read/write lock */ struct ecl_condition_variable condition_variable; /* condition-variable */ #endif -#ifdef ECL_SEMAPHORES struct ecl_semaphore semaphore; /* semaphore */ -#endif struct ecl_codeblock cblock; /* codeblock */ struct ecl_foreign foreign; /* user defined data type */ struct ecl_stack_frame frame; /* stack frame */