try to fix Linux build problems related to pthreads
svn: r18776
This commit is contained in:
parent
8242847c7a
commit
0b2a43f193
62
src/configure
vendored
62
src/configure
vendored
|
@ -2258,6 +2258,7 @@ show_explicitly_disabled "${enable_foreign}" Foreign
|
|||
|
||||
show_explicitly_enabled "${enable_places}" Places
|
||||
show_explicitly_enabled "${enable_futures}" Futures
|
||||
show_explicitly_disabled "${enable_futures}" Futures
|
||||
|
||||
show_explicitly_enabled "${enable_sgc}" SGC
|
||||
show_explicitly_enabled "${enable_sgcdebug}" "SGC debug mode"
|
||||
|
@ -10760,6 +10761,67 @@ cat >>confdefs.h <<\_ACEOF
|
|||
#define USE_PTHREAD_INSTEAD_OF_ITIMER 1
|
||||
_ACEOF
|
||||
|
||||
|
||||
msg="whether pthread_rwlock is available"
|
||||
{ echo "$as_me:$LINENO: checking $msg" >&5
|
||||
echo $ECHO_N "checking $msg... $ECHO_C" >&6; }
|
||||
if test "$cross_compiling" = yes; then
|
||||
rwlockavail=no
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
#include <pthread.h>
|
||||
pthread_rwlock_t l;
|
||||
int main() {
|
||||
return pthread_rwlock_init(&l, NULL);
|
||||
}
|
||||
_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
|
||||
rwlockavail=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 )
|
||||
rwlockavail=no
|
||||
fi
|
||||
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
|
||||
|
||||
{ echo "$as_me:$LINENO: result: $rwlockavail" >&5
|
||||
echo "${ECHO_T}$rwlockavail" >&6; }
|
||||
if test "$rwlockavail" = "yes" ; then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_PTHREAD_RWLOCK 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
################ Xrender ##################
|
||||
|
|
|
@ -296,6 +296,7 @@ show_explicitly_disabled "${enable_foreign}" Foreign
|
|||
|
||||
show_explicitly_enabled "${enable_places}" Places
|
||||
show_explicitly_enabled "${enable_futures}" Futures
|
||||
show_explicitly_disabled "${enable_futures}" Futures
|
||||
|
||||
show_explicitly_enabled "${enable_sgc}" SGC
|
||||
show_explicitly_enabled "${enable_sgcdebug}" "SGC debug mode"
|
||||
|
@ -1178,6 +1179,19 @@ if test "${enable_pthread}" = "yes" ; then
|
|||
PREFLAGS="$PREFLAGS -pthread"
|
||||
LDFLAGS="$LDFLAGS -pthread"
|
||||
AC_DEFINE(USE_PTHREAD_INSTEAD_OF_ITIMER, 1, [Pthread timer enabled])
|
||||
|
||||
[ msg="whether pthread_rwlock is available" ]
|
||||
AC_MSG_CHECKING($msg)
|
||||
AC_TRY_RUN(
|
||||
[ #include <pthread.h>]
|
||||
pthread_rwlock_t l;
|
||||
int main() {
|
||||
return pthread_rwlock_init(&l, NULL);
|
||||
}, rwlockavail=yes, rwlockavail=no, rwlockavail=no)
|
||||
AC_MSG_RESULT($rwlockavail)
|
||||
if test "$rwlockavail" = "yes" ; then
|
||||
AC_DEFINE(HAVE_PTHREAD_RWLOCK,1,[Have pthread_rwlock])
|
||||
fi
|
||||
fi
|
||||
|
||||
################ Xrender ##################
|
||||
|
|
|
@ -30,7 +30,7 @@ extern "C" {
|
|||
# if _MSC_VER
|
||||
# define THREAD_LOCAL /* empty */
|
||||
# define IMPLEMENT_THREAD_LOCAL_VIA_WIN_TLS
|
||||
# elif defined(OS_X) || (defined(linux) && defined(MZ_USES_SHARED_LIB))
|
||||
# elif defined(OS_X)
|
||||
# define IMPLEMENT_THREAD_LOCAL_VIA_PTHREADS
|
||||
# if defined(__x86_64__) || defined(__i386__)
|
||||
# define INLINE_GETSPECIFIC_ASSEMBLY_CODE
|
||||
|
@ -306,7 +306,7 @@ static inline Thread_Local_Variables *scheme_get_thread_local_variables() {
|
|||
# else
|
||||
asm volatile("movl %%gs:0x48(,%1,4), %0" : "=r"(x) : "r"(scheme_thread_local_key));
|
||||
# endif
|
||||
# elif defined(linux) && defined(MZ_USES_SHARED_LIB)
|
||||
# elif defined(linux)
|
||||
# if defined(__x86_64__)
|
||||
asm volatile( "mov %1, %%eax;"
|
||||
"shl $0x4, %%rax;"
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
/* Whether __attribute__ ((noinline)) works */
|
||||
#undef MZ_USE_NOINLINE
|
||||
|
||||
/* Whether pthread_rwlock is availabale: */
|
||||
#undef HAVE_PTHREAD_RWLOCK
|
||||
|
||||
/* Enable futures and/or places: */
|
||||
#undef MZ_USE_FUTURES
|
||||
#undef MZ_USE_PLACES
|
||||
|
|
|
@ -290,6 +290,8 @@ void mz_proc_thread_exit(void *rc) {
|
|||
|
||||
#ifndef WIN32
|
||||
|
||||
# ifdef HAVE_PTHREAD_RWLOCK
|
||||
|
||||
struct mzrt_rwlock {
|
||||
pthread_rwlock_t lock;
|
||||
};
|
||||
|
@ -322,6 +324,142 @@ int mzrt_rwlock_destroy(mzrt_rwlock *lock) {
|
|||
return pthread_rwlock_destroy(&lock->lock);
|
||||
}
|
||||
|
||||
# else
|
||||
|
||||
struct mzrt_rwlock {
|
||||
pthread_mutex_t m;
|
||||
pthread_cond_t cr, cw;
|
||||
int readers, writers, write_waiting;
|
||||
};
|
||||
|
||||
static mzrt_rwlock *locks[2];
|
||||
|
||||
static void *go(void *id)
|
||||
{
|
||||
int i = *(int *)id, j, amt;
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
amt = (random() % 400) + 100;
|
||||
usleep(amt - 100);
|
||||
if (!(i % 3)) {
|
||||
mzrt_rwlock_wrlock(locks[0]);
|
||||
printf("writing %d\n", i);
|
||||
usleep(amt);
|
||||
mzrt_rwlock_unlock(locks[0]);
|
||||
} else {
|
||||
mzrt_rwlock_rdlock(locks[0]);
|
||||
printf("reading %d\n", i);
|
||||
usleep(amt);
|
||||
mzrt_rwlock_unlock(locks[0]);
|
||||
}
|
||||
printf("done %d\n", i);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int mzrt_rwlock_create(mzrt_rwlock **lock) {
|
||||
int err;
|
||||
|
||||
*lock = malloc(sizeof(mzrt_rwlock));
|
||||
err = pthread_mutex_init(&(*lock)->m, NULL);
|
||||
if (err) { free(*lock); return err; }
|
||||
err = pthread_cond_init(&(*lock)->cr, NULL);
|
||||
if (err) { free(*lock); return err; }
|
||||
err = pthread_cond_init(&(*lock)->cw, NULL);
|
||||
if (err) { free(*lock); return err; }
|
||||
return err;
|
||||
}
|
||||
|
||||
static int rwlock_rdlock(mzrt_rwlock *lock, int just_try) {
|
||||
int err;
|
||||
|
||||
err = pthread_mutex_lock(&lock->m);
|
||||
if (err) return err;
|
||||
while (lock->writers || lock->write_waiting) {
|
||||
if (just_try) {
|
||||
err = pthread_mutex_unlock(&lock->m);
|
||||
if (err) return err;
|
||||
return EBUSY;
|
||||
} else {
|
||||
err = pthread_cond_wait(&lock->cr, &lock->m);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
lock->readers++;
|
||||
return pthread_mutex_unlock(&lock->m);
|
||||
}
|
||||
|
||||
int mzrt_rwlock_rdlock(mzrt_rwlock *lock) {
|
||||
return rwlock_rdlock(lock, 0);
|
||||
}
|
||||
|
||||
static int rwlock_wrlock(mzrt_rwlock *lock, int just_try) {
|
||||
int err;
|
||||
|
||||
err = pthread_mutex_lock(&lock->m);
|
||||
if (err) return err;
|
||||
while (lock->writers || lock->readers) {
|
||||
if (just_try) {
|
||||
err = pthread_mutex_unlock(&lock->m);
|
||||
if (err) return err;
|
||||
return EBUSY;
|
||||
} else {
|
||||
lock->write_waiting++;
|
||||
err = pthread_cond_wait(&lock->cw, &lock->m);
|
||||
--lock->write_waiting;
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
lock->writers++;
|
||||
return pthread_mutex_unlock(&lock->m);
|
||||
}
|
||||
|
||||
int mzrt_rwlock_wrlock(mzrt_rwlock *lock) {
|
||||
return rwlock_wrlock(lock, 0);
|
||||
}
|
||||
|
||||
int mzrt_rwlock_tryrdlock(mzrt_rwlock *lock) {
|
||||
return rwlock_rdlock(lock, 1);
|
||||
}
|
||||
|
||||
int mzrt_rwlock_trywrlock(mzrt_rwlock *lock) {
|
||||
return rwlock_wrlock(lock, 1);
|
||||
}
|
||||
|
||||
int mzrt_rwlock_unlock(mzrt_rwlock *lock) {
|
||||
int err;
|
||||
|
||||
err = pthread_mutex_lock(&lock->m);
|
||||
if (err) return err;
|
||||
|
||||
if (lock->readers)
|
||||
--lock->readers; /* must have been a read lock */
|
||||
else
|
||||
--lock->writers;
|
||||
|
||||
if (lock->write_waiting)
|
||||
err = pthread_cond_signal(&lock->cw);
|
||||
else
|
||||
err = pthread_cond_broadcast(&lock->cr);
|
||||
if (err) return err;
|
||||
|
||||
return pthread_mutex_unlock(&lock->m);
|
||||
}
|
||||
|
||||
int mzrt_rwlock_destroy(mzrt_rwlock *lock) {
|
||||
pthread_mutex_destroy(&lock->m);
|
||||
pthread_cond_destroy(&lock->cr);
|
||||
pthread_cond_destroy(&lock->cw);
|
||||
free(lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
struct mzrt_mutex {
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user