mirror of
git://slackware.nl/current.git
synced 2024-12-28 09:59:53 +01:00
d31c50870d
Thu Jun 30 20:26:57 UTC 2016 Slackware 14.2 x86_64 stable is released! The long development cycle (the Linux community has lately been living in "interesting times", as they say) is finally behind us, and we're proud to announce the release of Slackware 14.2. The new release brings many updates and modern tools, has switched from udev to eudev (no systemd), and adds well over a hundred new packages to the system. Thanks to the team, the upstream developers, the dedicated Slackware community, and everyone else who pitched in to help make this release a reality. The ISOs are off to be replicated, a 6 CD-ROM 32-bit set and a dual-sided 32-bit/64-bit x86/x86_64 DVD. Please consider supporting the Slackware project by picking up a copy from store.slackware.com. We're taking pre-orders now, and offer a discount if you sign up for a subscription. Have fun! :-)
127 lines
4.5 KiB
Diff
127 lines
4.5 KiB
Diff
diff --git c/include/private/gc_priv.h w/include/private/gc_priv.h
|
|
index 0ad92fc..b877fac 100644
|
|
--- c/include/private/gc_priv.h
|
|
+++ w/include/private/gc_priv.h
|
|
@@ -2368,6 +2368,7 @@ GC_INNER ptr_t GC_store_debug_info(ptr_t p, word sz, const char *str,
|
|
/* GC_notify_all_builder() is called when GC_fl_builder_count */
|
|
/* reaches 0. */
|
|
|
|
+ GC_INNER void GC_setup_mark_lock(void);
|
|
GC_INNER void GC_acquire_mark_lock(void);
|
|
GC_INNER void GC_release_mark_lock(void);
|
|
GC_INNER void GC_notify_all_builder(void);
|
|
diff --git c/include/private/gcconfig.h w/include/private/gcconfig.h
|
|
index c753cc2..b5ed075 100644
|
|
--- c/include/private/gcconfig.h
|
|
+++ w/include/private/gcconfig.h
|
|
@@ -1357,6 +1357,11 @@
|
|
# define PREFETCH_FOR_WRITE(x) \
|
|
__asm__ __volatile__ ("prefetchw %0" : : "m"(*(char *)(x)))
|
|
# endif
|
|
+# if defined(__GLIBC__)
|
|
+ /* Workaround lock elision implementation for some glibc. */
|
|
+# define GLIBC_2_19_TSX_BUG
|
|
+# include <gnu/libc-version.h> /* for gnu_get_libc_version() */
|
|
+# endif
|
|
# endif
|
|
# ifdef CYGWIN32
|
|
# define OS_TYPE "CYGWIN32"
|
|
@@ -2257,6 +2262,11 @@
|
|
/* FIXME: This seems to be fixed in GLibc v2.14. */
|
|
# define GETCONTEXT_FPU_EXCMASK_BUG
|
|
# endif
|
|
+# if defined(__GLIBC__)
|
|
+ /* Workaround lock elision implementation for some glibc. */
|
|
+# define GLIBC_2_19_TSX_BUG
|
|
+# include <gnu/libc-version.h> /* for gnu_get_libc_version() */
|
|
+# endif
|
|
# endif
|
|
# ifdef DARWIN
|
|
# define OS_TYPE "DARWIN"
|
|
diff --git c/include/private/pthread_support.h w/include/private/pthread_support.h
|
|
index 525a9aa..017f194 100644
|
|
--- c/include/private/pthread_support.h
|
|
+++ w/include/private/pthread_support.h
|
|
@@ -148,6 +148,8 @@ GC_INNER_PTHRSTART GC_thread GC_start_rtn_prepare_thread(
|
|
struct GC_stack_base *sb, void *arg);
|
|
GC_INNER_PTHRSTART void GC_thread_exit_proc(void *);
|
|
|
|
+GC_INNER void GC_setup_mark_lock(void);
|
|
+
|
|
#endif /* GC_PTHREADS && !GC_WIN32_THREADS */
|
|
|
|
#endif /* GC_PTHREAD_SUPPORT_H */
|
|
diff --git c/misc.c w/misc.c
|
|
index df434a1..3aca41d 100644
|
|
--- c/misc.c
|
|
+++ w/misc.c
|
|
@@ -875,6 +875,9 @@ GC_API void GC_CALL GC_init(void)
|
|
/* else */ InitializeCriticalSection (&GC_allocate_ml);
|
|
}
|
|
# endif /* GC_WIN32_THREADS */
|
|
+# if defined(GC_PTHREADS) && !defined(GC_WIN32_THREADS)
|
|
+ GC_setup_mark_lock();
|
|
+# endif /* GC_PTHREADS */
|
|
# if (defined(MSWIN32) || defined(MSWINCE)) && defined(THREADS)
|
|
InitializeCriticalSection(&GC_write_cs);
|
|
# endif
|
|
diff --git c/pthread_support.c w/pthread_support.c
|
|
index c00b93d..8a7c50b 100644
|
|
--- c/pthread_support.c
|
|
+++ w/pthread_support.c
|
|
@@ -1979,6 +1979,55 @@ GC_INNER void GC_lock(void)
|
|
|
|
static pthread_cond_t builder_cv = PTHREAD_COND_INITIALIZER;
|
|
|
|
+#ifdef GLIBC_2_19_TSX_BUG
|
|
+ /* Parse string like <major>[.<minor>[<tail>]] and return major value. */
|
|
+ static int parse_version(int *pminor, const char *pverstr) {
|
|
+ char *endp;
|
|
+ unsigned long value = strtoul(pverstr, &endp, 10);
|
|
+ int major = (int)value;
|
|
+
|
|
+ if (major < 0 || (char *)pverstr == endp || (unsigned)major != value) {
|
|
+ /* Parse error */
|
|
+ return -1;
|
|
+ }
|
|
+ if (*endp != '.') {
|
|
+ /* No minor part. */
|
|
+ *pminor = -1;
|
|
+ } else {
|
|
+ value = strtoul(endp + 1, &endp, 10);
|
|
+ *pminor = (int)value;
|
|
+ if (*pminor < 0 || (unsigned)(*pminor) != value) {
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+ return major;
|
|
+ }
|
|
+#endif /* GLIBC_2_19_TSX_BUG */
|
|
+
|
|
+GC_INNER void GC_setup_mark_lock(void)
|
|
+{
|
|
+# ifdef GLIBC_2_19_TSX_BUG
|
|
+ pthread_mutexattr_t mattr;
|
|
+ int glibc_minor = -1;
|
|
+ int glibc_major = parse_version(&glibc_minor, gnu_get_libc_version());
|
|
+
|
|
+ if (glibc_major > 2 || (glibc_major == 2 && glibc_minor >= 19)) {
|
|
+ /* TODO: disable this workaround for glibc with fixed TSX */
|
|
+ /* This disables lock elision to workaround a bug in glibc 2.19+ */
|
|
+ if (0 != pthread_mutexattr_init(&mattr)) {
|
|
+ ABORT("pthread_mutexattr_init failed");
|
|
+ }
|
|
+ if (0 != pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_NORMAL)) {
|
|
+ ABORT("pthread_mutexattr_settype failed");
|
|
+ }
|
|
+ if (0 != pthread_mutex_init(&mark_mutex, &mattr)) {
|
|
+ ABORT("pthread_mutex_init failed");
|
|
+ }
|
|
+ pthread_mutexattr_destroy(&mattr);
|
|
+ }
|
|
+# endif
|
|
+}
|
|
+
|
|
GC_INNER void GC_acquire_mark_lock(void)
|
|
{
|
|
GC_ASSERT(GC_mark_lock_holder != NUMERIC_THREAD_ID(pthread_self()));
|