1
Fork 0
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:
Ludovic Courtès 2009-10-02 16:32:34 +02:00
parent 46935a1fac
commit 705edb959b
7 changed files with 80 additions and 7 deletions

View file

@ -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

View file

@ -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

View file

@ -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 */
/*

View file

@ -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");

View file

@ -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@
/*

View file

@ -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.
*/

View file

@ -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))