* 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:
Corinna Vinschen 2011-05-16 09:55:18 +00:00
parent 943e23a49f
commit 6d6cfa4840
5 changed files with 59 additions and 9 deletions

View 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.

View 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");

View 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
- 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\

View 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)
{

View 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)
{