allocatestack.c changes for TLS_DTV_AT_TP

Paul Mackerras <[email protected]>
Newsgroups gmane.comp.lib.phil
Message-ID <[email protected]>
Here are the changes that I have made locally to allocatestack.c and
pthread_create.c to support the TLS_DTV_AT_TP model, which we use
(slightly modified :) on PPC.  As it says in the comments, it probably
needs stronger alignment applied in the calculation of pd.

Comments?

Paul.

diff -urN nptl-0.28/nptl/allocatestack.c libc/nptl/allocatestack.c
--- nptl-0.28/nptl/allocatestack.c	2003-03-02 08:39:31.000000000 +1100
+++ libc/nptl/allocatestack.c	2003-03-11 21:32:09.000000000 +1100
@@ -51,7 +51,11 @@
 # define MINIMAL_REST_STACK	4096
 #endif
 
-
+#if TLS_TCB_AT_TP
+# define TLS_TCB(pd)	(pd)
+#elif TLS_DTV_AT_TP
+# define TLS_TCB(pd)	((void *)((pd) + 1))
+#endif
 
 
 /* Cache handling for not-yet free stacks.  */
@@ -157,11 +161,12 @@
   result->nextevent = NULL;
 
   /* Clear the DTV.  */
-  dtv_t *dtv = GET_DTV (result);
+  dtv_t *dtv = GET_DTV (TLS_TCB(result));
   memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
 
   /* Re-initialize the TLS.  */
-  return _dl_allocate_tls_init (result);
+  _dl_allocate_tls_init (TLS_TCB(result));
+  return result;
 }
 
 
@@ -198,7 +203,7 @@
 	      stack_cache_actsize -= curr->stackblock_size;
 
 	      /* Free the memory associated with the ELF TLS.  */
-	      _dl_deallocate_tls (curr, false);
+	      _dl_deallocate_tls (TLS_TCB(curr), false);
 
 	      /* Remove this block.  This should never fail.  If it
 		 does something is really wrong.  */
@@ -250,8 +255,17 @@
 	 size...  We do not allocate guard pages if the user provided
 	 the stack.  It is the user's responsibility to do this if it
 	 is wanted.  */
+#if TLS_TCB_AT_TP
       pd = (struct pthread *) (((uintptr_t) attr->stackaddr - adj)
 			       & ~(__alignof (struct pthread) - 1)) - 1;
+#else
+      /* Place the static TLS area at the end of the stack,
+	 preceded by the thread descriptor.  */
+      /* XXX probably need more alignment */
+      pd = (struct pthread *)(((uintptr_t) attr->stackaddr - adj
+			       - TLS_TCB_SIZE - __static_tls_size)
+			      & ~(__alignof (struct pthread) - 1)) - 1;
+#endif
 
       /* The user provided stack memory needs to be cleared.  */
       memset (pd, '\0', sizeof (struct pthread));
@@ -282,7 +296,7 @@
 #endif
 
       /* Allocate the DTV for this thread.  */
-      if (_dl_allocate_tls (pd) == NULL)
+      if (_dl_allocate_tls (TLS_TCB(pd)) == NULL)
 	/* Something went wrong.  */
 	return errno;
 
@@ -363,8 +377,16 @@
 # define coloring 0
 #endif
 
+#if TLS_TCB_AT_TP
 	  /* Place the thread descriptor at the end of the stack.  */
 	  pd = (struct pthread *) ((char *) mem + size - coloring) - 1;
+#else
+	  /* Place the static TLS area at the end of the stack,
+	     preceded by the thread descriptor.  */
+	  /* XXX probably need more alignment */
+	  pd = (struct pthread *)((char *) mem + size - TLS_TCB_SIZE
+				  - __static_tls_size) - 1;
+#endif
 
 	  /* Remember the stack-related values.  */
 	  pd->stackblock = mem;
@@ -390,7 +412,7 @@
 #endif
 
 	  /* Allocate the DTV for this thread.  */
-	  if (_dl_allocate_tls (pd) == NULL)
+	  if (_dl_allocate_tls (TLS_TCB(pd)) == NULL)
 	    {
 	      /* Something went wrong.  */
 	      int err = errno;
@@ -466,7 +488,9 @@
   /* The stack begins before the TCB and the static TLS block.  */
   *stack = ((char *) (pd + 1) - __static_tls_size);
 #else
-# error "Implement me"
+  /* The top of the stack is at the start of the pthread struct.
+     This assumes that the stack grows downwards.  */
+  *stack = (char *) pd;
 #endif
 
   return 0;
@@ -495,7 +519,7 @@
     (void) queue_stack (pd);
   else
     /* Free the memory associated with the ELF TLS.  */
-    _dl_deallocate_tls (pd, false);
+    _dl_deallocate_tls (TLS_TCB(pd), false);
 
   lll_unlock (stack_cache_lock);
 }
diff -urN nptl-0.28/nptl/pthread_create.c libc/nptl/pthread_create.c
--- nptl-0.28/nptl/pthread_create.c	2003-02-23 20:00:24.000000000 +1100
+++ libc/nptl/pthread_create.c	2003-03-11 19:47:20.000000000 +1100
@@ -351,6 +351,8 @@
 #ifdef TLS_TCB_AT_TP
   /* Self-reference.  */
   pd->header.data.tcb = pd;
+#elif TLS_DTV_AT_TP
+  pd->header.data.tcb = pd + 1;
 #endif
 
   /* Store the address of the start routine and the parameter.  Since
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.