[m-rev.] for review: thread-local storage
Peter Wang
wangp at students.cs.mu.OZ.AU
Mon Jul 3 18:00:11 AEST 2006
On saturn, for a program sitting in a tight loop only, asm_jump.par.gc
is ~6 times faster after this patch. asm_jump.gc is still ~1.4 times
faster than that.
Estimated hours taken: 5
Branches: main
When possible, make use of the gcc `__thread' extension for introducing
thread-local variables. Currently we use the POSIX thread facility for storing
the address of the Mercury engine that is running on the current thread, i.e.
pthread_getspecific/pthread_setspecific. If gcc global registers are not
used, then each access of a Mercury register incurs a call to
`pthread_getspecific'. Using the `__thread' extension is very much faster.
(If gcc global registers are used then the address of the Mercury engine is
kept in a hardward register.)
configure.in:
Check if compiler has the `__thread' extension.
runtime/mercury_conf.h.in:
#define MR_TLS if `__thread' can be used.
runtime/mercury_context.c:
runtime/mercury_engine.h:
runtime/mercury_thread.c:
Make `MR_thread_engine_base' a thread-local variable if possible,
instead of using pthread_getspecific().
#define MR_set_thread_engine_base() to hide the differences between
when `__thread' is used or not.
Index: configure.in
===================================================================
RCS file: /home/mercury1/repository/mercury/configure.in,v
retrieving revision 1.455
diff -u -r1.455 configure.in
--- configure.in 28 Jun 2006 08:14:18 -0000 1.455
+++ configure.in 3 Jul 2006 07:37:02 -0000
@@ -2569,6 +2569,22 @@
#-----------------------------------------------------------------------------#
+AC_MSG_CHECKING(whether we can use thread-local storage class extension)
+AC_CACHE_VAL(mercury_cv_tls,
+ AC_TRY_COMPILE([],[
+ static __thread int thread_local_variable;
+ ],
+ [mercury_cv_tls=yes],
+ [mercury_cv_tls=no])
+)
+AC_MSG_RESULT($mercury_cv_tls)
+
+if test "$mercury_cv_tls" = yes; then
+ AC_DEFINE(MR_TLS)
+fi
+
+#-----------------------------------------------------------------------------#
+
#
# Figure out which is the best grade to use for various different purposes.
# In particular, choose the default grade for compiling applications.
Index: runtime/mercury_conf.h.in
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf.h.in,v
retrieving revision 1.54
diff -u -r1.54 mercury_conf.h.in
--- runtime/mercury_conf.h.in 28 Jun 2006 04:46:21 -0000 1.54
+++ runtime/mercury_conf.h.in 3 Jul 2006 06:23:00 -0000
@@ -358,8 +358,11 @@
** Digital Unix doesn't conform to the letter of the Posix standard
** for Pthreads.
**
+** MR_TLS is defined if the thread-local storage extension is supported.
+** That is, the compiler extends the C language with the `__thread' specifier.
*/
#undef MR_DIGITAL_UNIX_PTHREADS
+#undef MR_TLS
/*
** The bytecode files represent floats in 64-bit IEEE format.
Index: runtime/mercury_context.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_context.c,v
retrieving revision 1.45
diff -u -r1.45 mercury_context.c
--- runtime/mercury_context.c 29 Jun 2006 03:53:34 -0000 1.45
+++ runtime/mercury_context.c 3 Jul 2006 06:23:00 -0000
@@ -69,7 +69,9 @@
pthread_mutex_init(&free_context_list_lock, MR_MUTEX_ATTR);
pthread_mutex_init(&MR_global_lock, MR_MUTEX_ATTR);
pthread_mutex_init(&MR_pending_contexts_lock, MR_MUTEX_ATTR);
+ #ifndef MR_TLS
MR_KEY_CREATE(&MR_engine_base_key, NULL);
+ #endif
MR_KEY_CREATE(&MR_exception_handler_key, NULL);
#endif
Index: runtime/mercury_engine.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_engine.h,v
retrieving revision 1.38
diff -u -r1.38 mercury_engine.h
--- runtime/mercury_engine.h 30 Mar 2006 06:55:59 -0000 1.38
+++ runtime/mercury_engine.h 3 Jul 2006 06:19:03 -0000
@@ -400,10 +400,20 @@
#ifdef MR_THREAD_SAFE
- extern MercuryThreadKey MR_engine_base_key;
+ #ifdef MR_TLS
+ extern __thread MercuryEngine *MR_thread_engine_base;
- #define MR_thread_engine_base \
- ((MercuryEngine *) MR_GETSPECIFIC(MR_engine_base_key))
+ #define MR_set_thread_engine_base(eng) \
+ do { MR_thread_engine_base = eng; } while (0)
+ #else
+ extern MercuryThreadKey MR_engine_base_key;
+
+ #define MR_thread_engine_base \
+ ((MercuryEngine *) MR_GETSPECIFIC(MR_engine_base_key))
+
+ #define MR_set_thread_engine_base(eng) \
+ pthread_setspecific(MR_engine_base_key, eng)
+ #endif
#if MR_NUM_REAL_REGS > 0
#define MR_ENGINE_BASE_REGISTER
Index: runtime/mercury_thread.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_thread.c,v
retrieving revision 1.23
diff -u -r1.23 mercury_thread.c
--- runtime/mercury_thread.c 16 Sep 2005 16:43:55 -0000 1.23
+++ runtime/mercury_thread.c 3 Jul 2006 06:13:51 -0000
@@ -19,7 +19,11 @@
#ifdef MR_THREAD_SAFE
MercuryThreadKey MR_exception_handler_key;
- MercuryThreadKey MR_engine_base_key;
+ #ifdef MR_TLS
+ __thread MercuryEngine *MR_thread_engine_base;
+ #else
+ MercuryThreadKey MR_engine_base_key;
+ #endif
MercuryLock MR_global_lock;
#endif
@@ -80,14 +84,14 @@
** Check to see whether there is already an engine that is initialized
** in this thread. If so we just return, there's nothing for us to do.
*/
- if (MR_GETSPECIFIC(MR_engine_base_key)) {
+ if (MR_thread_engine_base != NULL) {
return MR_FALSE;
}
#endif
eng = MR_create_engine();
#ifdef MR_THREAD_SAFE
- pthread_setspecific(MR_engine_base_key, eng);
+ MR_set_thread_engine_base(eng);
MR_restore_registers();
#ifdef MR_ENGINE_BASE_REGISTER
MR_engine_base_word = (MR_Word) eng;
@@ -133,8 +137,8 @@
#ifdef MR_THREAD_SAFE
MercuryEngine *eng;
- eng = MR_GETSPECIFIC(MR_engine_base_key);
- pthread_setspecific(MR_engine_base_key, NULL);
+ eng = MR_thread_engine_base;
+ MR_set_thread_engine_base(NULL);
/*
** XXX calling destroy_engine(eng) here appears to segfault.
** This should probably be investigated and fixed.
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list