mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
Use TLS when available for `SCM_I_CURRENT_THREAD'.
* acinclude.m4 (GUILE_THREAD_LOCAL_STORAGE): New macro. * configure.ac: Use it. * libguile/__scm.h (SCM_THREAD_LOCAL): New macro. * libguile/gen-scmconfig.c (main): Define `SCM_HAVE_THREAD_STORAGE_CLASS'. * libguile/gen-scmconfig.h.in (SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS): New. * libguile/threads.c (scm_i_current_thread)[SCM_HAVE_THREAD_STORAGE_CLASS]: New. (SET_CURRENT_THREAD): New macro. (guilify_self_1, on_thread_exit, init_thread_key): Use it. * libguile/threads.h (scm_i_current_thread)[SCM_HAVE_THREAD_STORAGE_CLASS]: New declaration. (SCM_I_CURRENT_THREAD)[SCM_HAVE_THREAD_STORAGE_CLASS]: New macro. (init_thread_key_once, init_thread_key): Conditionalize on `!defined SCM_HAVE_THREAD_STORAGE_CLASS'. (scm_i_init_thread_for_guile): Update accordingly.
This commit is contained in:
parent
46935a1fac
commit
705edb959b
7 changed files with 80 additions and 7 deletions
20
acinclude.m4
20
acinclude.m4
|
@ -335,6 +335,26 @@ AC_DEFUN([GUILE_GNU_LD_RELRO], [
|
|||
AC_SUBST([GNU_LD_FLAGS])
|
||||
])
|
||||
|
||||
dnl GUILE_THREAD_LOCAL_STORAGE
|
||||
dnl
|
||||
dnl Check for compiler thread-local storage (TLS) support.
|
||||
AC_DEFUN([GUILE_THREAD_LOCAL_STORAGE], [
|
||||
AC_CACHE_CHECK([whether the `__thread' storage class is available],
|
||||
[ac_cv_have_thread_storage_class],
|
||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([__thread int tls_integer;],
|
||||
[tls_integer = 123;])],
|
||||
[ac_cv_have_thread_storage_class="yes"],
|
||||
[ac_cv_have_thread_storage_class="no"])])
|
||||
|
||||
if test "x$ac_cv_have_thread_storage_class" = "xyes"; then
|
||||
SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS=1
|
||||
else
|
||||
SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS=0
|
||||
fi
|
||||
|
||||
AC_SUBST([SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS])
|
||||
])
|
||||
|
||||
dnl GUILE_READLINE
|
||||
dnl
|
||||
dnl Check all the things needed by `guile-readline', the Readline
|
||||
|
|
|
@ -1380,6 +1380,8 @@ AC_DEFINE(PTHREAD_ATTR_GETSTACK_WORKS, [1], [Define when pthread_att_get_stack w
|
|||
CFLAGS="$old_CFLAGS"
|
||||
AC_MSG_RESULT($works)
|
||||
|
||||
GUILE_THREAD_LOCAL_STORAGE
|
||||
|
||||
fi # with_threads=pthreads
|
||||
|
||||
|
||||
|
|
|
@ -679,6 +679,14 @@ SCM_API SCM scm_apply_generic (SCM gf, SCM args);
|
|||
#define SCM_C_INLINE_KEYWORD
|
||||
#endif
|
||||
|
||||
/* Handling thread-local storage (TLS). */
|
||||
|
||||
#ifdef SCM_HAVE_THREAD_STORAGE_CLASS
|
||||
# define SCM_THREAD_LOCAL __thread
|
||||
#else
|
||||
# define SCM_THREAD_LOCAL
|
||||
#endif
|
||||
|
||||
#endif /* SCM___SCM_H */
|
||||
|
||||
/*
|
||||
|
|
|
@ -404,6 +404,13 @@ main (int argc, char *argv[])
|
|||
pf ("typedef long int scm_t_off;\n");
|
||||
#endif
|
||||
|
||||
pf ("/* Define to 1 if the compiler supports the "
|
||||
"`__thread' storage class. */\n");
|
||||
if (SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS)
|
||||
pf ("#define SCM_HAVE_THREAD_STORAGE_CLASS\n");
|
||||
else
|
||||
pf ("/* #undef SCM_HAVE_THREAD_STORAGE_CLASS */\n");
|
||||
|
||||
#if USE_DLL_IMPORT
|
||||
pf ("\n");
|
||||
pf ("/* Define some additional CPP macros on Win32 platforms. */\n");
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#define SCM_I_GSC_USE_NULL_THREADS @SCM_I_GSC_USE_NULL_THREADS@
|
||||
#define SCM_I_GSC_NEED_BRACES_ON_PTHREAD_ONCE_INIT @SCM_I_GSC_NEED_BRACES_ON_PTHREAD_ONCE_INIT@
|
||||
#define SCM_I_GSC_NEED_BRACES_ON_PTHREAD_MUTEX_INITIALIZER @SCM_I_GSC_NEED_BRACES_ON_PTHREAD_MUTEX_INITIALIZER@
|
||||
#define SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS @SCM_I_GSC_HAVE_THREAD_STORAGE_CLASS@
|
||||
#define SCM_I_GSC_HAVE_STRUCT_DIRENT64 @SCM_I_GSC_HAVE_STRUCT_DIRENT64@
|
||||
|
||||
/*
|
||||
|
|
|
@ -290,8 +290,27 @@ unblock_from_queue (SCM queue)
|
|||
/* Getting into and out of guile mode.
|
||||
*/
|
||||
|
||||
#ifdef SCM_HAVE_THREAD_STORAGE_CLASS
|
||||
|
||||
/* When thread-local storage (TLS) is available, a pointer to the
|
||||
current-thread object is kept in TLS. Note that storing the thread-object
|
||||
itself in TLS (rather than a pointer to some malloc'd memory) is not
|
||||
possible since thread objects may live longer than the actual thread they
|
||||
represent. */
|
||||
SCM_THREAD_LOCAL scm_i_thread *scm_i_current_thread = NULL;
|
||||
|
||||
# define SET_CURRENT_THREAD(_t) scm_i_current_thread = (_t)
|
||||
|
||||
#else /* !SCM_HAVE_THREAD_STORAGE_CLASS */
|
||||
|
||||
/* Key used to retrieve the current thread with `pthread_getspecific ()'. */
|
||||
scm_i_pthread_key_t scm_i_thread_key;
|
||||
|
||||
# define SET_CURRENT_THREAD(_t) \
|
||||
scm_i_pthread_setspecific (scm_i_thread_key, (_t))
|
||||
|
||||
#endif /* !SCM_HAVE_THREAD_STORAGE_CLASS */
|
||||
|
||||
|
||||
static scm_i_pthread_mutex_t thread_admin_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
||||
static scm_i_thread *all_threads = NULL;
|
||||
|
@ -357,7 +376,7 @@ guilify_self_1 (SCM_STACKITEM *base)
|
|||
t->exited = 0;
|
||||
t->guile_mode = 0;
|
||||
|
||||
scm_i_pthread_setspecific (scm_i_thread_key, t);
|
||||
SET_CURRENT_THREAD (t);
|
||||
|
||||
scm_i_pthread_mutex_lock (&thread_admin_mutex);
|
||||
t->next_thread = all_threads;
|
||||
|
@ -475,7 +494,7 @@ on_thread_exit (void *v)
|
|||
t->held_mutex = NULL;
|
||||
}
|
||||
|
||||
scm_i_pthread_setspecific (scm_i_thread_key, v);
|
||||
SET_CURRENT_THREAD (v);
|
||||
|
||||
/* Ensure the signal handling thread has been launched, because we might be
|
||||
shutting it down. */
|
||||
|
@ -514,9 +533,11 @@ on_thread_exit (void *v)
|
|||
|
||||
scm_i_pthread_mutex_unlock (&thread_admin_mutex);
|
||||
|
||||
scm_i_pthread_setspecific (scm_i_thread_key, NULL);
|
||||
SET_CURRENT_THREAD (NULL);
|
||||
}
|
||||
|
||||
#ifndef SCM_HAVE_THREAD_STORAGE_CLASS
|
||||
|
||||
static scm_i_pthread_once_t init_thread_key_once = SCM_I_PTHREAD_ONCE_INIT;
|
||||
|
||||
static void
|
||||
|
@ -525,6 +546,8 @@ init_thread_key (void)
|
|||
scm_i_pthread_key_create (&scm_i_thread_key, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Perform any initializations necessary to bring the current thread
|
||||
into guile mode, initializing Guile itself, if necessary.
|
||||
|
||||
|
@ -542,9 +565,12 @@ scm_i_init_thread_for_guile (SCM_STACKITEM *base, SCM parent)
|
|||
{
|
||||
scm_i_thread *t;
|
||||
|
||||
#ifndef SCM_HAVE_THREAD_STORAGE_CLASS
|
||||
scm_i_pthread_once (&init_thread_key_once, init_thread_key);
|
||||
#endif
|
||||
|
||||
if ((t = SCM_I_CURRENT_THREAD) == NULL)
|
||||
t = SCM_I_CURRENT_THREAD;
|
||||
if (t == NULL)
|
||||
{
|
||||
/* This thread has not been guilified yet.
|
||||
*/
|
||||
|
|
|
@ -194,9 +194,18 @@ SCM_API void scm_dynwind_critical_section (SCM mutex);
|
|||
|
||||
#ifdef BUILDING_LIBGUILE
|
||||
|
||||
# define SCM_I_CURRENT_THREAD \
|
||||
((scm_i_thread *) scm_i_pthread_getspecific (scm_i_thread_key))
|
||||
SCM_API scm_i_pthread_key_t scm_i_thread_key;
|
||||
# ifdef SCM_HAVE_THREAD_STORAGE_CLASS
|
||||
|
||||
SCM_INTERNAL SCM_THREAD_LOCAL scm_i_thread *scm_i_current_thread;
|
||||
# define SCM_I_CURRENT_THREAD (scm_i_current_thread)
|
||||
|
||||
# else /* !SCM_HAVE_THREAD_STORAGE_CLASS */
|
||||
|
||||
SCM_INTERNAL scm_i_pthread_key_t scm_i_thread_key;
|
||||
# define SCM_I_CURRENT_THREAD \
|
||||
((scm_i_thread *) scm_i_pthread_getspecific (scm_i_thread_key))
|
||||
|
||||
# endif /* !SCM_HAVE_THREAD_STORAGE_CLASS */
|
||||
|
||||
# define scm_i_dynwinds() (SCM_I_CURRENT_THREAD->dynwinds)
|
||||
# define scm_i_set_dynwinds(w) (SCM_I_CURRENT_THREAD->dynwinds = (w))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue