* 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> | ||||
|  | ||||
| 	* 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; | ||||
|   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"); | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
| 					       - sizeof (PVOID)); | ||||
| 					       + wrapper_arg.stacksize); | ||||
|       _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\ | ||||
| 	       movl  %[WRAPPER_ARG], %%ebx # Load &wrapper_arg into ebx  \n\ | ||||
| 	       movl  (%%ebx), %%eax        # Load thread func into eax   \n\ | ||||
|   | ||||
| @@ -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) | ||||
| { | ||||
|   | ||||
| @@ -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) | ||||
| { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user