summaryrefslogtreecommitdiff
path: root/Configure
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2021-06-20 19:35:13 +0000
committerTony Cook <tony@develop-help.com>2021-09-07 15:46:16 +1000
commit65f7068160bfc9a3f4b195a579c881188cc4fff3 (patch)
tree2d628c83f8daab915975f364a33e81e6b00eafad /Configure
parent756f0910f92bc6bc2d2c7eb17f26efccdf977cdc (diff)
downloadperl-65f7068160bfc9a3f4b195a579c881188cc4fff3.tar.gz
A Configure test for C11 thread local storage specificer, _Thread_local
We also provbe for gcc's earlier syntax, __thread.
Diffstat (limited to 'Configure')
-rwxr-xr-xConfigure127
1 files changed, 127 insertions, 0 deletions
diff --git a/Configure b/Configure
index 08f2445a40..5879d7a233 100755
--- a/Configure
+++ b/Configure
@@ -860,6 +860,8 @@ d_statfs_f_flags=''
d_statfs_s=''
d_static_inline=''
perl_static_inline=''
+d_thread_local=''
+perl_thread_local=''
d_fstatvfs=''
d_statvfs=''
d_stdio_cnt_lval=''
@@ -19231,6 +19233,129 @@ eval $setvar
$rm -f a.[co] b.[co]
$rm_try
+: see what flavor, if any, of thread local storage is supported
+echo " "
+echo "Checking to see if your system supports C11 thread local storage..."
+$cat > try.c <<'EOCP'
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+static int plus_one = 1;
+static int minus_one = -1;
+
+PROBE_MACRO int *minion;
+
+int callback (const void *a, const void *b) {
+ int val_a = *minion * *(const int *)a;
+ int val_b = *minion * *(const int *)b;
+ return val_a < val_b ? -1 : val_a > val_b;
+}
+
+#define SIZE 8
+
+void *thread_function(void *arg) {
+ /* thread local variables should start zeroed in each thread. */
+ if (minion != NULL) {
+ fprintf(stderr, "__thread variable started with %p, should be NULL\n",
+ minion);
+ exit(2);
+ }
+ minion = &minus_one;
+
+ int array[SIZE];
+ unsigned int i;
+ for (i = 0; i < SIZE; ++i) {
+ /* "Hash randomisation" - this array isn't in sorted order: */
+ array[i ^ 5] = i * i;
+ }
+
+ qsort(array, SIZE, sizeof(int), callback);
+
+ int bad = 0;
+ for (i = 0; i < SIZE; ++i) {
+ int want = (SIZE - 1 - i) * (SIZE - 1 - i);
+ int have = array[i];
+ if (want != have) {
+ ++bad;
+ fprintf(stderr, "array[%u] - want %i, have %i\n", i, want, have);
+ }
+ }
+ if (bad)
+ exit(3);
+
+ return NULL;
+}
+
+int main(int argc, char **argv) {
+ if (minion != NULL) {
+ fprintf(stderr, "__thread variable started with %p, should be NULL\n",
+ minion);
+ exit(4);
+ }
+
+ minion = &plus_one;
+
+ pthread_t tid;
+ int result = pthread_create(&tid, NULL, thread_function, NULL);
+ if (result) {
+ fprintf(stderr, "pthread_create failed (%d)\n", result);
+ exit(5);
+ }
+
+ result = pthread_join(tid, NULL);
+ if (result) {
+ fprintf(stderr, "pthread_join failed (%d)\n", result);
+ exit(6);
+ }
+
+ if (minion == NULL) {
+ fprintf(stderr, "__thread variable should not be NULL\n");
+ exit(7);
+ }
+ if (!(minion == &plus_one && *minion == 1)) {
+ fprintf(stderr, "__thread variable should be %d @ %p, not %d @ %p\n",
+ 1, &plus_one, *minion, minion);
+ exit(8);
+ }
+
+ return 0;
+}
+EOCP
+
+# Respect a hint (or previous) value for perl_thread_local, if there is one.
+case "$perl_thread_local" in
+'') # Check the various possibilities, and break out on success.
+ for thread_local in _Thread_local __thread; do
+ set try -DPROBE_MACRO=$thread_local
+ if eval $compile && $run ./try; then
+ $echo "Your compiler supports $thread_local." >&4
+ val=$define
+ perl_thread_local="$thread_local";
+ break;
+ fi
+ $echo "Your compiler does NOT support $thread_local." >&4
+ val="$undef"
+ done
+ ;;
+*thread*|*Thread*) # Some variant of thread local exists.
+ echo "Keeping your $hint value of $perl_thread_local."
+ val=$define
+ ;;
+*) # Unrecognized previous value -- blindly trust the supplied
+ # value and hope it makes sense. Use old value for
+ # d_thread_local, if there is one.
+ echo "Keeping your $hint value of $perl_thread_local."
+ case "$d_thread_local" in
+ '') val=$define ;;
+ *) val=$d_thread_local ;;
+ esac
+ ;;
+esac
+set d_thread_local
+eval $setvar
+$rm_try
+
: Check stream access
$cat >&4 <<EOM
Checking how to access stdio streams by file descriptor number...
@@ -24883,6 +25008,7 @@ d_tcsetpgrp='$d_tcsetpgrp'
d_telldir='$d_telldir'
d_telldirproto='$d_telldirproto'
d_tgamma='$d_tgamma'
+d_thread_local='$d_thread_local'
d_thread_safe_nl_langinfo_l='$d_thread_safe_nl_langinfo_l'
d_time='$d_time'
d_timegm='$d_timegm'
@@ -25258,6 +25384,7 @@ perl5='$perl5'
perl='$perl'
perl_patchlevel='$perl_patchlevel'
perl_static_inline='$perl_static_inline'
+perl_thread_local='$perl_thread_local'
perladmin='$perladmin'
perllibs='$perllibs'
perlpath='$perlpath'