From f0484f91b691b2c331f859e6f811422992c9ade3 Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Mon, 17 Jun 2019 10:16:03 +0200
Subject: [PATCH] <sys/cdefs.h>: Add a compatibility define for C11's
 _Thread_local keyword.

Also, use it whereever we were using the GNU extension __thread
previously.

This is a good thing because we will soon switch our -std to gnu11/c11
at least (maybe gnu18/c18), where this is a real C keyword. Also, stuff
in dports that parses C code, such as devel/gobject-introspection, does
not necessarily understand __thread and was behaving weirdly.

Based-on: FreeBSD's
---
 include/runetype.h                       |  2 +-
 lib/libc/gen/errlst.c                    |  2 +-
 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                |  6 +++---
 lib/libc/stdlib/nmalloc.c                |  6 +++---
 lib/libc/sys/intro.2                     |  8 ++++----
 lib/libc/x86_64/sys/cerror.S             |  4 ++--
 lib/libc_rtld/Makefile                   |  3 +--
 lib/libthread_xu/thread/thr_sem.c        |  4 ++--
 libexec/rtld-elf/Makefile                |  2 +-
 sys/sys/cdefs.h                          | 16 ++++++++++++++++
 sys/sys/errno.h                          |  2 +-
 test/sysperf/blib.c                      |  8 +++-----
 16 files changed, 42 insertions(+), 29 deletions(-)

diff --git a/include/runetype.h b/include/runetype.h
index 15498519fc..00df7c6841 100644
--- a/include/runetype.h
+++ b/include/runetype.h
@@ -91,7 +91,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/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 c20e5d6d22..85e7e67835 100644
--- a/lib/libc/locale/xlocale_private.h
+++ b/lib/libc/locale/xlocale_private.h
@@ -215,7 +215,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..cd6607f606 100644
--- a/lib/libc/stdlib/dmalloc.c
+++ b/lib/libc/stdlib/dmalloc.c
@@ -295,15 +295,15 @@ 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)
+#if defined(__RTLD)
 #define TLS_ATTRIBUTE
 #else
 #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 3608a750e8..a3297b7b6f 100644
--- a/lib/libc/stdlib/nmalloc.c
+++ b/lib/libc/stdlib/nmalloc.c
@@ -321,15 +321,15 @@ 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
+#ifdef __RTLD
 #define TLS_ATTRIBUTE
 #else
 #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..83dc7f1208 100644
--- a/lib/libc/sys/intro.2
+++ b/lib/libc/sys/intro.2
@@ -28,7 +28,7 @@
 .\"     @(#)intro.2	8.5 (Berkeley) 2/27/95
 .\" $FreeBSD: src/lib/libc/sys/intro.2,v 1.48 2007/01/09 00:28:14 imp Exp $
 .\"
-.Dd May 16, 2018
+.Dd June 17, 2019
 .Dt INTRO 2
 .Os
 .Sh NAME
@@ -53,9 +53,9 @@ This identifier is defined in
 .In errno.h
 as
 .Pp
-.Dl extern __thread int      errno;
-.Dl static __inline int    * __error(void);
-.Dl #define   errno       (* __error())
+.Dl "extern _Thread_local int      errno;"
+.Dl "static __inline int           *__error(void);"
+.Dl "#define errno                 (* __error())"
 .Pp
 This means there exists a thread-local
 .Va errno
diff --git a/lib/libc/x86_64/sys/cerror.S b/lib/libc/x86_64/sys/cerror.S
index b93d1f89dd..34e9ba37dc 100644
--- a/lib/libc/x86_64/sys/cerror.S
+++ b/lib/libc/x86_64/sys/cerror.S
@@ -42,14 +42,14 @@
 HIDENAME(cerror):
 	pushq	%rax
 #ifdef PIC
-#  ifdef __thread
+#  ifdef __RTLD
 	movq	PIC_GOT(CNAME(errno)),%rax
 #  else
 	leaq	errno@TLSGD(%rip),%rdi
 	call	__tls_get_addr@PLT
 #  endif
 #else
-#  ifdef __thread
+#  ifdef __RTLD
 	leaq	CNAME(errno)(%rip),%rax
 #  else
 	movq	errno@GOTTPOFF(%rip),%rax
diff --git a/lib/libc_rtld/Makefile b/lib/libc_rtld/Makefile
index 32fb36dd51..64d3efac79 100644
--- a/lib/libc_rtld/Makefile
+++ b/lib/libc_rtld/Makefile
@@ -9,8 +9,7 @@ CFLAGS+=-I${.CURDIR}/../libc/rpc
 CFLAGS+=-I${.CURDIR}/../../include
 CFLAGS+=-I${.CURDIR}/../libc/${MACHINE_ARCH}
 CFLAGS+=-I${.OBJDIR}
-CFLAGS+=-D__thread=
-CFLAGS+=-D__LIBC -D__LIBC_RTLD
+CFLAGS+=-D__LIBC -D__RTLD
 
 PRECIOUSLIB=	yes
 
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/libexec/rtld-elf/Makefile b/libexec/rtld-elf/Makefile
index 2254e09e3f..219ca49b9d 100644
--- a/libexec/rtld-elf/Makefile
+++ b/libexec/rtld-elf/Makefile
@@ -22,7 +22,7 @@ LDFLAGS+=	-flto
 .endif
 
 CFLAGS+=	-DIN_RTLD
-CFLAGS+=	-I${.CURDIR}/${MACHINE_ARCH} -I${.CURDIR} -D__thread=
+CFLAGS+=	-I${.CURDIR}/${MACHINE_ARCH} -I${.CURDIR} -D__RTLD
 CFLAGS+=	-I${.CURDIR}/../../lib/csu/common
 LDFLAGS+=	-nostdlib -Wl,-e.rtld_start,--no-undefined
 INSTALLFLAGS=	-C -b
diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h
index fea444908a..97c4035113 100644
--- a/sys/sys/cdefs.h
+++ b/sys/sys/cdefs.h
@@ -536,6 +536,22 @@
 #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.
+ */
+#ifndef __RTLD
+#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
+#else /* __RTLD */
+#define	_Thread_local
+#endif /* !__RTLD */
 #endif
 
 #endif /* __STDC_VERSION__ || __STDC_VERSION__ < 201112L */
diff --git a/sys/sys/errno.h b/sys/sys/errno.h
index 2bfa6a9b5c..69b026b612 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;
 
 int * __errno_location(void);		/* For language bindings only */
 __END_DECLS
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.23.0

