diff options
author | Nicholas Clark <nick@ccl4.org> | 2021-06-20 19:35:13 +0000 |
---|---|---|
committer | Tony Cook <tony@develop-help.com> | 2021-09-07 15:46:16 +1000 |
commit | 65f7068160bfc9a3f4b195a579c881188cc4fff3 (patch) | |
tree | 2d628c83f8daab915975f364a33e81e6b00eafad /Configure | |
parent | 756f0910f92bc6bc2d2c7eb17f26efccdf977cdc (diff) | |
download | perl-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-x | Configure | 127 |
1 files changed, 127 insertions, 0 deletions
@@ -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' |