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
079fd72c
Commit
079fd72c
authored
Jan 25, 2000
by
Alexandre Julliard
Committed by
Alexandre Julliard
Jan 25, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Share the system heap between different address spaces. Made process
heap per-address space instead of per-process.
parent
2fe57779
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
175 additions
and
21 deletions
+175
-21
heap.h
include/heap.h
+14
-0
process.h
include/process.h
+1
-1
winnt.h
include/winnt.h
+1
-0
environ.c
memory/environ.c
+10
-9
global.c
memory/global.c
+7
-7
heap.c
memory/heap.c
+142
-4
No files found.
include/heap.h
View file @
079fd72c
...
...
@@ -22,6 +22,7 @@ extern LPSTR HEAP_strdupA( HANDLE heap, DWORD flags, LPCSTR str );
extern
LPWSTR
HEAP_strdupW
(
HANDLE
heap
,
DWORD
flags
,
LPCWSTR
str
);
extern
LPWSTR
HEAP_strdupAtoW
(
HANDLE
heap
,
DWORD
flags
,
LPCSTR
str
);
extern
LPSTR
HEAP_strdupWtoA
(
HANDLE
heap
,
DWORD
flags
,
LPCWSTR
str
);
extern
BOOL
HEAP_CreateSystemHeap
(
void
);
/* SEGPTR helper macros */
...
...
@@ -41,5 +42,18 @@ static inline SEGPTR WINE_UNUSED SEGPTR_Get(LPCVOID ptr) {
#define SEGPTR_FREE(ptr) \
(HIWORD(ptr) ? HeapFree( SegptrHeap, 0, (ptr) ) : 0)
/* system heap private data */
/* you must lock the system heap before using this structure */
typedef
struct
{
void
*
gdi
;
/* GDI heap */
void
*
user
;
/* USER handle table */
void
*
cursor
;
/* cursor information */
void
*
queue
;
/* message queues descriptor */
void
*
win
;
/* windows descriptor */
void
*
root
;
/* X11 root window */
}
SYSTEM_HEAP_DESCR
;
extern
SYSTEM_HEAP_DESCR
*
SystemHeapDescr
;
#endif
/* __WINE_HEAP_H */
include/process.h
View file @
079fd72c
...
...
@@ -151,7 +151,7 @@ void WINAPI SetProcessDword( DWORD dwProcessID, INT offset, DWORD value );
extern
DWORD
WINAPI
MapProcessHandle
(
HANDLE
handle
);
/* scheduler/environ.c */
extern
BOOL
ENV_InheritEnvironment
(
PDB
*
pdb
,
LPCSTR
env
);
extern
BOOL
ENV_InheritEnvironment
(
LPCSTR
env
);
extern
void
ENV_FreeEnvironment
(
PDB
*
pdb
);
/* scheduler/process.c */
...
...
include/winnt.h
View file @
079fd72c
...
...
@@ -117,6 +117,7 @@ typedef struct _SINGLE_LIST_ENTRY {
#define HEAP_WINE_SEGPTR 0x01000000
/* Not a Win32 flag */
#define HEAP_WINE_CODESEG 0x02000000
/* Not a Win32 flag */
#define HEAP_WINE_CODE16SEG 0x04000000
/* Not a Win32 flag */
#define HEAP_WINE_SHARED 0x08000000
/* Not a Win32 flag */
/* Processor feature flags. */
#define PF_FLOATING_POINT_PRECISION_ERRATA 0
...
...
memory/environ.c
View file @
079fd72c
...
...
@@ -78,7 +78,7 @@ static BOOL ENV_BuildEnvironment( PDB *pdb )
/* Now allocate the environment */
if
(
!
(
p
=
HeapAlloc
(
SystemHeap
,
0
,
size
)))
return
FALSE
;
if
(
!
(
p
=
HeapAlloc
(
GetProcessHeap
()
,
0
,
size
)))
return
FALSE
;
pdb
->
env_db
->
environ
=
p
;
/* And fill it with the Unix environment */
...
...
@@ -102,11 +102,12 @@ static BOOL ENV_BuildEnvironment( PDB *pdb )
* Make a process inherit the environment from its parent or from an
* explicit environment.
*/
BOOL
ENV_InheritEnvironment
(
PDB
*
pdb
,
LPCSTR
env
)
BOOL
ENV_InheritEnvironment
(
LPCSTR
env
)
{
DWORD
size
;
LPCSTR
src
;
LPSTR
dst
;
PDB
*
pdb
=
PROCESS_Current
();
/* FIXME: should lock the parent environment */
if
(
!
env
)
...
...
@@ -131,7 +132,7 @@ BOOL ENV_InheritEnvironment( PDB *pdb, LPCSTR env )
/* Copy the environment */
if
(
!
(
pdb
->
env_db
->
environ
=
HeapAlloc
(
pdb
->
heap
,
0
,
size
)))
if
(
!
(
pdb
->
env_db
->
environ
=
HeapAlloc
(
GetProcessHeap
()
,
0
,
size
)))
return
FALSE
;
pdb
->
env_db
->
env_sel
=
SELECTOR_AllocBlock
(
pdb
->
env_db
->
environ
,
0x10000
,
SEGMENT_DATA
,
...
...
@@ -162,7 +163,7 @@ void ENV_FreeEnvironment( PDB *pdb )
if
(
!
pdb
->
env_db
)
return
;
if
(
pdb
->
env_db
->
env_sel
)
SELECTOR_FreeBlock
(
pdb
->
env_db
->
env_sel
,
1
);
DeleteCriticalSection
(
&
pdb
->
env_db
->
section
);
HeapFree
(
pdb
->
heap
,
0
,
pdb
->
env_db
);
/* the storage will be deleted when the process heap is destroyed */
}
...
...
@@ -182,7 +183,7 @@ LPCWSTR WINAPI GetCommandLineW(void)
PDB
*
pdb
=
PROCESS_Current
();
EnterCriticalSection
(
&
pdb
->
env_db
->
section
);
if
(
!
pdb
->
env_db
->
cmd_lineW
)
pdb
->
env_db
->
cmd_lineW
=
HEAP_strdupAtoW
(
pdb
->
heap
,
0
,
pdb
->
env_db
->
cmd_lineW
=
HEAP_strdupAtoW
(
GetProcessHeap
()
,
0
,
pdb
->
env_db
->
cmd_line
);
LeaveCriticalSection
(
&
pdb
->
env_db
->
section
);
return
pdb
->
env_db
->
cmd_lineW
;
...
...
@@ -209,8 +210,8 @@ LPWSTR WINAPI GetEnvironmentStringsW(void)
PDB
*
pdb
=
PROCESS_Current
();
EnterCriticalSection
(
&
pdb
->
env_db
->
section
);
size
=
HeapSize
(
pdb
->
heap
,
0
,
pdb
->
env_db
->
environ
);
if
((
ret
=
HeapAlloc
(
pdb
->
heap
,
0
,
size
*
sizeof
(
WCHAR
)
))
!=
NULL
)
size
=
HeapSize
(
GetProcessHeap
()
,
0
,
pdb
->
env_db
->
environ
);
if
((
ret
=
HeapAlloc
(
GetProcessHeap
()
,
0
,
size
*
sizeof
(
WCHAR
)
))
!=
NULL
)
{
LPSTR
pA
=
pdb
->
env_db
->
environ
;
LPWSTR
pW
=
ret
;
...
...
@@ -323,13 +324,13 @@ BOOL WINAPI SetEnvironmentVariableA( LPCSTR name, LPCSTR value )
len
=
value
?
strlen
(
name
)
+
strlen
(
value
)
+
2
:
0
;
if
(
*
p
)
len
-=
strlen
(
p
)
+
1
;
/* The name already exists */
old_size
=
HeapSize
(
pdb
->
heap
,
0
,
env
);
old_size
=
HeapSize
(
GetProcessHeap
()
,
0
,
env
);
if
(
len
<
0
)
{
LPSTR
next
=
p
+
strlen
(
p
)
+
1
;
/* We know there is a next one */
memmove
(
next
+
len
,
next
,
old_size
-
(
next
-
env
)
);
}
if
(
!
(
new_env
=
HeapReAlloc
(
pdb
->
heap
,
0
,
env
,
old_size
+
len
)))
if
(
!
(
new_env
=
HeapReAlloc
(
GetProcessHeap
()
,
0
,
env
,
old_size
+
len
)))
goto
done
;
if
(
pdb
->
env_db
->
env_sel
)
SELECTOR_MoveBlock
(
pdb
->
env_db
->
env_sel
,
new_env
);
...
...
memory/global.c
View file @
079fd72c
...
...
@@ -206,7 +206,7 @@ HGLOBAL16 GLOBAL_Alloc( UINT16 flags, DWORD size, HGLOBAL16 hOwner,
size
=
(
size
+
0x1f
)
&
~
0x1f
;
/* Allocate the linear memory */
ptr
=
HeapAlloc
(
SystemHeap
,
0
,
size
);
ptr
=
HeapAlloc
(
GetProcessHeap
()
,
0
,
size
);
/* FIXME: free discardable blocks and try again? */
if
(
!
ptr
)
return
0
;
...
...
@@ -216,7 +216,7 @@ HGLOBAL16 GLOBAL_Alloc( UINT16 flags, DWORD size, HGLOBAL16 hOwner,
isCode
,
is32Bit
,
isReadOnly
,
&
shmdata
);
if
(
!
handle
)
{
HeapFree
(
SystemHeap
,
0
,
ptr
);
HeapFree
(
GetProcessHeap
()
,
0
,
ptr
);
return
0
;
}
...
...
@@ -276,7 +276,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
if
(
!
(
pArena
->
flags
&
GA_MOVEABLE
)
||
!
(
pArena
->
flags
&
GA_DISCARDABLE
)
||
(
pArena
->
lockCount
>
0
)
||
(
pArena
->
pageLockCount
>
0
))
return
0
;
HeapFree
(
SystemHeap
,
0
,
(
void
*
)
pArena
->
base
);
HeapFree
(
GetProcessHeap
()
,
0
,
(
void
*
)
pArena
->
base
);
pArena
->
base
=
0
;
/* Note: we rely on the fact that SELECTOR_ReallocBlock won't
...
...
@@ -314,7 +314,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
((
char
*
)
ptr
<=
DOSMEM_MemoryBase
(
0
)
+
0x100000
))
ptr
=
DOSMEM_ResizeBlock
(
0
,
ptr
,
size
,
NULL
);
else
ptr
=
HeapReAlloc
(
SystemHeap
,
0
,
ptr
,
size
);
ptr
=
HeapReAlloc
(
GetProcessHeap
()
,
0
,
ptr
,
size
);
if
(
!
ptr
)
{
SELECTOR_FreeBlock
(
sel
,
(
oldsize
+
0xffff
)
/
0x10000
);
...
...
@@ -327,7 +327,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
sel
=
SELECTOR_ReallocBlock
(
sel
,
ptr
,
size
);
if
(
!
sel
)
{
HeapFree
(
SystemHeap
,
0
,
ptr
);
HeapFree
(
GetProcessHeap
()
,
0
,
ptr
);
memset
(
pArena
,
0
,
sizeof
(
GLOBALARENA
)
);
return
0
;
}
...
...
@@ -335,7 +335,7 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
if
(
!
(
pNewArena
=
GLOBAL_GetArena
(
sel
,
selcount
)))
{
HeapFree
(
SystemHeap
,
0
,
ptr
);
HeapFree
(
GetProcessHeap
()
,
0
,
ptr
);
SELECTOR_FreeBlock
(
sel
,
selcount
);
return
0
;
}
...
...
@@ -376,7 +376,7 @@ HGLOBAL16 WINAPI GlobalFree16(
TRACE
(
"%04x
\n
"
,
handle
);
if
(
!
GLOBAL_FreeBlock
(
handle
))
return
handle
;
/* failed */
if
(
ptr
)
HeapFree
(
SystemHeap
,
0
,
ptr
);
if
(
ptr
)
HeapFree
(
GetProcessHeap
()
,
0
,
ptr
);
return
0
;
}
...
...
memory/heap.c
View file @
079fd72c
...
...
@@ -93,6 +93,7 @@ typedef struct tagHEAP
CRITICAL_SECTION
critSection
;
/* Critical section for serialization */
DWORD
flags
;
/* Heap flags */
DWORD
magic
;
/* Magic number */
void
*
private
;
/* Private pointer for the user of the heap */
}
HEAP
;
#define HEAP_MAGIC ((DWORD)('H' | ('E'<<8) | ('A'<<16) | ('P'<<24)))
...
...
@@ -103,6 +104,14 @@ typedef struct tagHEAP
HANDLE
SystemHeap
=
0
;
HANDLE
SegptrHeap
=
0
;
SYSTEM_HEAP_DESCR
*
SystemHeapDescr
=
0
;
static
HEAP
*
processHeap
;
/* main process heap */
static
HEAP
*
firstHeap
;
/* head of secondary heaps list */
/* address where we try to map the system heap */
#define SYSTEM_HEAP_BASE ((void*)0x65430000)
static
BOOL
HEAP_IsRealArena
(
HANDLE
heap
,
DWORD
flags
,
LPCVOID
block
,
BOOL
quiet
);
#ifdef __GNUC__
...
...
@@ -419,7 +428,7 @@ static void HEAP_MakeInUseBlockFree( SUBHEAP *subheap, ARENA_INUSE *pArena )
/* Decommit the end of the heap */
HEAP_Decommit
(
subheap
,
pFree
+
1
);
if
(
!
(
subheap
->
heap
->
flags
&
HEAP_WINE_SHARED
))
HEAP_Decommit
(
subheap
,
pFree
+
1
);
}
...
...
@@ -458,6 +467,8 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
/* Commit memory */
if
(
flags
&
HEAP_WINE_SHARED
)
commitSize
=
totalSize
;
/* always commit everything in a shared heap */
if
(
!
VirtualAlloc
(
address
,
commitSize
,
MEM_COMMIT
,
PAGE_EXECUTE_READWRITE
))
{
WARN
(
"Could not commit %08lx bytes for sub-heap %08lx
\n
"
,
...
...
@@ -1001,6 +1012,20 @@ HANDLE WINAPI HeapCreate(
return
0
;
}
/* link it into the per-process heap list */
if
(
processHeap
)
{
HEAP
*
heapPtr
=
subheap
->
heap
;
EnterCriticalSection
(
&
processHeap
->
critSection
);
heapPtr
->
next
=
firstHeap
;
firstHeap
=
heapPtr
;
LeaveCriticalSection
(
&
processHeap
->
critSection
);
}
else
/* assume the first heap we create is the process main heap */
{
processHeap
=
subheap
->
heap
;
}
return
(
HANDLE
)
subheap
;
}
...
...
@@ -1010,15 +1035,29 @@ HANDLE WINAPI HeapCreate(
* TRUE: Success
* FALSE: Failure
*/
BOOL
WINAPI
HeapDestroy
(
HANDLE
heap
/* [in] Handle of heap */
)
{
BOOL
WINAPI
HeapDestroy
(
HANDLE
heap
/* [in] Handle of heap */
)
{
HEAP
*
heapPtr
=
HEAP_GetPtr
(
heap
);
SUBHEAP
*
subheap
;
TRACE
(
"%08x
\n
"
,
heap
);
if
(
!
heapPtr
)
return
FALSE
;
if
(
heapPtr
==
processHeap
)
/* cannot delete the main process heap */
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
FALSE
;
}
else
/* remove it from the per-process list */
{
HEAP
**
pptr
;
EnterCriticalSection
(
&
processHeap
->
critSection
);
pptr
=
&
firstHeap
;
while
(
*
pptr
&&
*
pptr
!=
heapPtr
)
pptr
=
&
(
*
pptr
)
->
next
;
if
(
*
pptr
)
*
pptr
=
(
*
pptr
)
->
next
;
LeaveCriticalSection
(
&
processHeap
->
critSection
);
}
DeleteCriticalSection
(
&
heapPtr
->
critSection
);
subheap
=
&
heapPtr
->
subheap
;
while
(
subheap
)
...
...
@@ -1391,6 +1430,105 @@ BOOL WINAPI HeapWalk(
/***********************************************************************
* HEAP_CreateSystemHeap
*
* Create the system heap.
*/
BOOL
HEAP_CreateSystemHeap
(
void
)
{
SYSTEM_HEAP_DESCR
*
descr
;
HANDLE
heap
;
HEAP
*
heapPtr
;
int
created
;
HANDLE
map
=
CreateFileMappingA
(
INVALID_HANDLE_VALUE
,
NULL
,
SEC_COMMIT
|
PAGE_READWRITE
,
0
,
HEAP_DEF_SIZE
,
"__SystemHeap"
);
if
(
!
map
)
return
FALSE
;
created
=
(
GetLastError
()
!=
ERROR_ALREADY_EXISTS
);
if
(
!
(
heapPtr
=
MapViewOfFileEx
(
map
,
FILE_MAP_ALL_ACCESS
,
0
,
0
,
0
,
SYSTEM_HEAP_BASE
)))
{
/* pre-defined address not available, use any one */
fprintf
(
stderr
,
"Warning: system heap base address %p not available
\n
"
,
SYSTEM_HEAP_BASE
);
if
(
!
(
heapPtr
=
MapViewOfFile
(
map
,
FILE_MAP_ALL_ACCESS
,
0
,
0
,
0
)))
{
CloseHandle
(
map
);
return
FALSE
;
}
}
heap
=
(
HANDLE
)
heapPtr
;
if
(
created
)
/* newly created heap */
{
HEAP_InitSubHeap
(
heapPtr
,
heapPtr
,
HEAP_WINE_SHARED
,
0
,
HEAP_DEF_SIZE
);
HeapLock
(
heap
);
descr
=
heapPtr
->
private
=
HeapAlloc
(
heap
,
HEAP_ZERO_MEMORY
,
sizeof
(
*
descr
)
);
assert
(
descr
);
}
else
{
/* wait for the heap to be initialized */
while
(
!
heapPtr
->
private
)
Sleep
(
1
);
HeapLock
(
heap
);
/* remap it to the right address if necessary */
if
(
heapPtr
->
subheap
.
heap
!=
heapPtr
)
{
void
*
base
=
heapPtr
->
subheap
.
heap
;
HeapUnlock
(
heap
);
UnmapViewOfFile
(
heapPtr
);
if
(
!
(
heapPtr
=
MapViewOfFileEx
(
map
,
FILE_MAP_ALL_ACCESS
,
0
,
0
,
0
,
base
)))
{
fprintf
(
stderr
,
"Couldn't map system heap at the correct address (%p)
\n
"
,
base
);
CloseHandle
(
map
);
return
FALSE
;
}
heap
=
(
HANDLE
)
heapPtr
;
HeapLock
(
heap
);
}
descr
=
heapPtr
->
private
;
assert
(
descr
);
}
SystemHeap
=
heap
;
SystemHeapDescr
=
descr
;
HeapUnlock
(
heap
);
CloseHandle
(
map
);
return
TRUE
;
}
/***********************************************************************
* GetProcessHeap (KERNEL32.259)
*/
HANDLE
WINAPI
GetProcessHeap
(
void
)
{
return
(
HANDLE
)
processHeap
;
}
/***********************************************************************
* GetProcessHeaps (KERNEL32.376)
*/
DWORD
WINAPI
GetProcessHeaps
(
DWORD
count
,
HANDLE
*
heaps
)
{
DWORD
total
;
HEAP
*
ptr
;
if
(
!
processHeap
)
return
0
;
/* should never happen */
total
=
1
;
/* main heap */
EnterCriticalSection
(
&
processHeap
->
critSection
);
for
(
ptr
=
firstHeap
;
ptr
;
ptr
=
ptr
->
next
)
total
++
;
if
(
total
<=
count
)
{
*
heaps
++
=
(
HANDLE
)
processHeap
;
for
(
ptr
=
firstHeap
;
ptr
;
ptr
=
ptr
->
next
)
*
heaps
++
=
(
HANDLE
)
ptr
;
}
LeaveCriticalSection
(
&
processHeap
->
critSection
);
return
total
;
}
/***********************************************************************
* HEAP_xalloc
*
* Same as HeapAlloc(), but die on failure.
...
...
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