1# threadlib.m4 serial 16 2dnl Copyright (C) 2005-2019 Free Software Foundation, Inc. 3dnl This file is free software; the Free Software Foundation 4dnl gives unlimited permission to copy and/or distribute it, 5dnl with or without modifications, as long as this notice is preserved. 6 7dnl From Bruno Haible. 8 9AC_PREREQ([2.60]) 10 11dnl gl_THREADLIB 12dnl ------------ 13dnl Tests for a multithreading library to be used. 14dnl If the configure.ac contains a definition of the gl_THREADLIB_DEFAULT_NO 15dnl (it must be placed before the invocation of gl_THREADLIB_EARLY!), then the 16dnl default is 'no', otherwise it is system dependent. In both cases, the user 17dnl can change the choice through the options --enable-threads=choice or 18dnl --disable-threads. 19dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS, 20dnl USE_PTH_THREADS, USE_WINDOWS_THREADS 21dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use 22dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with 23dnl libtool). 24dnl Sets the variables LIBMULTITHREAD and LTLIBMULTITHREAD similarly, for 25dnl programs that really need multithread functionality. The difference 26dnl between LIBTHREAD and LIBMULTITHREAD is that on platforms supporting weak 27dnl symbols, typically LIBTHREAD is empty whereas LIBMULTITHREAD is not. 28dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for 29dnl multithread-safe programs. 30 31AC_DEFUN([gl_THREADLIB_EARLY], 32[ 33 AC_REQUIRE([gl_THREADLIB_EARLY_BODY]) 34]) 35 36dnl The guts of gl_THREADLIB_EARLY. Needs to be expanded only once. 37 38AC_DEFUN([gl_THREADLIB_EARLY_BODY], 39[ 40 dnl Ordering constraints: This macro modifies CPPFLAGS in a way that 41 dnl influences the result of the autoconf tests that test for *_unlocked 42 dnl declarations, on AIX 5 at least. Therefore it must come early. 43 AC_BEFORE([$0], [gl_FUNC_GLIBC_UNLOCKED_IO])dnl 44 AC_BEFORE([$0], [gl_ARGP])dnl 45 46 AC_REQUIRE([AC_CANONICAL_HOST]) 47 dnl _GNU_SOURCE is needed for pthread_rwlock_t on glibc systems. 48 AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) 49 dnl Check for multithreading. 50 m4_ifdef([gl_THREADLIB_DEFAULT_NO], 51 [m4_divert_text([DEFAULTS], [gl_use_threads_default=no])], 52 [m4_divert_text([DEFAULTS], [gl_use_threads_default=])]) 53 AC_ARG_ENABLE([threads], 54AC_HELP_STRING([--enable-threads={posix|solaris|pth|windows}], [specify multithreading API])m4_ifdef([gl_THREADLIB_DEFAULT_NO], [], [ 55AC_HELP_STRING([--disable-threads], [build without multithread safety])]), 56 [gl_use_threads=$enableval], 57 [if test -n "$gl_use_threads_default"; then 58 gl_use_threads="$gl_use_threads_default" 59 else 60changequote(,)dnl 61 case "$host_os" in 62 dnl Disable multithreading by default on OSF/1, because it interferes 63 dnl with fork()/exec(): When msgexec is linked with -lpthread, its 64 dnl child process gets an endless segmentation fault inside execvp(). 65 dnl Disable multithreading by default on Cygwin 1.5.x, because it has 66 dnl bugs that lead to endless loops or crashes. See 67 dnl <https://cygwin.com/ml/cygwin/2009-08/msg00283.html>. 68 osf*) gl_use_threads=no ;; 69 cygwin*) 70 case `uname -r` in 71 1.[0-5].*) gl_use_threads=no ;; 72 *) gl_use_threads=yes ;; 73 esac 74 ;; 75 *) gl_use_threads=yes ;; 76 esac 77changequote([,])dnl 78 fi 79 ]) 80 if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then 81 # For using <pthread.h>: 82 case "$host_os" in 83 osf*) 84 # On OSF/1, the compiler needs the flag -D_REENTRANT so that it 85 # groks <pthread.h>. cc also understands the flag -pthread, but 86 # we don't use it because 1. gcc-2.95 doesn't understand -pthread, 87 # 2. putting a flag into CPPFLAGS that has an effect on the linker 88 # causes the AC_LINK_IFELSE test below to succeed unexpectedly, 89 # leading to wrong values of LIBTHREAD and LTLIBTHREAD. 90 CPPFLAGS="$CPPFLAGS -D_REENTRANT" 91 ;; 92 esac 93 # Some systems optimize for single-threaded programs by default, and 94 # need special flags to disable these optimizations. For example, the 95 # definition of 'errno' in <errno.h>. 96 case "$host_os" in 97 aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;; 98 solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; 99 esac 100 fi 101]) 102 103dnl The guts of gl_THREADLIB. Needs to be expanded only once. 104 105AC_DEFUN([gl_THREADLIB_BODY], 106[ 107 AC_REQUIRE([gl_THREADLIB_EARLY_BODY]) 108 gl_threads_api=none 109 LIBTHREAD= 110 LTLIBTHREAD= 111 LIBMULTITHREAD= 112 LTLIBMULTITHREAD= 113 if test "$gl_use_threads" != no; then 114 dnl Check whether the compiler and linker support weak declarations. 115 AC_CACHE_CHECK([whether imported symbols can be declared weak], 116 [gl_cv_have_weak], 117 [gl_cv_have_weak=no 118 dnl First, test whether the compiler accepts it syntactically. 119 AC_LINK_IFELSE( 120 [AC_LANG_PROGRAM( 121 [[extern void xyzzy (); 122#pragma weak xyzzy]], 123 [[xyzzy();]])], 124 [gl_cv_have_weak=maybe]) 125 if test $gl_cv_have_weak = maybe; then 126 dnl Second, test whether it actually works. On Cygwin 1.7.2, with 127 dnl gcc 4.3, symbols declared weak always evaluate to the address 0. 128 AC_RUN_IFELSE( 129 [AC_LANG_SOURCE([[ 130#include <stdio.h> 131#pragma weak fputs 132int main () 133{ 134 return (fputs == NULL); 135}]])], 136 [gl_cv_have_weak=yes], 137 [gl_cv_have_weak=no], 138 [dnl When cross-compiling, assume that only ELF platforms support 139 dnl weak symbols. 140 AC_EGREP_CPP([Extensible Linking Format], 141 [#ifdef __ELF__ 142 Extensible Linking Format 143 #endif 144 ], 145 [gl_cv_have_weak="guessing yes"], 146 [gl_cv_have_weak="guessing no"]) 147 ]) 148 fi 149 dnl But when linking statically, weak symbols don't work. 150 case " $LDFLAGS " in 151 *" -static "*) gl_cv_have_weak=no ;; 152 esac 153 ]) 154 if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then 155 # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that 156 # it groks <pthread.h>. It's added above, in gl_THREADLIB_EARLY_BODY. 157 AC_CHECK_HEADER([pthread.h], 158 [gl_have_pthread_h=yes], [gl_have_pthread_h=no]) 159 if test "$gl_have_pthread_h" = yes; then 160 # Other possible tests: 161 # -lpthreads (FSU threads, PCthreads) 162 # -lgthreads 163 gl_have_pthread= 164 # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist 165 # in libc. IRIX 6.5 has the first one in both libc and libpthread, but 166 # the second one only in libpthread, and lock.c needs it. 167 # 168 # If -pthread works, prefer it to -lpthread, since Ubuntu 14.04 169 # needs -pthread for some reason. See: 170 # https://lists.gnu.org/r/bug-gnulib/2014-09/msg00023.html 171 save_LIBS=$LIBS 172 for gl_pthread in '' '-pthread'; do 173 LIBS="$LIBS $gl_pthread" 174 AC_LINK_IFELSE( 175 [AC_LANG_PROGRAM( 176 [[#include <pthread.h> 177 pthread_mutex_t m; 178 pthread_mutexattr_t ma; 179 ]], 180 [[pthread_mutex_lock (&m); 181 pthread_mutexattr_init (&ma);]])], 182 [gl_have_pthread=yes 183 LIBTHREAD=$gl_pthread LTLIBTHREAD=$gl_pthread 184 LIBMULTITHREAD=$gl_pthread LTLIBMULTITHREAD=$gl_pthread]) 185 LIBS=$save_LIBS 186 test -n "$gl_have_pthread" && break 187 done 188 189 # Test for libpthread by looking for pthread_kill. (Not pthread_self, 190 # since it is defined as a macro on OSF/1.) 191 if test -n "$gl_have_pthread" && test -z "$LIBTHREAD"; then 192 # The program links fine without libpthread. But it may actually 193 # need to link with libpthread in order to create multiple threads. 194 AC_CHECK_LIB([pthread], [pthread_kill], 195 [LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread 196 # On Solaris and HP-UX, most pthread functions exist also in libc. 197 # Therefore pthread_in_use() needs to actually try to create a 198 # thread: pthread_create from libc will fail, whereas 199 # pthread_create will actually create a thread. 200 # On Solaris 10 or newer, this test is no longer needed, because 201 # libc contains the fully functional pthread functions. 202 case "$host_os" in 203 solaris | solaris2.[1-9] | solaris2.[1-9].* | hpux*) 204 AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1], 205 [Define if the pthread_in_use() detection is hard.]) 206 esac 207 ]) 208 elif test -z "$gl_have_pthread"; then 209 # Some library is needed. Try libpthread and libc_r. 210 AC_CHECK_LIB([pthread], [pthread_kill], 211 [gl_have_pthread=yes 212 LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread 213 LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread]) 214 if test -z "$gl_have_pthread"; then 215 # For FreeBSD 4. 216 AC_CHECK_LIB([c_r], [pthread_kill], 217 [gl_have_pthread=yes 218 LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r 219 LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r]) 220 fi 221 fi 222 if test -n "$gl_have_pthread"; then 223 gl_threads_api=posix 224 AC_DEFINE([USE_POSIX_THREADS], [1], 225 [Define if the POSIX multithreading library can be used.]) 226 if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then 227 if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then 228 AC_DEFINE([USE_POSIX_THREADS_WEAK], [1], 229 [Define if references to the POSIX multithreading library should be made weak.]) 230 LIBTHREAD= 231 LTLIBTHREAD= 232 fi 233 fi 234 fi 235 fi 236 fi 237 if test -z "$gl_have_pthread"; then 238 if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then 239 gl_have_solaristhread= 240 gl_save_LIBS="$LIBS" 241 LIBS="$LIBS -lthread" 242 AC_LINK_IFELSE( 243 [AC_LANG_PROGRAM( 244 [[ 245#include <thread.h> 246#include <synch.h> 247 ]], 248 [[thr_self();]])], 249 [gl_have_solaristhread=yes]) 250 LIBS="$gl_save_LIBS" 251 if test -n "$gl_have_solaristhread"; then 252 gl_threads_api=solaris 253 LIBTHREAD=-lthread 254 LTLIBTHREAD=-lthread 255 LIBMULTITHREAD="$LIBTHREAD" 256 LTLIBMULTITHREAD="$LTLIBTHREAD" 257 AC_DEFINE([USE_SOLARIS_THREADS], [1], 258 [Define if the old Solaris multithreading library can be used.]) 259 if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then 260 AC_DEFINE([USE_SOLARIS_THREADS_WEAK], [1], 261 [Define if references to the old Solaris multithreading library should be made weak.]) 262 LIBTHREAD= 263 LTLIBTHREAD= 264 fi 265 fi 266 fi 267 fi 268 if test "$gl_use_threads" = pth; then 269 gl_save_CPPFLAGS="$CPPFLAGS" 270 AC_LIB_LINKFLAGS([pth]) 271 gl_have_pth= 272 gl_save_LIBS="$LIBS" 273 LIBS="$LIBS $LIBPTH" 274 AC_LINK_IFELSE( 275 [AC_LANG_PROGRAM([[#include <pth.h>]], [[pth_self();]])], 276 [gl_have_pth=yes]) 277 LIBS="$gl_save_LIBS" 278 if test -n "$gl_have_pth"; then 279 gl_threads_api=pth 280 LIBTHREAD="$LIBPTH" 281 LTLIBTHREAD="$LTLIBPTH" 282 LIBMULTITHREAD="$LIBTHREAD" 283 LTLIBMULTITHREAD="$LTLIBTHREAD" 284 AC_DEFINE([USE_PTH_THREADS], [1], 285 [Define if the GNU Pth multithreading library can be used.]) 286 if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then 287 if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then 288 AC_DEFINE([USE_PTH_THREADS_WEAK], [1], 289 [Define if references to the GNU Pth multithreading library should be made weak.]) 290 LIBTHREAD= 291 LTLIBTHREAD= 292 fi 293 fi 294 else 295 CPPFLAGS="$gl_save_CPPFLAGS" 296 fi 297 fi 298 if test -z "$gl_have_pthread"; then 299 case "$gl_use_threads" in 300 yes | windows | win32) # The 'win32' is for backward compatibility. 301 if { case "$host_os" in 302 mingw*) true;; 303 *) false;; 304 esac 305 }; then 306 gl_threads_api=windows 307 AC_DEFINE([USE_WINDOWS_THREADS], [1], 308 [Define if the native Windows multithreading API can be used.]) 309 fi 310 ;; 311 esac 312 fi 313 fi 314 AC_MSG_CHECKING([for multithread API to use]) 315 AC_MSG_RESULT([$gl_threads_api]) 316 AC_SUBST([LIBTHREAD]) 317 AC_SUBST([LTLIBTHREAD]) 318 AC_SUBST([LIBMULTITHREAD]) 319 AC_SUBST([LTLIBMULTITHREAD]) 320]) 321 322AC_DEFUN([gl_THREADLIB], 323[ 324 AC_REQUIRE([gl_THREADLIB_EARLY]) 325 AC_REQUIRE([gl_THREADLIB_BODY]) 326]) 327 328 329dnl gl_DISABLE_THREADS 330dnl ------------------ 331dnl Sets the gl_THREADLIB default so that threads are not used by default. 332dnl The user can still override it at installation time, by using the 333dnl configure option '--enable-threads'. 334 335AC_DEFUN([gl_DISABLE_THREADS], [ 336 m4_divert_text([INIT_PREPARE], [gl_use_threads_default=no]) 337]) 338 339 340dnl Survey of platforms: 341dnl 342dnl Platform Available Compiler Supports test-lock 343dnl flavours option weak result 344dnl --------------- --------- --------- -------- --------- 345dnl Linux 2.4/glibc posix -lpthread Y OK 346dnl 347dnl GNU Hurd/glibc posix 348dnl 349dnl Ubuntu 14.04 posix -pthread Y OK 350dnl 351dnl FreeBSD 5.3 posix -lc_r Y 352dnl posix -lkse ? Y 353dnl posix -lpthread ? Y 354dnl posix -lthr Y 355dnl 356dnl FreeBSD 5.2 posix -lc_r Y 357dnl posix -lkse Y 358dnl posix -lthr Y 359dnl 360dnl FreeBSD 4.0,4.10 posix -lc_r Y OK 361dnl 362dnl NetBSD 1.6 -- 363dnl 364dnl OpenBSD 3.4 posix -lpthread Y OK 365dnl 366dnl Mac OS X 10.[123] posix -lpthread Y OK 367dnl 368dnl Solaris 7,8,9 posix -lpthread Y Sol 7,8: 0.0; Sol 9: OK 369dnl solaris -lthread Y Sol 7,8: 0.0; Sol 9: OK 370dnl 371dnl HP-UX 11 posix -lpthread N (cc) OK 372dnl Y (gcc) 373dnl 374dnl IRIX 6.5 posix -lpthread Y 0.5 375dnl 376dnl AIX 4.3,5.1 posix -lpthread N AIX 4: 0.5; AIX 5: OK 377dnl 378dnl OSF/1 4.0,5.1 posix -pthread (cc) N OK 379dnl -lpthread (gcc) Y 380dnl 381dnl Cygwin posix -lpthread Y OK 382dnl 383dnl Any of the above pth -lpth 0.0 384dnl 385dnl Mingw windows N OK 386dnl 387dnl BeOS 5 -- 388dnl 389dnl The test-lock result shows what happens if in test-lock.c EXPLICIT_YIELD is 390dnl turned off: 391dnl OK if all three tests terminate OK, 392dnl 0.5 if the first test terminates OK but the second one loops endlessly, 393dnl 0.0 if the first test already loops endlessly. 394