I wish to propose two changes that I currently have in my Solaris patchkit. I'll use two separate e-mails here to avoid confusion.
Both changes add environment variables controlling the way wine does things.
The first patch addresses a problem I have found where Windows applications under wine exceed the allocated stack. By default wine allocates the same 1MB stack that windows does but wine has a different stack consumption that does windows, adding the wine translation layers, possibly OGL then X calls on top of this.
The following patch allows an environment variable WINE_STACK to redefine the minimum stack to give applications and to add extra stack to that declared in the executables header to allow for additional stack consumption. Currently it works like this
if WINE_STACK is not set the default semantics are used just like wine does today
if WINE_STACK is set then wine allocates the maximum of the value given in the WINE_STACK env var or 1MB. 25% of the value specified in WINE_STACK is added to the value declared in the applications executable header to provide more headroom for wine/X calls.
Please excuse the primitive debugging included for now, it'll have to be removed for primetime.
Comments anyone ?
Index: dlls/ntdll/thread.c =================================================================== RCS file: /home/wine/wine/dlls/ntdll/thread.c,v retrieving revision 1.26 diff -u -3 -p -r1.26 thread.c --- dlls/ntdll/thread.c 27 Apr 2005 08:18:20 -0000 1.26 +++ dlls/ntdll/thread.c 6 May 2005 21:21:30 -0000 @@ -25,7 +25,7 @@ #ifdef HAVE_SYS_MMAN_H #include <sys/mman.h> #endif - +#include <stdio.h> #include "ntstatus.h" #include "thread.h" #include "winternl.h" @@ -221,6 +221,9 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN ULONG size; int request_pipe[2]; NTSTATUS status; + unsigned long stack_min=1024*1024; + unsigned long stack_overhead=0; + char stack_mul=0;
if( ! is_current_process( process ) ) { @@ -273,23 +276,67 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN MEM_SYSTEM, PAGE_EXECUTE_READWRITE ); info->pthread_info.teb_size = size; info->pthread_info.teb_sel = teb->teb_sel; - + + + /* Allocate the stack: + Allow the user to set an environment variable to specify the stack size + WINE_STACK, allow the user to use multiplier notation + eg K for kilobyts or M for Megabytes or M + example WINE_STCK=2048K or WINE_STACK=2M bithe specify 2 Megabytes + */ + + if(getenv("WINE_STACK")) { + sscanf(getenv("WINE_STACK")," %lu%c ",&stack_min,&stack_mul); + fprintf(stderr,"Got stack spec of %lu %c bytes from environment",stack_min,stack_mul); + } + + switch (stack_mul) { + case 'm': + case 'M': + stack_min=stack_min*1024*1024; + stack_overhead=stack_min/4; + break; + case 'b': + case 'B': + stack_overhead=stack_min/4; + break; + case 'k': + case 'K': + stack_min=stack_min*1024; + stack_overhead=stack_min/4; + break; + + default: + stack_min=1024*1024; + stack_overhead=0; + break; + } + + stack_min=max(stack_min,1024*1024); + fprintf(stderr,"Minimum Stack Set to %lu overhead allowance = %d\n",stack_min,stack_overhead); + /* Get the stack size recommendation from the program prefix (Executible header) + Because this is not "real windows" we have additional stack overheads particularly in xlib + where the user has specified a stack requirement (IE VIA WINE_STACK) add 25% of the minimum + stack over and above the value in the header to allow for this + */ if (!stack_reserve || !stack_commit) { IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress ); - if (!stack_reserve) stack_reserve = nt->OptionalHeader.SizeOfStackReserve; + if (!stack_reserve) stack_reserve = nt->OptionalHeader.SizeOfStackReserve+stack_overhead; if (!stack_commit) stack_commit = nt->OptionalHeader.SizeOfStackCommit; } if (stack_reserve < stack_commit) stack_reserve = stack_commit; stack_reserve = (stack_reserve + 0xffff) & ~0xffff; /* round to 64K boundary */ - if (stack_reserve < 1024 * 1024) stack_reserve = 1024 * 1024; /* Xlib needs a large stack */ + if (stack_reserve < stack_min) stack_reserve = stack_min; /* Xlib needs a large stack */
info->pthread_info.stack_base = NULL; info->pthread_info.stack_size = stack_reserve; info->pthread_info.entry = start_thread; info->entry_point = start; info->entry_arg = param; - + + fprintf(stderr,"Allocated thread at %lx Allocated stack of %lu Bytes\n",stack_commit,stack_reserve); + if (wine_pthread_create_thread( &info->pthread_info ) == -1) { status = STATUS_NO_MEMORY;
Robert Lunnon wrote:
I wish to propose two changes that I currently have in my Solaris patchkit. I'll use two separate e-mails here to avoid confusion.
Both changes add environment variables controlling the way wine does things.
The first patch addresses a problem I have found where Windows applications under wine exceed the allocated stack. By default wine allocates the same 1MB stack that windows does but wine has a different stack consumption that does windows, adding the wine translation layers, possibly OGL then X calls on top of this.
The following patch allows an environment variable WINE_STACK to redefine the minimum stack to give applications and to add extra stack to that declared in the executables header to allow for additional stack consumption. Currently it works like this
if WINE_STACK is not set the default semantics are used just like wine does today
if WINE_STACK is set then wine allocates the maximum of the value given in the WINE_STACK env var or 1MB. 25% of the value specified in WINE_STACK is added to the value declared in the applications executable header to provide more headroom for wine/X calls.
Please excuse the primitive debugging included for now, it'll have to be removed for primetime.
Comments anyone ?
I think this is a bit weird: `wine prog.exe` is not equivalent to: `WINE_STACK=1M wine prog.exe` -- it is equivalent to this weird thing: `WINE_STACK=838860B wine prog.exe`
Why wouldn't you simple add that 25% extra in every case?
regards,
Joris
On Sat, 7 May 2005 07:47 pm, Joris Huizer wrote:
Robert Lunnon wrote:
I wish to propose two changes that I currently have in my Solaris patchkit. I'll use two separate e-mails here to avoid confusion.
Both changes add environment variables controlling the way wine does things.
The first patch addresses a problem I have found where Windows applications under wine exceed the allocated stack. By default wine allocates the same 1MB stack that windows does but wine has a different stack consumption that does windows, adding the wine translation layers, possibly OGL then X calls on top of this.
The following patch allows an environment variable WINE_STACK to redefine the minimum stack to give applications and to add extra stack to that declared in the executables header to allow for additional stack consumption. Currently it works like this
if WINE_STACK is not set the default semantics are used just like wine does today
if WINE_STACK is set then wine allocates the maximum of the value given in the WINE_STACK env var or 1MB. 25% of the value specified in WINE_STACK is added to the value declared in the applications executable header to provide more headroom for wine/X calls.
Please excuse the primitive debugging included for now, it'll have to be removed for primetime.
Comments anyone ?
I think this is a bit weird: `wine prog.exe` is not equivalent to: `WINE_STACK=1M wine prog.exe` -- it is equivalent to this weird thing: `WINE_STACK=838860B wine prog.exe`
Why wouldn't you simple add that 25% extra in every case?
Well, that would be a solution but it doesn't allow a fallback to "Standard windows behaviour" I have no idea if there are any applications out there that are sensitive to the size of their stack segments
Bob
On Sat, 07 May 2005 18:13:41 +1000, Robert Lunnon wrote:
Comments anyone ?
I have to echo Joris, why don't we just increase the default stack size if this is causing problems? Does it cost us anything?
thanks -mike
Robert Lunnon bobl@optushome.com.au writes:
The first patch addresses a problem I have found where Windows applications under wine exceed the allocated stack. By default wine allocates the same 1MB stack that windows does but wine has a different stack consumption that does windows, adding the wine translation layers, possibly OGL then X calls on top of this.
Actually Wine stack usage should be very similar to Windows. The real problem is that Xlib seems to allocate large amount of stack space in some cases; I believe this has improved lately, since it's obviously also a problem for threaded Unix apps, and we haven't had reports of stack overflows on Linux for a long time. What you probably want to do is just unconditionally add some more space on Solaris until the X libraries are fixed.
On Sat, 7 May 2005 10:06 pm, Alexandre Julliard wrote:
Robert Lunnon bobl@optushome.com.au writes:
The first patch addresses a problem I have found where Windows applications under wine exceed the allocated stack. By default wine allocates the same 1MB stack that windows does but wine has a different stack consumption that does windows, adding the wine translation layers, possibly OGL then X calls on top of this.
Actually Wine stack usage should be very similar to Windows. The real problem is that Xlib seems to allocate large amount of stack space in some cases; I believe this has improved lately, since it's obviously also a problem for threaded Unix apps, and we haven't had reports of stack overflows on Linux for a long time. What you probably want to do is just unconditionally add some more space on Solaris until the X libraries are fixed.
When I wrote this I was trying to maintain the "Standard windows behaviour" in the first instance with stack space expansion occurring only in the abnormal case (Where the app does have a stack depletion problem and therefore the env var is set)
If the concensus is to add space unconditionally (#ifdef only for Solaris) then I'm happy to do that.
Bob