Skip to content

Commit

Permalink
If we have thread local storage, use it instead of posix_getspecific().
Browse files Browse the repository at this point in the history
Declare and use a variable PL_current_context to store a pointer to the
thread's interpreter struct. Use this to implement implicit context undef
ITHREADS, instead of a call to posix_getspecific().

For normal threaded code, this will eliminate function calls. For threaded
code in shared objects (the typical configuration for Linux distribution
builds) there still needs to be a function call to get the pointer to
thread local variables, but there will only be one per function, not one
per read of the variable.
  • Loading branch information
nwc10 authored and tonycoz committed Sep 7, 2021
1 parent 65f7068 commit 3683a9e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 6 deletions.
8 changes: 8 additions & 0 deletions globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions makedef.pl
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ BEGIN
# 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};
Expand Down
32 changes: 26 additions & 6 deletions thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 3683a9e

Please sign in to comment.