Discussion:
Stack size allocations
Robert Lunnon
2005-05-07 08:13:41 UTC
Permalink
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;
Joris Huizer
2005-05-07 09:47:08 UTC
Permalink
Post by Robert Lunnon
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
Robert Lunnon
2005-05-07 11:50:02 UTC
Permalink
Post by Joris Huizer
Post by Robert Lunnon
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 ?
`wine prog.exe`
`WINE_STACK=1M wine prog.exe`
`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
Mike Hearn
2005-05-07 11:44:53 UTC
Permalink
Post by Robert Lunnon
Comments anyone ?
Mike Hearn
2005-05-07 11:45:18 UTC
Permalink
Post by Robert Lunnon
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
Alexandre Julliard
2005-05-07 12:06:57 UTC
Permalink
Post by Robert Lunnon
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.
--
Alexandre Julliard
***@winehq.org
Robert Lunnon
2005-05-07 22:03:47 UTC
Permalink
Post by Alexandre Julliard
Post by Robert Lunnon
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

Loading...