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