From 0bd0e21c22bee43a24f61fbb29123081d71138f4 Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Thu, 13 Jun 2019 17:47:26 +0200
Subject: [PATCH] WIP _Thread_local

---
 include/runetype.h                       |  2 +-
 lib/libc/gen/errlst.c                    |  2 +-
 lib/libc/gen/tls.c                       | 12 ------------
 lib/libc/locale/setrunelocale.c          |  2 +-
 lib/libc/locale/xlocale.c                |  2 +-
 lib/libc/locale/xlocale_private.h        |  2 +-
 lib/libc/stdlib/cxa_thread_atexit_impl.c |  2 +-
 lib/libc/stdlib/dmalloc.c                |  4 ++--
 lib/libc/stdlib/nmalloc.c                |  4 ++--
 lib/libc/sys/intro.2                     |  4 ++--
 lib/libthread_xu/thread/thr_sem.c        |  4 ++--
 sys/sys/cdefs.h                          | 13 +++++++++++++
 sys/sys/errno.h                          |  2 +-
 test/sysperf/blib.c                      |  8 +++-----
 14 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/include/runetype.h b/include/runetype.h
index e18687fba4..d1ce8229c0 100644
--- a/include/runetype.h
+++ b/include/runetype.h
@@ -89,7 +89,7 @@ extern const _RuneLocale *_CurrentRuneLocale;
 #if defined(__NO_TLS) || defined(__RUNETYPE_INTERNAL)
 extern const _RuneLocale *__getCurrentRuneLocale(void);
 #else
-extern __thread const _RuneLocale *_ThreadRuneLocale;
+extern _Thread_local const _RuneLocale *_ThreadRuneLocale;
 static __inline const _RuneLocale *__getCurrentRuneLocale(void)
 {
 
diff --git a/lib/libc/gen/errlst.c b/lib/libc/gen/errlst.c
index 32e1db9fbd..1bf2a2b71c 100644
--- a/lib/libc/gen/errlst.c
+++ b/lib/libc/gen/errlst.c
@@ -149,5 +149,5 @@ const char *const sys_errlist[] = {
 	"Protocol error",			/* 92 - EPROTO */
 	"No medium found",			/* 93 - ENOMEDIUM */
 };
-__thread int errno;
+_Thread_local int errno;
 const int sys_nerr = sizeof(sys_errlist) / sizeof(sys_errlist[0]);
diff --git a/lib/libc/gen/tls.c b/lib/libc/gen/tls.c
index 449c2273dc..053c21f8ea 100644
--- a/lib/libc/gen/tls.c
+++ b/lib/libc/gen/tls.c
@@ -267,18 +267,6 @@ _libc_allocate_tls(void)
 
 	tcb = _rtld_allocate_tls();
 
-#if 0
-#if defined(__thread)
-	/* non-TLS libc */
-	tcb->tcb_errno_p = &errno;
-#elif defined(PIC)
-	/* TLS libc dynamically linked */
-	tcb->tcb_errno_p = __tls_get_addr_tcb(tcb, __get_errno_GOT_ptr());
-#else
-	/* TLS libc (threaded or unthreaded) */
-	tcb->tcb_errno_p = (void *)((char *)tcb + __get_errno_GS_offset());
-#endif
-#endif
 	return(tcb);
 }
 
diff --git a/lib/libc/locale/setrunelocale.c b/lib/libc/locale/setrunelocale.c
index ece10102ec..27125753f0 100644
--- a/lib/libc/locale/setrunelocale.c
+++ b/lib/libc/locale/setrunelocale.c
@@ -58,7 +58,7 @@ extern _RuneLocale const *_CurrentRuneLocale;
 /*
  * A cached version of the runes for this thread.  Used by ctype.h
  */
-__thread const _RuneLocale *_ThreadRuneLocale;
+_Thread_local const _RuneLocale *_ThreadRuneLocale;
 #endif
 
 extern int __mb_sb_limit;
diff --git a/lib/libc/locale/xlocale.c b/lib/libc/locale/xlocale.c
index fb607b4771..0ef3261ccf 100644
--- a/lib/libc/locale/xlocale.c
+++ b/lib/libc/locale/xlocale.c
@@ -58,7 +58,7 @@ extern struct xlocale_component __xlocale_C_ctype;
 /*
  * The locale for this thread.
  */
-__thread locale_t __thread_locale;
+_Thread_local locale_t __thread_locale;
 #endif
 /*
  * Flag indicating that one or more per-thread locales exist.
diff --git a/lib/libc/locale/xlocale_private.h b/lib/libc/locale/xlocale_private.h
index c805c4381f..674e441067 100644
--- a/lib/libc/locale/xlocale_private.h
+++ b/lib/libc/locale/xlocale_private.h
@@ -211,7 +211,7 @@ extern int __has_thread_locale;
  * The per-thread locale.  Avoids the need to use pthread lookup functions when
  * getting the per-thread locale.
  */
-extern __thread locale_t __thread_locale;
+extern _Thread_local locale_t __thread_locale;
 
 /**
  * Returns the current locale for this thread, or the global locale if none is
diff --git a/lib/libc/stdlib/cxa_thread_atexit_impl.c b/lib/libc/stdlib/cxa_thread_atexit_impl.c
index c0bcb68836..8243977aba 100644
--- a/lib/libc/stdlib/cxa_thread_atexit_impl.c
+++ b/lib/libc/stdlib/cxa_thread_atexit_impl.c
@@ -43,7 +43,7 @@ struct thread_dtorfn {
 	void *dso;
 	LIST_ENTRY(thread_dtorfn) entry;
 };
-static __thread LIST_HEAD(dtor_list, thread_dtorfn) dtors =
+static _Thread_local LIST_HEAD(dtor_list, thread_dtorfn) dtors =
     LIST_HEAD_INITIALIZER(dtors);
 
 int __cxa_thread_atexit_impl(void (*func)(void *), void *arg, void *dso);
diff --git a/lib/libc/stdlib/dmalloc.c b/lib/libc/stdlib/dmalloc.c
index 983de72801..2a7406bee5 100644
--- a/lib/libc/stdlib/dmalloc.c
+++ b/lib/libc/stdlib/dmalloc.c
@@ -295,7 +295,7 @@ struct slglobaldata {
  * With this attribute set, do not require a function call for accessing
  * this variable when the code is compiled -fPIC.
  *
- * Must be empty for libc_rtld (similar to __thread)
+ * Must be empty for libc_rtld (similar to _Thread_local)
  */
 #if defined(__LIBC_RTLD)
 #define TLS_ATTRIBUTE
@@ -303,7 +303,7 @@ struct slglobaldata {
 #define TLS_ATTRIBUTE __attribute__ ((tls_model ("initial-exec")));
 #endif
 
-static __thread struct slglobaldata slglobal TLS_ATTRIBUTE;
+static _Thread_local struct slglobaldata slglobal TLS_ATTRIBUTE;
 static pthread_key_t thread_malloc_key;
 static pthread_once_t thread_malloc_once = PTHREAD_ONCE_INIT;
 static struct slglobaldata slglobaldepot;
diff --git a/lib/libc/stdlib/nmalloc.c b/lib/libc/stdlib/nmalloc.c
index 886da289c4..62e39ccf02 100644
--- a/lib/libc/stdlib/nmalloc.c
+++ b/lib/libc/stdlib/nmalloc.c
@@ -322,7 +322,7 @@ typedef struct thr_mags {
  * With this attribute set, do not require a function call for accessing
  * this variable when the code is compiled -fPIC.
  *
- * Must be empty for libc_rtld (similar to __thread).
+ * Must be empty for libc_rtld (similar to _Thread_local).
  */
 #ifdef __LIBC_RTLD
 #define TLS_ATTRIBUTE
@@ -330,7 +330,7 @@ typedef struct thr_mags {
 #define TLS_ATTRIBUTE __attribute__ ((tls_model ("initial-exec")))
 #endif
 
-static __thread thr_mags thread_mags TLS_ATTRIBUTE;
+static _Thread_local thr_mags thread_mags TLS_ATTRIBUTE;
 static pthread_key_t thread_mags_key;
 static pthread_once_t thread_mags_once = PTHREAD_ONCE_INIT;
 static magazine_depot depots[NZONES];
diff --git a/lib/libc/sys/intro.2 b/lib/libc/sys/intro.2
index d93efb3e9d..92c19c232b 100644
--- a/lib/libc/sys/intro.2
+++ b/lib/libc/sys/intro.2
@@ -53,8 +53,8 @@ This identifier is defined in
 .In errno.h
 as
 .Pp
-.Dl extern __thread int      errno;
-.Dl static __inline int    * __error(void);
+.Dl extern _Thread_local int      errno;
+.Dl static __inline      int    * __error(void);
 .Dl #define   errno       (* __error())
 .Pp
 This means there exists a thread-local
diff --git a/lib/libthread_xu/thread/thr_sem.c b/lib/libthread_xu/thread/thr_sem.c
index 7cba20208e..6736a87400 100644
--- a/lib/libthread_xu/thread/thr_sem.c
+++ b/lib/libthread_xu/thread/thr_sem.c
@@ -189,8 +189,8 @@ sem_alloc(unsigned int value, int pshared)
 		return (NULL);
 	}
 	if (pshared) {
-		static __thread sem_t sem_base;
-		static __thread int sem_count;
+		static _Thread_local sem_t sem_base;
+		static _Thread_local int sem_count;
 
 		if (sem_base == NULL) {
 			sem_base = mmap(NULL, getpagesize(),
diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h
index 7d0f417340..e71834a0b5 100644
--- a/sys/sys/cdefs.h
+++ b/sys/sys/cdefs.h
@@ -514,6 +514,19 @@
 #define	__CTASSERT(x, y)	typedef char __assert ## y[(x) ? 1 : -1]
 #endif
 #endif
+
+/*
+ * GCC 4.7 has -std=c++11 but does not support thread_local.
+ */
+#if !__has_extension(c_thread_local)
+#if (defined(__cplusplus) && __cplusplus >= 201103L && __GNUC_PREREQ__(4, 8)) || \
+    __has_extension(cxx_thread_local)
+#define	_Thread_local		thread_local
+#else
+#define	_Thread_local		__thread
+#endif
+#endif
+
 #endif
 
 #endif /* __STDC_VERSION__ || __STDC_VERSION__ < 201112L */
diff --git a/sys/sys/errno.h b/sys/sys/errno.h
index 657e5ec267..17d60368b4 100644
--- a/sys/sys/errno.h
+++ b/sys/sys/errno.h
@@ -42,7 +42,7 @@
 
 #if !defined(_KERNEL) || defined(_KERNEL_VIRTUAL)
 __BEGIN_DECLS
-extern __thread int	errno;
+extern _Thread_local int	errno;
 __END_DECLS
 
 static __inline int *__error(void)
diff --git a/test/sysperf/blib.c b/test/sysperf/blib.c
index a1f48b9c7c..dc438656c6 100644
--- a/test/sysperf/blib.c
+++ b/test/sysperf/blib.c
@@ -2,8 +2,6 @@
  * BLIB.C
  *
  * Simple benchmarking library
- *
- * $DragonFly: src/test/sysperf/blib.c,v 1.6 2007/08/21 19:23:46 corecode Exp $
  */
 
 #include <sys/types.h>
@@ -12,9 +10,9 @@
 #include <stdlib.h>
 #include <stdarg.h>
 
-static __thread struct timeval tv1;
-static __thread struct timeval tv2;
-static __thread long long last_us;
+static _Thread_local struct timeval tv1;
+static _Thread_local struct timeval tv2;
+static _Thread_local long long last_us;
 
 void
 start_timing(void)
-- 
2.21.0

