Implemented semaphores using atomic operations

This commit is contained in:
Juanjo Garcia-Ripoll 2012-04-02 17:12:50 +02:00
parent e607b5c7f8
commit 0fecb887e0
9 changed files with 123 additions and 342 deletions

25
src/aclocal.m4 vendored
View file

@ -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 <semaphore.h>
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],[

View file

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

View file

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

View file

@ -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 <errno.h>
#include <time.h>
#include <signal.h>
#define ECL_INCLUDE_MATH_H
#define AO_ASSUME_WINDOWS98 /* We need this for CAS */
#include <ecl/ecl.h>
#ifdef ECL_WINDOWS_THREADS
# include <windows.h>
#else
# include <pthread.h>
#endif
#ifdef HAVE_GETTIMEOFDAY
# include <sys/time.h>
#endif
#include <ecl/internal.h>
#include <ecl/ecl-inl.h>
/*----------------------------------------------------------------------
* 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)
}

79
src/configure vendored
View file

@ -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 <semaphore.h>
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

View file

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

View file

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

View file

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

View file

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