eglibc (2.11.3-2) amd64/local-linuxthreads-gscope.diff

Summary

 linuxthreads/sysdeps/x86_64/tls.h |   42 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

    
download this patch

Patch contents

---
 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__ */