[PATCH libX11] config: Add an option to initialize threads by default.
Rami Ylimäki
rami.ylimaki at vincit.fi
Mon Jan 31 02:46:56 PST 2011
It's sometimes impossible to know in advance whether an X client is
using Xlib from multiple threads or not. For example, there could be
some generic X client that acts as a plugin container. Plugins could
be loaded to the container at runtime, but the container doesn't know
whether the plugins are using Xlib from a separate thread or not.
This change makes it possible to guard a system against a missing
XInitThreads call in X clients. One might argue that this is a client
problem and that all X clients should call XInitThreads if it's
possible that they could use Xlib from multiple threads. However,
experience has shown that it's just too easy for developers to
overlook the need for this call.
Enabling thread safety by default causes a performance regression,
because even single threaded applications would start to lock data
structures. However, the performance regression is only noticeable in
a theoretical worst case situation. In realistic use cases the
overhead from unnecessary locking can't be seen. Relative x11perf
results showing the amount of regression for worst case and some
common operations are shown below.
enabled disabled Operation
------- -------- ---------
1.00 1.00 Copy 10x10 from window to window
1.00 1.00 Copy 500x500 from window to window
1.00 2.68 X protocol NoOperation
Signed-off-by: Rami Ylimäki <rami.ylimaki at vincit.fi>
---
configure.ac | 36 ++++++++++++++++++++++++++++++++++++
src/locking.c | 10 ++++++++++
2 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/configure.ac b/configure.ac
index 40d032d..27ed595 100644
--- a/configure.ac
+++ b/configure.ac
@@ -270,6 +270,37 @@ AC_ARG_ENABLE(xthreads,
[Disable Xlib support for Multithreading]),
[xthreads=$enableval],[xthreads=yes])
+dnl Check if the user wants XInitThreads to be called by default on
+dnl library initialization.
+AC_ARG_ENABLE(
+ init_xthreads,
+ AC_HELP_STRING(
+ [--enable-init-xthreads],
+ [Call XInitThreads on library initialization]),
+ [init_xthreads=$enableval],
+ [init_xthreads=no])
+
+dnl Check if XInitThreads can be called by default on library
+dnl initialization. The following conditions must be true for that.
+dnl
+dnl - Option --enable-xthreads is given.
+dnl - Option --enable-init-xthreads is given.
+dnl - Compiler is GCC.
+dnl - GCC supports library contructors.
+if test "x$xthreads" = xyes && test "x$init_xthreads" = xyes && test "x$GCC" = xyes ; then
+ dnl Set warnings as errors so that GCC fails if the attribute is
+ dnl not supported.
+ old_CFLAGS="$CFLAGS"
+ CFLAGS="-Werror"
+ dnl Check if GCC recognizes constructor attribute.
+ AC_COMPILE_IFELSE(
+ [ void __attribute__((constructor)) test(void) {}; ],
+ init_xthreads=yes,
+ init_xthreads=no)
+ dnl Restore flags.
+ CFLAGS="$old_CFLAGS"
+fi
+
AC_CHECK_LIB(c, getpwuid_r, [mtsafeapi="yes"], [mtsafeapi="no"])
case x$xthreads in
@@ -279,6 +310,10 @@ xyes)
then
AC_DEFINE(XUSE_MTSAFE_API,1,[Whether libX11 needs to use MT safe API's])
fi
+ if test x$init_xthreads = xyes
+ then
+ AC_DEFINE(INIT_XTHREADS,1,[Whether XInitThreads is called on library initialization])
+ fi
;;
*)
;;
@@ -480,6 +515,7 @@ echo " Loadable xcursor library support: "$XLIB_LOADABLE_XCURSOR
echo " Threading support: "$xthreads
echo " Use Threads safe API: "$mtsafeapi
echo " Threads stubs in libX11: "$thrstubs
+echo " Threads initialized by default: "$init_xthreads
echo " XCMS: "$XCMS
echo " Internationalization support: "$XLOCALE
echo " XF86BigFont support: "$XF86BIGFONT
diff --git a/src/locking.c b/src/locking.c
index 4f9a40f..7673a20 100644
--- a/src/locking.c
+++ b/src/locking.c
@@ -615,6 +615,16 @@ Status XInitThreads(void)
return 1;
}
+#ifdef INIT_XTHREADS
+
+/** Initialize threads by default when Xlib is loaded. */
+static void __attribute__((constructor)) XInitLib(void)
+{
+ if (!XInitThreads())
+ exit(1);
+}
+
+#endif /* INIT_XTHREADS*/
#else /* XTHREADS */
Status XInitThreads(void)
{
--
1.6.3.3
More information about the xorg-devel
mailing list