]> sourceware.org Git - newlib-cygwin.git/commitdiff
* dcrt0.cc (child_info_fork::alloc_stack_hard_way): Check if the
authorCorinna Vinschen <corinna@vinschen.de>
Mon, 16 May 2011 09:55:18 +0000 (09:55 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Mon, 16 May 2011 09:55:18 +0000 (09:55 +0000)
requested stack is application-provided within the user heap or an
mmapped region.  If so, just use it.  Add comment to explain why.
* miscfuncs.cc (thread_wrapper): If an application-provided stack
has been given, implement cygtls area at the stackbase.  Fix comment.
* mmap.cc (is_mmapped_region): New function.
* winsup.h (is_mmapped_region): Declare.

winsup/cygwin/ChangeLog
winsup/cygwin/dcrt0.cc
winsup/cygwin/miscfuncs.cc
winsup/cygwin/mmap.cc
winsup/cygwin/winsup.h

index 1870469311762eaa24db1298dccbd96b76d4ebfe..8551e462c5025b2b3ce87c287047e594adcd8cec 100644 (file)
@@ -1,3 +1,13 @@
+2011-05-16  Corinna Vinschen  <corinna@vinschen.de>
+
+       * dcrt0.cc (child_info_fork::alloc_stack_hard_way): Check if the
+       requested stack is application-provided within the user heap or an
+       mmapped region.  If so, just use it.  Add comment to explain why.
+       * miscfuncs.cc (thread_wrapper): If an application-provided stack
+       has been given, implement cygtls area at the stackbase.  Fix comment.
+       * mmap.cc (is_mmapped_region): New function.
+       * winsup.h (is_mmapped_region): Declare.
+
 2011-05-15  Corinna Vinschen  <corinna@vinschen.de>
 
        * miscfuncs.cc (thread_wrapper): Add comments to assembler code.
index 92056c80f5031f6c08b97ea008f49a2a08c040a6..a6eb2696d22ccdb5360aa287c72d8798e079bd13 100644 (file)
@@ -398,6 +398,15 @@ child_info_fork::alloc_stack_hard_way (volatile char *b)
   int newlen;
   bool guard;
 
+  /* First check if the requested stack area is part of the user heap
+     or part of a mmaped region.  If so, we have been started from a
+     pthread with an application-provided stack, and the stack has just
+     to be used as is. */
+  if ((stacktop >= cygheap->user_heap.base
+      && stackbottom <= cygheap->user_heap.max)
+      || is_mmapped_region ((caddr_t) stacktop, (caddr_t) stackbottom))
+    return;
+
   if (!VirtualQuery ((LPCVOID) &b, &m, sizeof m))
     api_fatal ("fork: couldn't get stack info, %E");
 
index 73dec4c1a65d7680cc5feaca1dff23c6c06093a2..a166ca1da77582e631b438b0b1ea2ae5b0f0299b 100644 (file)
@@ -410,16 +410,17 @@ thread_wrapper (VOID *arg)
     {
       /* If the application provided the stack, we must make sure that
         it's actually used by the thread function.  So what we do here is
-        to compute the stackbase of the application-provided stack and
-        change the stack pointer accordingly.
-
-        NOTE: _my_tls is on the stack created by CreateThread!  It's
-              unlikely the tls structure will ever exceed 64K, but if
-              so, we have to raise the size of the stack in the call
-              to CreateThread, too. */
+        to compute the stackbase of the application-provided stack, move
+        _my_tls to the stackbase, and change the stack pointer accordingly. */
+      wrapper_arg.stackaddr = (PVOID) ((PBYTE) wrapper_arg.stackaddr
+                                              + wrapper_arg.stacksize);
+      _tlsbase = (char *) wrapper_arg.stackaddr;
       wrapper_arg.stackaddr = (PVOID) ((PBYTE) wrapper_arg.stackaddr
-                                              + wrapper_arg.stacksize
-                                              - sizeof (PVOID));
+                                              - CYGTLS_PADSIZE);
+      _tlstop = (char *) wrapper_arg.stackaddr;
+      _my_tls.init_thread ((char *) wrapper_arg.stackaddr,
+                          (DWORD (*)(void*, void*)) wrapper_arg.func);
+      wrapper_arg.stackaddr = (PVOID) (_tlstop - sizeof (PVOID));
       __asm__ ("\n\
               movl  %[WRAPPER_ARG], %%ebx # Load &wrapper_arg into ebx  \n\
               movl  (%%ebx), %%eax        # Load thread func into eax   \n\
index 059daa186bcbde9ce2eb7c544138bf1c62dfc276..9daa32fd735b41de9b29693903ca71cb4c4ed3eb 100644 (file)
@@ -659,6 +659,34 @@ mmap_areas::del_list (mmap_list *ml)
   cfree (ml);
 }
 
+/* This function allows an external function to test if a given memory
+   region is part of an mmapped memory region. */
+bool
+is_mmapped_region (caddr_t start_addr, caddr_t end_address)
+{
+  bool ret = false;
+
+  size_t len = end_address - start_addr;
+
+  LIST_LOCK ();
+  mmap_list *map_list = mmapped_areas.get_list_by_fd (-1, NULL);
+
+  mmap_record *rec;
+  caddr_t u_addr;
+  DWORD u_len;
+
+  LIST_FOREACH (rec, &map_list->recs, mr_next)
+    {
+      if (rec->match (start_addr, len, u_addr, u_len))
+       {
+         ret = true;
+         break;
+       }
+    }
+  LIST_UNLOCK ();
+  return ret;
+}
+
 /* This function is called from exception_handler when a segmentation
    violation has occurred.  It should also be called from all Cygwin
    functions that want to support passing noreserve mmap page addresses
@@ -677,6 +705,7 @@ mmap_areas::del_list (mmap_list *ml)
    On MAP_NORESERVE_COMMITED, the exeception handler should return 0 to
    allow the application to retry the memory access, or the calling Cygwin
    function should retry the Windows system call. */
+
 mmap_region_status
 mmap_is_attached_or_noreserve (void *addr, size_t len)
 {
index 087da61f4b79644f69af7de3ee4f565ec9c8702a..44f00339b0dac1d9c99b615fe94836fd827c2dda 100644 (file)
@@ -270,6 +270,7 @@ enum mmap_region_status
     MMAP_NORESERVE_COMMITED
   };
 mmap_region_status mmap_is_attached_or_noreserve (void *addr, size_t len);
+bool is_mmapped_region (caddr_t start_addr, caddr_t end_address);
 
 inline bool flush_file_buffers (HANDLE h)
 {
This page took 0.041189 seconds and 5 git commands to generate.