mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-18 23:12:15 +08:00
* 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:
parent
943e23a49f
commit
6d6cfa4840
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user