xref: /unit/auto/threads (revision 765:7b63756a81a4)
10Sigor@sysoev.ru
20Sigor@sysoev.ru# Copyright (C) Igor Sysoev
30Sigor@sysoev.ru# Copyright (C) NGINX, Inc.
40Sigor@sysoev.ru
50Sigor@sysoev.ru
60Sigor@sysoev.rucase "$NXT_SYSTEM" in
70Sigor@sysoev.ru
80Sigor@sysoev.ru    Linux)
90Sigor@sysoev.ru        NXT_PTHREAD="-lpthread"
100Sigor@sysoev.ru    ;;
110Sigor@sysoev.ru
120Sigor@sysoev.ru    FreeBSD)
130Sigor@sysoev.ru        # FreeBSD libc supports only pthread stubs.
140Sigor@sysoev.ru        NXT_PTHREAD="-lpthread"
150Sigor@sysoev.ru    ;;
160Sigor@sysoev.ru
170Sigor@sysoev.ru    SunOS)
180Sigor@sysoev.ru        case "$NXT_SYSTEM_VERSION" in
190Sigor@sysoev.ru        5.8 | 5.9)
200Sigor@sysoev.ru            NXT_PTHREAD="-lpthread"
210Sigor@sysoev.ru        ;;
220Sigor@sysoev.ru        *)
230Sigor@sysoev.ru            # Solaris 10 libpthread.so.1 is a filter to libc.so.1.
240Sigor@sysoev.ru            NXT_PTHREAD=
250Sigor@sysoev.ru        ;;
260Sigor@sysoev.ru        esac
270Sigor@sysoev.ru    ;;
280Sigor@sysoev.ru
290Sigor@sysoev.ru    Darwin)
300Sigor@sysoev.ru        # MacOSX libpthread.dylib is a symlink to libSystem.dylib.
310Sigor@sysoev.ru        NXT_PTHREAD=
320Sigor@sysoev.ru    ;;
330Sigor@sysoev.ru
340Sigor@sysoev.ru    *)
350Sigor@sysoev.ru        NXT_PTHREAD="-lpthread"
360Sigor@sysoev.ru    ;;
370Sigor@sysoev.ruesac
380Sigor@sysoev.ru
390Sigor@sysoev.ru
400Sigor@sysoev.ru# Linux, FreeBSD.
410Sigor@sysoev.ru
420Sigor@sysoev.runxt_feature="pthread_yield()"
430Sigor@sysoev.runxt_feature_name=NXT_HAVE_PTHREAD_YIELD
440Sigor@sysoev.runxt_feature_run=
450Sigor@sysoev.runxt_feature_incs=
460Sigor@sysoev.runxt_feature_libs=$NXT_PTHREAD
470Sigor@sysoev.runxt_feature_test="#define _GNU_SOURCE
480Sigor@sysoev.ru              #include <pthread.h>
490Sigor@sysoev.ru
500Sigor@sysoev.ru              int main() {
510Sigor@sysoev.ru                  pthread_yield();
520Sigor@sysoev.ru                  return 0;
530Sigor@sysoev.ru              }"
540Sigor@sysoev.ru. auto/feature
550Sigor@sysoev.ru
560Sigor@sysoev.ru
570Sigor@sysoev.ruif [ $nxt_found = no ]; then
580Sigor@sysoev.ru
590Sigor@sysoev.ru    # MacOSX.
600Sigor@sysoev.ru
610Sigor@sysoev.ru    nxt_feature="pthread_yield_np()"
620Sigor@sysoev.ru    nxt_feature_name=NXT_HAVE_PTHREAD_YIELD_NP
630Sigor@sysoev.ru    nxt_feature_run=
640Sigor@sysoev.ru    nxt_feature_incs=
650Sigor@sysoev.ru    nxt_feature_libs=$NXT_PTHREAD
660Sigor@sysoev.ru    nxt_feature_test="#include <pthread.h>
670Sigor@sysoev.ru
680Sigor@sysoev.ru                  int main() {
690Sigor@sysoev.ru                      pthread_yield_np();
700Sigor@sysoev.ru                      return 0;
710Sigor@sysoev.ru                  }"
720Sigor@sysoev.ru    . auto/feature
730Sigor@sysoev.rufi
740Sigor@sysoev.ru
750Sigor@sysoev.ru
760Sigor@sysoev.ru# FreeBSD, Solaris, AIX.
770Sigor@sysoev.ru
780Sigor@sysoev.runxt_feature="pthread spinlock"
790Sigor@sysoev.runxt_feature_name=NXT_HAVE_PTHREAD_SPINLOCK
800Sigor@sysoev.runxt_feature_run=yes
810Sigor@sysoev.runxt_feature_incs=
820Sigor@sysoev.runxt_feature_libs=$NXT_PTHREAD
830Sigor@sysoev.runxt_feature_test="#include <pthread.h>
840Sigor@sysoev.ru
850Sigor@sysoev.ru              int main() {
860Sigor@sysoev.ru                  pthread_spinlock_t  lock;
870Sigor@sysoev.ru
880Sigor@sysoev.ru                  if (pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE) != 0)
890Sigor@sysoev.ru                      return 1;
900Sigor@sysoev.ru                  if (pthread_spin_lock(&lock) != 0)
910Sigor@sysoev.ru                      return 1;
920Sigor@sysoev.ru                  if (pthread_spin_unlock(&lock) != 0)
930Sigor@sysoev.ru                      return 1;
940Sigor@sysoev.ru                  if (pthread_spin_destroy(&lock) != 0)
950Sigor@sysoev.ru                      return 1;
960Sigor@sysoev.ru                  return 0;
970Sigor@sysoev.ru              }"
980Sigor@sysoev.ru. auto/feature
990Sigor@sysoev.ru
1000Sigor@sysoev.ru
1010Sigor@sysoev.ruif [ $nxt_found = yes ]; then
1020Sigor@sysoev.ru
1030Sigor@sysoev.ru    # Linux glibc uses 0 as pthread_spinlock_t initial value on the most
1040Sigor@sysoev.ru    # platforms.  However, on i386 and x86_64 the initial value is 1.
1050Sigor@sysoev.ru
1060Sigor@sysoev.ru    nxt_feature="pthread spinlock zero initial value"
1070Sigor@sysoev.ru    nxt_feature_name=NXT_HAVE_PTHREAD_SPINLOCK_ZERO
1080Sigor@sysoev.ru    nxt_feature_run=yes
1090Sigor@sysoev.ru    nxt_feature_incs=
1100Sigor@sysoev.ru    nxt_feature_libs=$NXT_PTHREAD
1110Sigor@sysoev.ru    nxt_feature_test="#include <pthread.h>
1120Sigor@sysoev.ru
1130Sigor@sysoev.ru                      pthread_spinlock_t  lock = 0;
1140Sigor@sysoev.ru
1150Sigor@sysoev.ru                      int main() {
1160Sigor@sysoev.ru                          if (pthread_spin_trylock(&lock) != 0)
1170Sigor@sysoev.ru                              return 1;
1180Sigor@sysoev.ru                          if (pthread_spin_unlock(&lock) != 0)
1190Sigor@sysoev.ru                              return 1;
1200Sigor@sysoev.ru                          return 0;
1210Sigor@sysoev.ru                      }"
1220Sigor@sysoev.ru    . auto/feature
1230Sigor@sysoev.rufi
1240Sigor@sysoev.ru
1250Sigor@sysoev.ru
1260Sigor@sysoev.runxt_feature="sem_timedwait()"
1270Sigor@sysoev.runxt_feature_name=NXT_HAVE_SEM_TIMEDWAIT
1280Sigor@sysoev.runxt_feature_run=yes
1290Sigor@sysoev.runxt_feature_incs=
1300Sigor@sysoev.runxt_feature_libs=
1310Sigor@sysoev.runxt_feature_test="#include <semaphore.h>
1320Sigor@sysoev.ru
1330Sigor@sysoev.ru                  int main() {
1340Sigor@sysoev.ru                      sem_t            sem;
1350Sigor@sysoev.ru                      struct timespec  ts;
1360Sigor@sysoev.ru
1370Sigor@sysoev.ru                      if (sem_init(&sem, 0, 0) != 0)
1380Sigor@sysoev.ru                          return 1;
1390Sigor@sysoev.ru                      if (sem_post(&sem) != 0)
1400Sigor@sysoev.ru                          return 1;
1410Sigor@sysoev.ru
1420Sigor@sysoev.ru                      ts.tv_sec = 0;
1430Sigor@sysoev.ru                      ts.tv_nsec = 0;
1440Sigor@sysoev.ru                      if (sem_timedwait(&sem, &ts) != 0)
1450Sigor@sysoev.ru                          return 1;
1460Sigor@sysoev.ru
1470Sigor@sysoev.ru                      if (sem_destroy(&sem) != 0)
1480Sigor@sysoev.ru                          return 1;
1490Sigor@sysoev.ru                      return 0;
1500Sigor@sysoev.ru                  }"
1510Sigor@sysoev.ru. auto/feature
1520Sigor@sysoev.ru
1530Sigor@sysoev.ru
1540Sigor@sysoev.ruif [ $nxt_found = no ]; then
1550Sigor@sysoev.ru
1560Sigor@sysoev.ru    if [ -n "$NXT_PTHREAD" ]; then
1570Sigor@sysoev.ru
1580Sigor@sysoev.ru        # Linux requires libpthread.
1590Sigor@sysoev.ru
1600Sigor@sysoev.ru        nxt_feature="sem_timedwait() in libpthread"
1610Sigor@sysoev.ru        nxt_feature_libs=$NXT_PTHREAD
1620Sigor@sysoev.ru        . auto/feature
1630Sigor@sysoev.ru    fi
1640Sigor@sysoev.ru
1650Sigor@sysoev.ru    if [ $nxt_found = no ]; then
1660Sigor@sysoev.ru
1670Sigor@sysoev.ru        # Solaris 10 requires librt.
1680Sigor@sysoev.ru
1690Sigor@sysoev.ru        nxt_feature="sem_timedwait() in librt"
1700Sigor@sysoev.ru        nxt_feature_libs="-lrt"
1710Sigor@sysoev.ru        . auto/feature
1720Sigor@sysoev.ru
1730Sigor@sysoev.ru        if [ $nxt_found = yes ]; then
1740Sigor@sysoev.ru            NXT_LIBRT="-lrt"
1750Sigor@sysoev.ru        fi
1760Sigor@sysoev.ru    fi
1770Sigor@sysoev.rufi
1780Sigor@sysoev.ru
1790Sigor@sysoev.ru
1800Sigor@sysoev.ru# Thread Local Storage / Thread Specific Data.
1810Sigor@sysoev.ru#
1820Sigor@sysoev.ru# Linux, FreeBSD 5.3, Solaris.
183*709Sigor@sysoev.ru# MacOSX 10.7 (Lion) Clang.
1840Sigor@sysoev.ru
1850Sigor@sysoev.runxt_feature="__thread"
1860Sigor@sysoev.runxt_feature_name=NXT_HAVE_THREAD_STORAGE_CLASS
1870Sigor@sysoev.runxt_feature_run=yes
1880Sigor@sysoev.runxt_feature_incs=
1890Sigor@sysoev.runxt_feature_libs=$NXT_PTHREAD
1900Sigor@sysoev.runxt_feature_test="#include <pthread.h>
1910Sigor@sysoev.ru                  #include <stdlib.h>
1920Sigor@sysoev.ru
1930Sigor@sysoev.ru                  __thread int  key;
1940Sigor@sysoev.ru
1950Sigor@sysoev.ru                  void *func(void *p);
1960Sigor@sysoev.ru
1970Sigor@sysoev.ru                  void *func(void *p) {
1980Sigor@sysoev.ru                      key = 0x9abcdef0;
1990Sigor@sysoev.ru                      return NULL;
2000Sigor@sysoev.ru                  }
2010Sigor@sysoev.ru
2020Sigor@sysoev.ru                  int main() {
2030Sigor@sysoev.ru                      void       *n;
2040Sigor@sysoev.ru                      pthread_t  pt;
2050Sigor@sysoev.ru
2060Sigor@sysoev.ru                      key = 0x12345678;
2070Sigor@sysoev.ru                      if (pthread_create(&pt, NULL, func, NULL))
2080Sigor@sysoev.ru                          return 1;
2090Sigor@sysoev.ru                      if (pthread_join(pt, &n))
2100Sigor@sysoev.ru                          return 1;
2110Sigor@sysoev.ru                      if (key != 0x12345678)
2120Sigor@sysoev.ru                          return 1;
2130Sigor@sysoev.ru                      return 0;
2140Sigor@sysoev.ru                  }"
2150Sigor@sysoev.ru. auto/feature
2160Sigor@sysoev.ru
2170Sigor@sysoev.ru
2180Sigor@sysoev.ruif [ $nxt_found = no ]; then
2190Sigor@sysoev.ru
2200Sigor@sysoev.ru    # MacOSX GCC lacks __thread support.
2210Sigor@sysoev.ru    # On NetBSD __thread causes segmentation fault.
2220Sigor@sysoev.ru
2230Sigor@sysoev.ru    nxt_feature="phtread_key_t"
2240Sigor@sysoev.ru    nxt_feature_name=NXT_HAVE_PTHREAD_SPECIFIC_DATA
2250Sigor@sysoev.ru    nxt_feature_run=yes
2260Sigor@sysoev.ru    nxt_feature_incs=
2270Sigor@sysoev.ru    nxt_feature_libs=$NXT_PTHREAD
2280Sigor@sysoev.ru    nxt_feature_test="#include <pthread.h>
2290Sigor@sysoev.ru
2300Sigor@sysoev.ru                      int main() {
2310Sigor@sysoev.ru                          pthread_key_t  key = -1;
2320Sigor@sysoev.ru
2330Sigor@sysoev.ru                          if (pthread_key_create(&key, NULL))
2340Sigor@sysoev.ru                              return 1;
2350Sigor@sysoev.ru                          if (pthread_setspecific(key, (void *) 0x12345678))
2360Sigor@sysoev.ru                              return 1;
2370Sigor@sysoev.ru                          if (pthread_getspecific(key) != (void *) 0x12345678)
2380Sigor@sysoev.ru                              return 1;
2390Sigor@sysoev.ru                          return 0;
2400Sigor@sysoev.ru                      }"
2410Sigor@sysoev.ru    . auto/feature
2420Sigor@sysoev.ru
2430Sigor@sysoev.ru
2440Sigor@sysoev.ru    nxt_feature="PTHREAD_KEYS_MAX"
2450Sigor@sysoev.ru    nxt_feature_name=
2460Sigor@sysoev.ru    nxt_feature_run=value
2470Sigor@sysoev.ru    nxt_feature_incs=
2480Sigor@sysoev.ru    nxt_feature_libs=
2490Sigor@sysoev.ru    nxt_feature_test="#include <limits.h>
2500Sigor@sysoev.ru                      #include <pthread.h>
2510Sigor@sysoev.ru                      #include <stdio.h>
2520Sigor@sysoev.ru
2530Sigor@sysoev.ru                      int main() {
2540Sigor@sysoev.ru                          printf(\"%d\", PTHREAD_KEYS_MAX);
2550Sigor@sysoev.ru                          return 0;
2560Sigor@sysoev.ru                      }"
2570Sigor@sysoev.ru    . auto/feature
2580Sigor@sysoev.rufi
259