Stack size allocations

Robert Lunnon bobl at optushome.com.au
Sat May 7 03:13:41 CDT 2005


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;



More information about the wine-devel mailing list