(TLS_PRE_TCB_SIZE): If PTHREAD_STRUCT_END_PADDING
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / ia64 / tls.h
index 5ce7473..e3ad068 100644 (file)
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  nptl/IA-64 version.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -22,6 +22,7 @@
 
 #include <dl-sysdep.h>
 #ifndef __ASSEMBLER__
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 # include <stdlib.h>
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 
@@ -42,6 +47,8 @@ typedef struct
   void *private;
 } tcbhead_t;
 
+register struct pthread *__thread_self __asm__("r13");
+
 # define TLS_MULTIPLE_THREADS_IN_TCB 1
 
 #else /* __ASSEMBLER__ */
@@ -64,8 +71,6 @@ typedef struct
 /* Get system call information.  */
 # include <sysdep.h>
 
-register struct pthread *__thread_self __asm__("r13");
-
 /* This is the size of the initial TCB.  */
 # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
 
@@ -75,8 +80,15 @@ register struct pthread *__thread_self __asm__("r13");
 /* This is the size of the TCB.  */
 # define TLS_TCB_SIZE sizeof (tcbhead_t)
 
-/* This is the size we need before TCB.  */
-# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
+/* This is the size we need before TCB.
+   If there is not any room for uintptr_t stack_guard in struct pthread's
+   final padding, we need to put struct pthread 16 byte slower.  */
+# define TLS_PRE_TCB_SIZE \
+  (sizeof (struct pthread)                                     \
+   + (PTHREAD_STRUCT_END_PADDING < sizeof (uintptr_t)          \
+      ? ((sizeof (uintptr_t) + __alignof__ (struct pthread) - 1)\
+        & ~(__alignof__ (struct pthread) - 1))                 \
+      : 0))
 
 /* Alignment requirements for the TCB.  */
 # define TLS_TCB_ALIGN __alignof__ (struct pthread)
@@ -100,22 +112,32 @@ register struct pthread *__thread_self __asm__("r13");
 #  define GET_DTV(descr) \
   (((tcbhead_t *) (descr))->dtv)
 
+#define THREAD_SELF_SYSINFO    (((tcbhead_t *) __thread_self)->private)
+#define THREAD_SYSINFO(pd) \
+  (((tcbhead_t *) ((char *) (pd) + TLS_PRE_TCB_SIZE))->private)
+
+#if defined NEED_DL_SYSINFO
+# define INIT_SYSINFO   THREAD_SELF_SYSINFO = (void *) GLRO(dl_sysinfo)
+#else
+# define INIT_SYSINFO   NULL
+#endif
+
 /* Code to initially initialize the thread pointer.  This might need
    special attention since 'errno' is not yet available and if the
    operation can cause a failure 'errno' must not be touched.  */
 # define TLS_INIT_TP(thrdescr, secondcall) \
-  (__thread_self = (thrdescr), NULL)
+  (__thread_self = (thrdescr), INIT_SYSINFO, NULL)
 
 /* Return the address of the dtv for the current thread.  */
 #  define THREAD_DTV() \
   (((tcbhead_t *)__thread_self)->dtv)
 
 /* Return the thread descriptor for the current thread.  */
-# define THREAD_SELF (__thread_self - 1)
+# define THREAD_SELF \
+  ((struct pthread *) ((char *) __thread_self - TLS_PRE_TCB_SIZE))
 
-/* Identifier for the current thread.  THREAD_SELF is usable but
-   sometimes more expensive than necessary as in this case.  */
-# define THREAD_ID __thread_self
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF REGISTER (64, 64, 13 * 8, -TLS_PRE_TCB_SIZE)
 
 /* Access to data in the thread descriptor is easy.  */
 #define THREAD_GETMEM(descr, member) \
@@ -127,6 +149,13 @@ register struct pthread *__thread_self __asm__("r13");
 #define THREAD_SETMEM_NC(descr, member, idx, value) \
   descr->member[idx] = (value)
 
+/* Set the stack guard field in TCB head.  */
+#define THREAD_SET_STACK_GUARD(value) \
+  (((uintptr_t *) __thread_self)[-1] = (value))
+#define THREAD_COPY_STACK_GUARD(descr) \
+  (((uintptr_t *) ((char *) (descr) + TLS_PRE_TCB_SIZE))[-1] \
+   = ((uintptr_t *) __thread_self)[-1])
+
 #endif /* __ASSEMBLER__ */
 
 #endif /* tls.h */