diff options
Diffstat (limited to 'm4/ost_pthread.m4')
-rw-r--r-- | m4/ost_pthread.m4 | 582 |
1 files changed, 582 insertions, 0 deletions
diff --git a/m4/ost_pthread.m4 b/m4/ost_pthread.m4 new file mode 100644 index 00000000..d427c735 --- /dev/null +++ b/m4/ost_pthread.m4 @@ -0,0 +1,582 @@ +dnl Copyright (C) 1999-2001 Open Source Telecom Corporation. +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a configuration +dnl script generated by Autoconf, you may include it under the same +dnl distribution terms that you use for the rest of that program. + +AC_DEFUN([OST_LIB_PTHREAD], +[ + AC_REQUIRE([OST_SYS_POSIX]) + AC_REQUIRE([OST_CC_SYSTIME]) + THREAD_FLAGS="" + THREAD_LIBS="" + ost_cv_thread_library="none" + ost_cv_rt_library="none" + ost_cv_cxx_mode=false + + AC_ARG_WITH(pthread, [ --with-pthread[=lib] using specified pthread library], + [if test "$withval" != "" ; then ost_cv_thread_library=$withval ; fi] + ) + + AC_ARG_WITH(linuxthreads, [ --with-linuxthreads use linux kernel mode library], + [ost_cv_thread_library=lthread + AC_DEFINE(WITH_LINUXTHREADS, [1], [bsd system using linuxthreads]) + if test "$withval" != "yes" ; then + THREAD_FLAGS="-D__USE_GNU -D__USE_UNIX98 -I$withval $THREAD_FLAGS" + CFLAGS="-D__USE_GNU -D__USE_UNIX98 -I$withval $CFLAGS" + else + THREAD_FLAGS="-D__USE_GNU -D__USE_UNIX98 -I/usr/local/include/pthread/linuxthreads $THREAD_FLAGS" + CFLAGS="-D__USE_GNU -D__USE_UNIX98 -I/usr/local/include/pthread/linuxthreads $CFLAGS" + fi + ]) + + AC_CHECK_HEADERS(pthread.h, [ + AC_DEFINE(HAVE_PTHREAD_H, [1], [posix thread header]) + ost_cv_posix_threads=yes], + ost_cv_posix_threads=no) + + if test $ost_cv_posix_threads = no ; then + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + SAVE_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -pthread" + AC_TRY_COMPILE([#include <pthread.h>],[], + AC_DEFINE(HAVE_PTHREAD_H, [1]) + ost_cv_cxx_mode=true + ost_cv_posix_threads=yes) + CXXFLAGS="$SAVE_CXXFLAGS" + AC_LANG_RESTORE + fi + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + + ost_cv_posix_atomic=no + AC_CHECK_HEADERS(sys/atomic_op.h,[ + AC_DEFINE(HAVE_ATOMIC_AIX, [1], [atomic aix operations]) + ]) + AC_CHECK_HEADERS([sys/atomic.h], + ost_cv_posix_sys_atomic=yes, + ost_cv_posix_sys_atomic=no) + if test $ost_cv_posix_sys_atomic = yes ; then + AC_MSG_CHECKING([for atomic_t]) + AC_TRY_COMPILE([#include <sys/atomic.h>], + [ + atomic_t at; at.counter = 1; + atomic_dec_and_test(&at); + atomic_sub(4, &at); + atomic_inc(&at); + atomic_add(3, &at); + ], + [ost_cv_posix_atomic=yes + AC_DEFINE(HAVE_WORKING_SYS_ATOMIC_H, [1], [has usable atomic functions])], + [ost_cv_posix_atomic=no]) + AC_MSG_RESULT($ost_cv_posix_atomic) + fi + + dnl check for gcc's bits/atomicity and the atomic functions therein + AC_CHECK_HEADERS([bits/atomicity.h], + ost_cv_bits_atomicity=yes, + ost_cv_bits_atomicity=no) + if test $ost_cv_bits_atomicity = yes ; then + AC_MSG_CHECKING([for _Atomic_word]) + AC_TRY_COMPILE([#include <bits/atomicity.h>], + [ + _Atomic_word i = 0; + __atomic_add(&i, 1); + __exchange_and_add(&i, 1); + ], + [ost_cv_gcc_atomic=yes + AC_DEFINE(HAVE_GCC_BITS_ATOMIC, [1], [has gcc atomic functions])], + [ost_cv_gcc_atomic=no]) + AC_MSG_RESULT($ost_cv_gcc_atomic) + + AC_MSG_CHECKING([for __gnu_cxx::_Atomic_word]) + AC_TRY_COMPILE([#include <bits/atomicity.h>], + [ + using namespace __gnu_cxx; + _Atomic_word i = 0; + __atomic_add(&i, 1); + __exchange_and_add(&i, 1); + ], + [ost_cv_gcc_cxx_atomic=yes + AC_DEFINE(HAVE_GCC_CXX_BITS_ATOMIC, [1], + [has __gnu_cxx atomic functions])], + [ost_cv_gcc_cxx_atomic=no]) + AC_MSG_RESULT($ost_cv_gcc_cxx_atomic) + fi + +AC_LANG_RESTORE + + if test "$target" = NONE ; then + targetdir="" + else + targetdir="$target" + fi + + AC_CHECK_HEADERS(thread.h) + if test "$prefix" = NONE ; then + thrprefix="/usr/$targetdir/include" + if test -d /usr/$targetdir/sys-include ; then + thrprefix="$prefix/$targetdir/sys-include" ; fi + else + thrprefix="$prefix/$targetdir/include" + if test -d "$prefix/$targetdir/sys-include" ; then + thrprefix="$prefix/$targetdir/sys-include" ; fi + fi + + if test ! -f $thrprefix/thread.h ; then + thrprefix=/usr/include + fi + + AC_SUBST(thrprefix) + + if test $ost_cv_posix_threads = yes ; then + if test "$ost_cv_thread_library" = "none" ; then + + ost_cv_thread_flags="" + for flags in -kthread -pthread -mthreads -pthreads -Kthread --threadsafe -mt ; do + + AC_MSG_CHECKING(whether ${CC-cc} accepts $flags) + echo 'void f(){}' >conftest.c + if test -z "`${CC-cc} $flags -c conftest.c 2>&1`"; then + ost_cv_thread_flags=$flags + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + rm -f conftest* + if test ! -z "$ost_cv_thread_flags" ; then break ; fi + done +# if test "$ost_cv_prog_cc_pthread" = "no" ; then +# AC_CACHE_CHECK(whether ${CC-cc} accepts -mthreads, +# ost_cv_prog_cc_mthreads, +# [echo 'void f(){}' >conftest.c +# if test -z "`${CC-cc} -mthreads -c conftest.c 2>&1`"; then +# ost_cv_prog_cc_mthreads=yes +# else +# ost_cv_prog_cc_mthreads=no +# fi +# rm -f conftest* +# ]) +# fi + ost_cv_thread_library=none + AC_CHECK_LIB(pthread, pthread_self, + ost_cv_thread_library=pthread, + AC_CHECK_LIB(c_r, pthread_self, + ost_cv_thread_library=c_r, + AC_CHECK_LIB(pthread, pthread_kill, + ost_cv_thread_library=pthread, + AC_CHECK_LIB(pthreads, pthread_self, + ost_cv_thread_library=pthreads, + AC_CHECK_LIB(thread, pthread_self, + ost_cv_thread_library=thread))))) + + if test $ost_cv_thread_library = none ; then + AC_CHECK_LIB(gthreads, pthread_self,[ + AC_CHECK_LIB(malloc, malloc) + ost_cv_thread_library=gthreads]) + fi + if test $ost_cv_thread_library = none ; then + AC_CHECK_LIB(cma, pthread_self, + ost_cv_thread_library=cma) + fi + + if test $ost_cv_thread_library = none ; then + AC_CHECK_LIB(c, pthread_self, + ost_cv_thread_library=c) + fi + + if test $ost_cv_thread_library = none ; then + AC_MSG_ERROR(no library for posix threads found!) + fi + else +# ost_cv_prog_cc_pthread=no +# ost_cv_prog_cc_mthreads=no + ost_cv_thread_flags="" + fi + + AC_CHECK_LIB(${ost_cv_thread_library}, pthread_mach_thread_np, + AC_DEFINE(HAVE_PTHREAD_MACH_THREAD_NP, [1], [has mach link]) + ) + + AC_CHECK_LIB(${ost_cv_thread_library}, nanosleep, + AC_DEFINE(HAVE_PTHREAD_NANOSLEEP, [1], [has nanosleep]),[ + AC_CHECK_LIB(posix4, nanosleep,[ + AC_DEFINE(HAVE_PTHREAD_NANOSLEEP, [1]) + THREAD_LIBS="$THREAD_LIBS -lposix4" + ],[ + AC_CHECK_LIB(rt, nanosleep,[ + AC_DEFINE(HAVE_PTHREAD_NANOSLEEP, [1]) + ost_cv_rt_library="-lrt"]) + ]) + + ]) + + AC_CHECK_LIB(rt, clock_gettime,[ + ost_cv_rt_library="-lrt" + AC_DEFINE(HAVE_HIRES_TIMER, [1], [have hires]) + ],[ + AC_CHECK_FUNCS(clock_gettime,[ + AC_DEFINE(HAVE_HIRES_TIMER, [1], [have hires]) + ]) + ]) + + AC_CHECK_LIB(rt, mlockall,[ + AC_DEFINE(HAVE_MLOCK, [1], [have mlock]) + AC_DEFINE(HAVE_MLOCKALL, [1], [have memlockall]) + ost_cv_rt_library="-lrt"], + [ + AC_CHECK_FUNCS(mlock) + AC_CHECK_FUNCS(mlockall) + ]) + + if test "$ost_cv_rt_library" != "none" ; then + THREAD_LIBS="$THREAD_LIBS $ost_cv_rt_library" ; fi + + if test ! -z "$ost_cv_thread_flags" ; then + THREAD_LIBS="$THREAD_LIBS $ost_cv_thread_flags" + else + THREAD_LIBS="$THREAD_LIBS -l$ost_cv_thread_library" + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd*) flag="-D_THREAD_SAFE";; + *solaris* | alpha*-osf*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + THREAD_FLAGS="$flag" + fi + + AC_SUBST(THREAD_FLAGS) + AC_SUBST(THREAD_LIBS) +# LIBS="$THREAD_LIBS $LIBS" + if test "$ost_cv_thread_library" != "lthread" ; then + AC_CHECK_HEADERS(pthread_np.h) + fi + AC_CHECK_HEADERS(semaphore.h) + AC_CHECK_HEADERS(sched.h) + AC_CHECK_HEADERS(sys/sched.h) + AC_CHECK_FUNCS(sched_getscheduler) + AC_CACHE_CHECK([for recursive mutex type support], ost_cv_mutex_recursive, + [ + ost_cv_mutex_recursive="none" + + if test "$ost_cv_cxx_mode" = true ; then + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + SAVE_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -pthread" + fi + + AC_TRY_COMPILE( + [#include <pthread.h>], + [ + #ifndef PTHREAD_MUTEXTYPE_RECURSIVE + #ifdef PTHREAD_MUTEX_RECURSIVE + #define PTHREAD_MUTEXTYPE_RECURSIVE PTHREAD_MUTEX_RECURSIVE + #endif + #endif + return (int)PTHREAD_MUTEXTYPE_RECURSIVE; + ], + ost_cv_mutex_recursive="portable", + [ + AC_EGREP_HEADER(PTHREAD_MUTEXTYPE_RECURSIVE_NP,pthread.h, + ost_cv_mutex_recursive=non-portable) + AC_EGREP_HEADER(PTHREAD_MUTEX_RECURSIVE_INITIALIZER_NP, pthread.h, + ost_cv_mutex_recursive=lthread) + AC_EGREP_HEADER(PTHREAD_MUTEX_RECURSIVE_NP,pthread.h, + ost_cv_mutex_recursive=linux) + AC_EGREP_HEADER(MUTEX_TYPE_COUNTING_FAST,pthread.h, + ost_cv_mutex_recursive=counting) + ]) + if test $ost_cv_mutex_recursive = "none" ; then + if test $ost_cv_thread_library = "lthread" ; then + ost_cv_mutex_recursive=linux + fi + fi + rm -f conftest* + ]) + + if test $ost_cv_mutex_recursive = "none" ; then + AC_TRY_COMPILE( + [#include <pthread.h>], + [return MUTEX_TYPE_COUNTING_FAST;], + ost_cv_mutex_recursive=counting) + fi + + if test "$ost_cv_cxx_mode" = true ; then + CXXFLAGS="$SAVE_CXXFLAGS" + AC_LANG_RESTORE + fi + + + case $ost_cv_mutex_recursive in + non-portable) + AC_DEFINE(PTHREAD_MUTEXTYPE_RECURSIVE, + PTHREAD_MUTEXTYPE_RECURSIVE_NP, [mutex type]) + ;; + linux) + AC_DEFINE(PTHREAD_MUTEXTYPE_RECURSIVE, + PTHREAD_MUTEX_RECURSIVE_NP) + ;; + counting) + AC_DEFINE(PTHREAD_MUTEXTYPE_RECURSIVE, + MUTEX_TYPE_COUNTING_FAST) + ;; + esac + + AC_CHECK_LIB(${ost_cv_thread_library}, pthread_mutexattr_settype, + AC_DEFINE(HAVE_PTHREAD_MUTEXATTR_SETTYPE, [1], [has setttype]), + [ + AC_CHECK_LIB(${ost_cv_thread_library}, pthread_mutexattr_settype_np, + AC_DEFINE(HAVE_PTHREAD_MUTEXATTR_SETTYPE_NP, + [1], [has non portable settype])) + AC_CHECK_LIB(${ost_cv_thread_library}, pthread_mutexattr_setkind_np, + AC_DEFINE(HAVE_PTHREAD_MUTEXATTR_SETKIND_NP, + [1], [has non portable setkind])) + ] + ) + + ost_cv_thread_rwlock=false + AC_CHECK_LIB(${ost_cv_thread_library}, pthread_rwlock_init,[ + ost_cv_thread_rwlock=true + AC_DEFINE(HAVE_PTHREAD_RWLOCK, [1], [has rwlock support])]) + + AC_CHECK_LIB(c, pread,[ + AC_DEFINE(HAVE_PREAD_PWRITE, [1], [has pwrite])],[ + AC_CHECK_LIB(${ost_cv_thread_library}, pread,[ + AC_DEFINE(HAVE_PREAD_PWRITE, [1])],[ + AC_CHECK_LIB(c_r, pread,[AC_DEFINE(HAVE_PREAD_PWRITE)]) + ]) + ]) + + AC_CHECK_LIB(${ost_cv_thread_library}, pthread_suspend, + AC_DEFINE(HAVE_PTHREAD_SUSPEND, [1], [has suspend])) + + AC_CHECK_LIB(${ost_cv_thread_library}, pthread_attr_setstacksize, + AC_DEFINE(HAVE_PTHREAD_ATTR_SETSTACKSIZE, [1], [has stack size])) + + AC_CHECK_LIB(${ost_cv_thread_library}, pthread_yield_np, + AC_DEFINE(HAVE_PTHREAD_YIELD_NP, [1], [has np yield]),[ + AC_CHECK_LIB(${ost_cv_thread_library}, pthread_yield, + AC_DEFINE(HAVE_PTHREAD_YIELD, [1], [has yield]),[ + AC_CHECK_LIB(${ost_cv_thread_library}, sched_yield, + AC_DEFINE(HAVE_PTHREAD_SCHED_YIELD, [1], [has sched yield])) + ]) + ]) + + AC_CHECK_LIB(${ost_cv_thread_library}, pthread_cancel,[ + AC_DEFINE(HAVE_PTHREAD_CANCEL, [1], [has cancel]) + AC_CHECK_LIB(${ost_cv_thread_library}, + pthread_setcanceltype, + AC_DEFINE(HAVE_PTHREAD_SETCANCELTYPE, [1], [has setcanceltype]), + AC_CHECK_LIB($ost_cv_thread_library, pthread_setcanel, + AC_DEFINE(HAVE_PTHREAD_SETCANCEL, [1], [has setcancel]))) + ],[ + AC_CHECK_LIB(${ost_cv_thread_library}, + pthread_setcanceltype,[ + AC_DEFINE(HAVE_PTHREAD_CANCEL) + AC_DEFINE(HAVE_PTHREAD_SETCANCELTYPE)]) + + ]) + + AC_CHECK_LIB(${ost_cv_thread_library}, pthread_delay_np, + AC_DEFINE(HAVE_PTHREAD_DELAY_NP, [1], [has non portable delay])) + + fi + + UNAME=`uname` + if test "$UNAME" = "AIX" ; then + AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) + CC=$PTHREAD_CC + AC_DEFINE(COMMON_AIX_FIXES, [1], [aix fixes needed]) + fi + +AH_BOTTOM([ +#ifdef HAVE_THREAD_H +#include "@thrprefix@/thread.h" +#if defined(i386) && defined(__svr4__) && !defined(__sun) +#define _THR_UNIXWARE +#endif +#if defined(__SVR4) && defined(__sun) +#define _THR_SUNOS5 +#else +#if defined(__SVR4__) && defined(__SUN__) +#define _THR_SUNOS5 +#endif +#endif +#endif + +#ifdef HAVE_WORKING_SYS_ATOMIC_H +#include <sys/atomic.h> +#define HAVE_ATOMIC +#elif defined(HAVE_ATOMIC_AIX) +#include <sys/atomic_op.h> +#ifndef HAVE_ATOMIC +#define HAVE_ATOMIC +#endif +#endif + +#if defined(__cplusplus) +#if defined(HAVE_GCC_BITS_ATOMIC) || defined(HAVE_GCC_CXX_BITS_ATOMIC) +#include <bits/atomicity.h> +#define HAVE_ATOMIC +#endif +#endif + +#if defined(HAVE_PTHREAD_H) && ( defined(_THREAD_SAFE) || defined(_REENTRANT) ) + +#ifdef __QNX__ +#define __EXT_QNX +#endif + +#include <pthread.h> + +#ifdef HAVE_PTHREAD_NP_H +#include <pthread_np.h> +#endif + +#ifdef HAVE_SEMAPHORE_H +#include <semaphore.h> +#endif +#ifdef _POSIX_PRIORITY_SCHEDULING +#ifdef HAVE_SCHED_H +#include <sched.h> +#else +#ifdef HAVE_SYS_SCHED_H +#include <sys/sched.h> +#endif +#endif +#endif + +#define __PTHREAD_H__ +#ifndef PTHREAD_MUTEXTYPE_RECURSIVE +#ifdef MUTEX_TYPE_COUNTING_FAST +#define PTHREAD_MUTEXTYPE_RECURSIVE MUTEX_TYPE_COUNTING_FAST +#endif +#endif +#ifndef PTHREAD_MUTEXTYPE_RECURSIVE +#ifdef PTHREAD_MUTEX_RECURSIVE +#define PTHREAD_MUTEXTYPE_RECURSIVE PTHREAD_MUTEX_RECURSIVE +#endif +#endif +#ifndef HAVE_PTHREAD_MUTEXATTR_SETTYPE +#if HAVE_PTHREAD_MUTEXATTR_SETKIND_NP +#ifndef PTHREAD_MUTEXTYPE_RECURSIVE +#define PTHREAD_MUTEXTYPE_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP +#endif +#define pthread_mutexattr_gettype(x, y) pthread_mutexattr_getkind_np(x, y) +#define pthread_mutexattr_settype(x, y) pthread_mutexattr_setkind_np(x, y) +#endif +#if HAVE_PTHREAD_MUTEXATTR_SETTYPE_NP +#ifndef PTHREAD_MUTEXTYPE_RECURSIVE +#define PTHREAD_MUTEXTYPE_RECURSIVE PTHREAD_MUTEXTYPE_RECURSIVE_NP +#endif +#define pthread_mutexattr_settype(x, y) pthread_mutexattr_settype_np(x, y) +#define pthread_mutexattr_gettype(x, y) pthread_mutexattr_gettype_np(x, y) +#endif +#endif + +#ifdef HAVE_PTHREAD_MACH_THREAD_NP +#define _THR_MACH +#endif + +#ifndef HAVE_PTHREAD_YIELD +#ifdef HAVE_PTHREAD_YIELD_NP +#define pthread_yield() pthread_yield_np() +#define HAVE_PTHREAD_YIELD +#endif +#endif + +#ifndef HAVE_PTHREAD_YIELD +#ifdef HAVE_PTHREAD_SCHED_YIELD +#define pthread_yield() sched_yield() +#define HAVE_PTHREAD_YIELD +#endif +#endif + +#ifndef HAVE_PTHREAD_DELAY +#ifdef HAVE_PTHREAD_DELAY_NP +#define HAVE_PTHREAD_DELAY +#define pthread_delay(x) pthread_delay_np(x) +#endif +#if defined(HAVE_PTHREAD_NANOSLEEP) +#ifndef HAVE_PTHREAD_DELAY +#define HAVE_PTHREAD_DELAY +#ifdef __FreeBSD__ +#ifdef __cplusplus +extern "C" int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); +#endif +#endif +#define pthread_delay(x) nanosleep(x, NULL) +#endif +#endif +#endif + +#ifdef HAVE_PTHREAD_ATTR_SETSTACK +#ifndef PTHREAD_STACK_MIN +#define PTHREAD_STACK_MIN 32768 +#endif +#endif + +#ifndef HAVE_PTHREAD_CANCEL +#ifdef SIGCANCEL +#define CCXX_SIG_THREAD_CANCEL SIGCANCEL +#else +#define CCXX_SIG_THREAD_CANCEL SIGQUIT +#endif +#define pthread_cancel(x) pthread_kill(x, CCXX_SIG_THREAD_CANCEL) +#define pthread_setcanceltype(x, y) +#define pthread_setcancelstate(x, y) +#endif + +#ifndef HAVE_PTHREAD_SETCANCELTYPE +#ifdef HAVE_PTHREAD_SETCANCEL +enum +{ PTHREAD_CANCEL_ASYNCHRONOUS = CANCEL_ON, + PTHREAD_CANCEL_DEFERRED = CANCEL_OFF}; +enum +{ PTHREAD_CANCEL_ENABLE = CANCEL_ON, + PTHREAD_CANCEL_DISABLE = CANCEL_OFF}; +#define pthread_setcancelstate(x, y) \ + (y == NULL) ? pthread_setcancel(x) : *y = pthread_setcancel +#define pthread_setcanceltype(x, y) \ + (y == NULL) ? pthread_setasynccancel(x) | *y = pthread_setasynccancel(x) +#else +#define pthread_setcanceltype(x, y) +#define pthread_setcancelstate(x, y) +#endif +#endif + +#ifdef _AIX +#ifdef HAVE_PTHREAD_SUSPEND +#undef HAVE_PTHREAD_SUSPEND +#endif +#endif + +#endif + + + ]) + +]) + |