* 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.
This commit is contained in:
		| @@ -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> | 2011-05-15  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* miscfuncs.cc (thread_wrapper): Add comments to assembler code. | 	* miscfuncs.cc (thread_wrapper): Add comments to assembler code. | ||||||
|   | |||||||
| @@ -398,6 +398,15 @@ child_info_fork::alloc_stack_hard_way (volatile char *b) | |||||||
|   int newlen; |   int newlen; | ||||||
|   bool guard; |   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)) |   if (!VirtualQuery ((LPCVOID) &b, &m, sizeof m)) | ||||||
|     api_fatal ("fork: couldn't get stack info, %E"); |     api_fatal ("fork: couldn't get stack info, %E"); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -410,16 +410,17 @@ thread_wrapper (VOID *arg) | |||||||
|     { |     { | ||||||
|       /* If the application provided the stack, we must make sure that |       /* 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 | 	 it's actually used by the thread function.  So what we do here is | ||||||
| 	 to compute the stackbase of the application-provided stack and | 	 to compute the stackbase of the application-provided stack, move | ||||||
| 	 change the stack pointer accordingly. | 	 _my_tls to the stackbase, 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. */ |  | ||||||
|       wrapper_arg.stackaddr = (PVOID) ((PBYTE) wrapper_arg.stackaddr |       wrapper_arg.stackaddr = (PVOID) ((PBYTE) wrapper_arg.stackaddr | ||||||
| 					       + wrapper_arg.stacksize | 					       + wrapper_arg.stacksize); | ||||||
| 					       - sizeof (PVOID)); |       _tlsbase = (char *) wrapper_arg.stackaddr; | ||||||
|  |       wrapper_arg.stackaddr = (PVOID) ((PBYTE) wrapper_arg.stackaddr | ||||||
|  | 					       - 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\ |       __asm__ ("\n\ | ||||||
| 	       movl  %[WRAPPER_ARG], %%ebx # Load &wrapper_arg into ebx  \n\ | 	       movl  %[WRAPPER_ARG], %%ebx # Load &wrapper_arg into ebx  \n\ | ||||||
| 	       movl  (%%ebx), %%eax        # Load thread func into eax   \n\ | 	       movl  (%%ebx), %%eax        # Load thread func into eax   \n\ | ||||||
|   | |||||||
| @@ -659,6 +659,34 @@ mmap_areas::del_list (mmap_list *ml) | |||||||
|   cfree (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 | /* This function is called from exception_handler when a segmentation | ||||||
|    violation has occurred.  It should also be called from all Cygwin |    violation has occurred.  It should also be called from all Cygwin | ||||||
|    functions that want to support passing noreserve mmap page addresses |    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 |    On MAP_NORESERVE_COMMITED, the exeception handler should return 0 to | ||||||
|    allow the application to retry the memory access, or the calling Cygwin |    allow the application to retry the memory access, or the calling Cygwin | ||||||
|    function should retry the Windows system call. */ |    function should retry the Windows system call. */ | ||||||
|  |  | ||||||
| mmap_region_status | mmap_region_status | ||||||
| mmap_is_attached_or_noreserve (void *addr, size_t len) | mmap_is_attached_or_noreserve (void *addr, size_t len) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -270,6 +270,7 @@ enum mmap_region_status | |||||||
|     MMAP_NORESERVE_COMMITED |     MMAP_NORESERVE_COMMITED | ||||||
|   }; |   }; | ||||||
| mmap_region_status mmap_is_attached_or_noreserve (void *addr, size_t len); | 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) | inline bool flush_file_buffers (HANDLE h) | ||||||
| { | { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user