summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--globals.c8
-rw-r--r--makedef.pl3
-rw-r--r--thread.h32
3 files changed, 37 insertions, 6 deletions
diff --git a/globals.c b/globals.c
index 045c71ca3f..5a78c81166 100644
--- a/globals.c
+++ b/globals.c
@@ -30,6 +30,14 @@
*/
#include "regcomp.h"
+/* We need somewhere to declare this. This file seems a good place.
+ * This is not a regular "global" in that we don't know whether it needs to
+ * exist until we include threads.h, and we don't want it as part of any
+ * global struct (if that or something similar is re-introduced. */
+
+#if defined(USE_ITHREADS) && defined(PERL_THREAD_LOCAL)
+PERL_THREAD_LOCAL void *PL_current_context;
+#endif
/*
* ex: set ts=8 sts=4 sw=4 et:
diff --git a/makedef.pl b/makedef.pl
index b5b07a7ece..f13573171e 100644
--- a/makedef.pl
+++ b/makedef.pl
@@ -189,6 +189,9 @@ my %skip;
# All platforms export boot_DynaLoader unconditionally.
my %export = ( boot_DynaLoader => 1 );
+++$export{PL_current_context}
+ if defined $Config{perl_thread_local} && $define{USE_ITHREADS};
+
sub try_symbols {
foreach my $symbol (@_) {
++$export{$symbol} unless exists $skip{$symbol};
diff --git a/thread.h b/thread.h
index dcec0c064b..8ec4411b0c 100644
--- a/thread.h
+++ b/thread.h
@@ -379,19 +379,39 @@
# define PTHREAD_GETSPECIFIC(key) pthread_getspecific(key)
#endif
-#ifndef PERL_GET_CONTEXT
-# define PERL_GET_CONTEXT PTHREAD_GETSPECIFIC(PL_thr_key)
-#endif
+#if defined(PERL_THREAD_LOCAL) && !defined(PERL_GET_CONTEXT) && !defined(PERL_SET_CONTEXT)
+/* Use C11 thread-local storage, where possible: */
+# define PERL_USE_THREAD_LOCAL
+extern PERL_THREAD_LOCAL void *PL_current_context;
+
+# define PERL_GET_CONTEXT PL_current_context
+
+/* Set our thread-specific value anyway, in case code is reading it directly. */
+# define PERL_SET_CONTEXT(t) \
+ STMT_START { \
+ int _eC_; \
+ if ((_eC_ = pthread_setspecific(PL_thr_key, PL_current_context = (void *)(t)))) \
+ Perl_croak_nocontext("panic: pthread_setspecific (%d) [%s:%d]", \
+ _eC_, __FILE__, __LINE__); \
+ } STMT_END
+
+#else
+/* else fall back to pthreads */
+
+# ifndef PERL_GET_CONTEXT
+# define PERL_GET_CONTEXT PTHREAD_GETSPECIFIC(PL_thr_key)
+# endif
-#ifndef PERL_SET_CONTEXT
-# define PERL_SET_CONTEXT(t) \
+# ifndef PERL_SET_CONTEXT
+# define PERL_SET_CONTEXT(t) \
STMT_START { \
int _eC_; \
if ((_eC_ = pthread_setspecific(PL_thr_key, (void *)(t)))) \
Perl_croak_nocontext("panic: pthread_setspecific (%d) [%s:%d]", \
_eC_, __FILE__, __LINE__); \
} STMT_END
-#endif /* PERL_SET_CONTEXT */
+# endif /* PERL_SET_CONTEXT */
+#endif /* PERL_THREAD_LOCAL */
#ifndef INIT_THREADS
# ifdef NEED_PTHREAD_INIT