Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
3ef93229
Commit
3ef93229
authored
Apr 13, 2000
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleanup thread stack allocation. Use a single VirtualAlloc for TEB and
the various stacks.
parent
86ff8c08
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
108 additions
and
108 deletions
+108
-108
thread.h
include/thread.h
+1
-1
process.c
scheduler/process.c
+1
-2
thread.c
scheduler/thread.c
+106
-105
No files found.
include/thread.h
View file @
3ef93229
...
...
@@ -119,7 +119,7 @@ typedef struct _TEB
/* scheduler/thread.c */
extern
TEB
*
THREAD_CreateInitialThread
(
struct
_PDB
*
pdb
,
int
server_fd
);
extern
TEB
*
THREAD_Create
(
struct
_PDB
*
pdb
,
void
*
pid
,
void
*
tid
,
int
fd
,
DWORD
flags
,
extern
TEB
*
THREAD_Create
(
struct
_PDB
*
pdb
,
void
*
pid
,
void
*
tid
,
int
fd
,
DWORD
stack_size
,
BOOL
alloc_stack16
);
extern
BOOL
THREAD_IsWin16
(
TEB
*
thdb
);
extern
TEB
*
THREAD_IdToTEB
(
DWORD
id
);
...
...
scheduler/process.c
View file @
3ef93229
...
...
@@ -557,8 +557,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, HFILE hFile, LPCSTR cmd_line, LPCSTR en
/* Create the main thread */
if
(
!
(
teb
=
THREAD_Create
(
pdb
,
req
->
pid
,
req
->
tid
,
fd
,
flags
&
CREATE_SUSPENDED
,
size
,
alloc_stack16
)))
goto
error
;
if
(
!
(
teb
=
THREAD_Create
(
pdb
,
req
->
pid
,
req
->
tid
,
fd
,
size
,
alloc_stack16
)))
goto
error
;
teb
->
startup
=
PROCESS_Start
;
fd
=
-
1
;
/* don't close it */
...
...
scheduler/thread.c
View file @
3ef93229
...
...
@@ -18,6 +18,7 @@
#include "process.h"
#include "task.h"
#include "module.h"
#include "global.h"
#include "user.h"
#include "winerror.h"
#include "heap.h"
...
...
@@ -74,57 +75,20 @@ TEB *THREAD_IdToTEB( DWORD id )
*
* Initialization of a newly created TEB.
*/
static
BOOL
THREAD_InitTEB
(
TEB
*
teb
,
DWORD
stack_size
,
BOOL
alloc_stack16
)
static
BOOL
THREAD_InitTEB
(
TEB
*
teb
,
PDB
*
pdb
)
{
DWORD
old_prot
;
/* Allocate the stack */
/* FIXME:
* If stacksize smaller than 1 MB, allocate 1MB
* (one program wanted only 10 kB, which is recommendable, but some WINE
* functions, noteably in the files subdir, push HUGE structures and
* arrays on the stack. They probably shouldn't.)
* If stacksize larger than 16 MB, warn the user. (We could shrink the stack
* but this could give more or less unexplainable crashes.)
*/
if
(
stack_size
<
1024
*
1024
)
stack_size
=
1024
*
1024
;
if
(
stack_size
>=
16
*
1024
*
1024
)
WARN
(
"Thread stack size is %ld MB.
\n
"
,
stack_size
/
1024
/
1024
);
teb
->
stack_base
=
VirtualAlloc
(
NULL
,
stack_size
+
SIGNAL_STACK_SIZE
+
(
alloc_stack16
?
0x10000
:
0
),
MEM_COMMIT
,
PAGE_EXECUTE_READWRITE
);
if
(
!
teb
->
stack_base
)
goto
error
;
/* Set a guard page at the bottom of the stack */
VirtualProtect
(
teb
->
stack_base
,
1
,
PAGE_EXECUTE_READWRITE
|
PAGE_GUARD
,
&
old_prot
);
teb
->
stack_top
=
(
char
*
)
teb
->
stack_base
+
stack_size
;
teb
->
stack_low
=
teb
->
stack_base
;
teb
->
signal_stack
=
teb
->
stack_top
;
/* start of signal stack */
/* Allocate the 16-bit stack selector */
if
(
alloc_stack16
)
{
teb
->
stack_sel
=
SELECTOR_AllocBlock
(
teb
->
stack_top
,
0x10000
,
SEGMENT_DATA
,
FALSE
,
FALSE
);
if
(
!
teb
->
stack_sel
)
goto
error
;
teb
->
cur_stack
=
PTR_SEG_OFF_TO_SEGPTR
(
teb
->
stack_sel
,
0x10000
-
sizeof
(
STACK16FRAME
)
);
teb
->
signal_stack
=
(
char
*
)
teb
->
signal_stack
+
0x10000
;
}
/* StaticUnicodeString */
teb
->
except
=
(
void
*
)
~
0UL
;
teb
->
htask16
=
pdb
->
task
;
teb
->
self
=
teb
;
teb
->
tibflags
=
(
pdb
->
flags
&
PDB32_WIN16_PROC
)
?
0
:
TEBF_WIN32
;
teb
->
tls_ptr
=
teb
->
tls_array
;
teb
->
process
=
pdb
;
teb
->
exit_code
=
STILL_ACTIVE
;
teb
->
socket
=
-
1
;
teb
->
StaticUnicodeString
.
MaximumLength
=
sizeof
(
teb
->
StaticUnicodeBuffer
);
teb
->
StaticUnicodeString
.
Buffer
=
(
PWSTR
)
teb
->
StaticUnicodeBuffer
;
return
TRUE
;
error:
if
(
teb
->
stack_sel
)
SELECTOR_FreeBlock
(
teb
->
stack_sel
,
1
);
if
(
teb
->
stack_base
)
VirtualFree
(
teb
->
stack_base
,
0
,
MEM_RELEASE
);
return
FALSE
;
teb
->
teb_sel
=
SELECTOR_AllocBlock
(
teb
,
0x1000
,
SEGMENT_DATA
,
TRUE
,
FALSE
);
return
(
teb
->
teb_sel
!=
0
);
}
...
...
@@ -134,12 +98,10 @@ error:
* Free data structures associated with a thread.
* Must be called from the context of another thread.
*/
void
CALLBACK
THREAD_FreeTEB
(
ULONG_PTR
arg
)
static
void
CALLBACK
THREAD_FreeTEB
(
TEB
*
teb
)
{
TEB
*
teb
=
(
TEB
*
)
arg
;
TRACE
(
"(%p) called
\n
"
,
teb
);
SERVICE_Delete
(
teb
->
cleanup
);
if
(
teb
->
cleanup
)
SERVICE_Delete
(
teb
->
cleanup
);
/* Free the associated memory */
...
...
@@ -149,85 +111,124 @@ void CALLBACK THREAD_FreeTEB( ULONG_PTR arg )
if
(
teb
->
buffer
)
munmap
(
teb
->
buffer
,
teb
->
buffer_size
);
if
(
teb
->
debug_info
)
HeapFree
(
GetProcessHeap
(),
0
,
teb
->
debug_info
);
VirtualFree
(
teb
->
stack_base
,
0
,
MEM_RELEASE
);
VirtualFree
(
teb
,
0
,
MEM_RELEASE
);
}
/***********************************************************************
* THREAD_
CreateInitialThread
* THREAD_
InitStack
*
*
Create the initial
thread.
*
Allocate the stack of a
thread.
*/
TEB
*
THREAD_CreateInitialThread
(
PDB
*
pdb
,
int
server_fd
)
static
TEB
*
THREAD_InitStack
(
TEB
*
teb
,
PDB
*
pdb
,
DWORD
stack_size
,
BOOL
alloc_stack16
)
{
initial_teb
.
except
=
(
void
*
)
-
1
;
initial_teb
.
self
=
&
initial_teb
;
initial_teb
.
tibflags
=
(
pdb
->
flags
&
PDB32_WIN16_PROC
)
?
0
:
TEBF_WIN32
;
initial_teb
.
tls_ptr
=
initial_teb
.
tls_array
;
initial_teb
.
process
=
pdb
;
initial_teb
.
exit_code
=
STILL_ACTIVE
;
initial_teb
.
socket
=
server_fd
;
DWORD
old_prot
,
total_size
;
DWORD
page_size
=
VIRTUAL_GetPageSize
();
void
*
base
;
/* Allocate the
TEB selector (%fs register)
*/
/* Allocate the
stack
*/
if
(
!
(
initial_teb
.
teb_sel
=
SELECTOR_AllocBlock
(
&
initial_teb
,
0x1000
,
SEGMENT_DATA
,
TRUE
,
FALSE
)))
if
(
stack_size
>=
16
*
1024
*
1024
)
WARN
(
"Thread stack size is %ld MB.
\n
"
,
stack_size
/
1024
/
1024
);
/* FIXME: some Wine functions use a lot of stack, so we add 64Kb here */
stack_size
+=
64
*
1024
;
/* Memory layout in allocated block:
*
* size contents
* 1 page NOACCESS guard page
* SIGNAL_STACK_SIZE signal stack
* 1 page NOACCESS guard page
* 1 page PAGE_GUARD guard page
* stack_size normal stack
* 64Kb 16-bit stack (optional)
* 1 page TEB (except for initial thread)
*/
stack_size
=
(
stack_size
+
(
page_size
-
1
))
&
~
(
page_size
-
1
);
total_size
=
stack_size
+
SIGNAL_STACK_SIZE
+
3
*
page_size
;
if
(
alloc_stack16
)
total_size
+=
0x10000
;
if
(
!
teb
)
total_size
+=
page_size
;
if
(
!
(
base
=
VirtualAlloc
(
NULL
,
total_size
,
MEM_COMMIT
,
PAGE_EXECUTE_READWRITE
)))
return
NULL
;
if
(
!
teb
)
{
teb
=
(
TEB
*
)((
char
*
)
base
+
total_size
-
page_size
);
if
(
!
THREAD_InitTEB
(
teb
,
pdb
))
{
MESSAGE
(
"Could not allocate fs register for initial thread
\n
"
);
VirtualFree
(
base
,
0
,
MEM_RELEASE
);
return
NULL
;
}
SYSDEPS_SetCurThread
(
&
initial_teb
);
}
teb
->
stack_low
=
base
;
teb
->
stack_base
=
base
;
teb
->
signal_stack
=
(
char
*
)
base
+
page_size
;
teb
->
stack_top
=
(
char
*
)
base
+
3
*
page_size
+
SIGNAL_STACK_SIZE
+
stack_size
;
/* Now proceed with normal initialization */
/* Setup guard pages */
VirtualProtect
(
base
,
1
,
PAGE_NOACCESS
,
&
old_prot
);
VirtualProtect
(
(
char
*
)
teb
->
signal_stack
+
SIGNAL_STACK_SIZE
,
1
,
PAGE_NOACCESS
,
&
old_prot
);
VirtualProtect
(
(
char
*
)
teb
->
signal_stack
+
SIGNAL_STACK_SIZE
+
page_size
,
1
,
PAGE_EXECUTE_READWRITE
|
PAGE_GUARD
,
&
old_prot
);
/* Allocate the 16-bit stack selector */
if
(
alloc_stack16
)
{
teb
->
stack_sel
=
SELECTOR_AllocBlock
(
teb
->
stack_top
,
0x10000
,
SEGMENT_DATA
,
FALSE
,
FALSE
);
if
(
!
teb
->
stack_sel
)
goto
error
;
teb
->
cur_stack
=
PTR_SEG_OFF_TO_SEGPTR
(
teb
->
stack_sel
,
0x10000
-
sizeof
(
STACK16FRAME
)
);
}
return
teb
;
error:
THREAD_FreeTEB
(
teb
);
return
NULL
;
}
/***********************************************************************
* THREAD_CreateInitialThread
*
* Create the initial thread.
*
* NOTES: The first allocated TEB on NT is at 0x7ffde000.
*/
TEB
*
THREAD_CreateInitialThread
(
PDB
*
pdb
,
int
server_fd
)
{
if
(
!
THREAD_InitTEB
(
&
initial_teb
,
pdb
))
return
NULL
;
SYSDEPS_SetCurThread
(
&
initial_teb
);
initial_teb
.
socket
=
server_fd
;
if
(
CLIENT_InitThread
())
return
NULL
;
if
(
!
THREAD_InitTEB
(
&
initial_teb
,
0
,
TRUE
))
return
NULL
;
return
&
initial_teb
;
return
THREAD_InitStack
(
&
initial_teb
,
pdb
,
0
,
TRUE
);
}
/***********************************************************************
* THREAD_Create
*
* NOTES:
* Native NT dlls are using the space left on the allocated page
* the first allocated TEB on NT is at 0x7ffde000, since we can't
* allocate in this area and don't support a granularity of 4kb
* yet we leave it to VirtualAlloc to choose an address.
*/
TEB
*
THREAD_Create
(
PDB
*
pdb
,
void
*
pid
,
void
*
tid
,
int
fd
,
DWORD
flags
,
TEB
*
THREAD_Create
(
PDB
*
pdb
,
void
*
pid
,
void
*
tid
,
int
fd
,
DWORD
stack_size
,
BOOL
alloc_stack16
)
{
TEB
*
teb
=
VirtualAlloc
(
0
,
0x1000
,
MEM_COMMIT
,
PAGE_EXECUTE_READWRITE
);
if
(
!
teb
)
return
NULL
;
teb
->
except
=
(
void
*
)
-
1
;
teb
->
htask16
=
pdb
->
task
;
teb
->
self
=
teb
;
teb
->
tibflags
=
(
pdb
->
flags
&
PDB32_WIN16_PROC
)
?
0
:
TEBF_WIN32
;
teb
->
tls_ptr
=
teb
->
tls_array
;
teb
->
process
=
pdb
;
teb
->
exit_code
=
STILL_ACTIVE
;
teb
->
socket
=
fd
;
TEB
*
teb
;
if
((
teb
=
THREAD_InitStack
(
NULL
,
pdb
,
stack_size
,
alloc_stack16
)))
{
teb
->
pid
=
pid
;
teb
->
tid
=
tid
;
teb
->
socket
=
fd
;
fcntl
(
fd
,
F_SETFD
,
1
);
/* set close on exec flag */
/* Allocate the TEB selector (%fs register) */
teb
->
teb_sel
=
SELECTOR_AllocBlock
(
teb
,
0x1000
,
SEGMENT_DATA
,
TRUE
,
FALSE
);
if
(
!
teb
->
teb_sel
)
goto
error
;
/* Do the rest of the initialization */
if
(
!
THREAD_InitTEB
(
teb
,
stack_size
,
alloc_stack16
))
goto
error
;
TRACE
(
"(%p) succeeded
\n
"
,
teb
);
}
return
teb
;
error:
if
(
teb
->
teb_sel
)
SELECTOR_FreeBlock
(
teb
->
teb_sel
,
1
);
VirtualFree
(
teb
,
0
,
MEM_RELEASE
);
return
NULL
;
}
...
...
@@ -245,7 +246,7 @@ static void THREAD_Start(void)
if
(
DuplicateHandle
(
GetCurrentProcess
(),
GetCurrentThread
(),
GetCurrentProcess
(),
&
cleanup_object
,
0
,
FALSE
,
DUPLICATE_SAME_ACCESS
))
NtCurrentTeb
()
->
cleanup
=
SERVICE_AddObject
(
cleanup_object
,
THREAD_FreeTEB
,
NtCurrentTeb
()
->
cleanup
=
SERVICE_AddObject
(
cleanup_object
,
(
PAPCFUNC
)
THREAD_FreeTEB
,
(
ULONG_PTR
)
NtCurrentTeb
()
);
PROCESS_CallUserSignalProc
(
USIG_THREAD_INIT
,
0
);
...
...
@@ -272,7 +273,7 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
handle
=
req
->
handle
;
if
(
!
(
teb
=
THREAD_Create
(
PROCESS_Current
(),
(
void
*
)
GetCurrentProcessId
(),
req
->
tid
,
socket
,
flags
,
stack
,
TRUE
)))
req
->
tid
,
socket
,
stack
,
TRUE
)))
{
close
(
socket
);
return
0
;
...
...
@@ -281,12 +282,12 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
teb
->
entry_point
=
start
;
teb
->
entry_arg
=
param
;
teb
->
startup
=
THREAD_Start
;
if
(
id
)
*
id
=
(
DWORD
)
teb
->
tid
;
if
(
SYSDEPS_SpawnThread
(
teb
)
==
-
1
)
{
CloseHandle
(
handle
);
return
0
;
}
if
(
id
)
*
id
=
(
DWORD
)
teb
->
tid
;
return
handle
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment