---
linuxthreads/sysdeps/x86_64/tls.h | 42 ++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
--- a/linuxthreads/sysdeps/x86_64/tls.h
+++ b/linuxthreads/sysdeps/x86_64/tls.h
@@ -49,6 +49,11 @@
uintptr_t sysinfo;
uintptr_t stack_guard;
uintptr_t pointer_guard;
+# ifdef __FreeBSD_kernel__
+ long gscope_flag;
+# else
+ int gscope_flag;
+# endif
} tcbhead_t;
#else /* __ASSEMBLER__ */
@@ -147,6 +152,43 @@
((descr)->p_header.data.pointer_guard \
= THREAD_GETMEM (THREAD_SELF, p_header.data.pointer_guard))
+/* Get and set the global scope generation counter in the TCB head. */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED 1
+#define THREAD_GSCOPE_FLAG_WAIT 2
+#ifdef __FreeBSD_kernel__
+# define THREAD_GSCOPE_RESET_FLAG() \
+ do \
+ { int __res; \
+ asm volatile ("xchgl %0, %%fs:%P1" \
+ : "=r" (__res) \
+ : "i" (offsetof (struct _pthread_descr_struct, p_gscope_flag)), \
+ "0" (THREAD_GSCOPE_FLAG_UNUSED)); \
+ if (__res == THREAD_GSCOPE_FLAG_WAIT) \
+ lll_futex_wake (&THREAD_SELF->p_gscope_flag, 1); \
+ } \
+ while (0)
+#else
+/* As the FreeBSD kernel defines futex as long (compared to int with
+ a Linux kernel), we need to use xchgq instead of xchgl to handle
+ the gscope_flag variable. */
+# define THREAD_GSCOPE_RESET_FLAG() \
+ do \
+ { long __res; \
+ asm volatile ("xchgq %0, %%fs:%P1" \
+ : "=r" (__res) \
+ : "i" (offsetof (struct _pthread_descr_struct, p_gscope_flag)), \
+ "0" (THREAD_GSCOPE_FLAG_UNUSED)); \
+ if (__res == THREAD_GSCOPE_FLAG_WAIT) \
+ lll_futex_wake (&THREAD_SELF->p_gscope_flag, 1); \
+ } \
+ while (0)
+#endif /* __FreeBSD_kernel__ */
+#define THREAD_GSCOPE_SET_FLAG() \
+ THREAD_SETMEM (THREAD_SELF, p_gscope_flag, THREAD_GSCOPE_FLAG_USED)
+#define THREAD_GSCOPE_WAIT() \
+ do { /* GL(dl_wait_lookup_done) () */ } while (0)
+
# endif /* HAVE_TLS_SUPPORT */
#endif /* __ASSEMBLER__ */