mirror of
https://github.com/reactos/wine.git
synced 2025-02-15 10:29:19 +00:00
Only create the system heap when we actually need it.
This commit is contained in:
parent
61d32b4e0d
commit
7f187e5043
@ -15,10 +15,7 @@
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/windef16.h" /* for SEGPTR */
|
||||
|
||||
extern HANDLE SystemHeap;
|
||||
|
||||
extern SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr );
|
||||
extern BOOL HEAP_CreateSystemHeap(void);
|
||||
|
||||
/* SEGPTR helper macros */
|
||||
|
||||
@ -78,18 +75,4 @@ inline static LPSTR HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str )
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
128
memory/heap.c
128
memory/heap.c
@ -96,7 +96,6 @@ 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)))
|
||||
@ -105,10 +104,7 @@ typedef struct tagHEAP
|
||||
#define HEAP_MIN_BLOCK_SIZE (8+sizeof(ARENA_FREE)) /* Min. heap block size */
|
||||
#define COMMIT_MASK 0xffff /* bitmask for commit/decommit granularity */
|
||||
|
||||
HANDLE SystemHeap = 0;
|
||||
|
||||
SYSTEM_HEAP_DESCR *SystemHeapDescr = 0;
|
||||
|
||||
static HEAP *systemHeap; /* globally shared heap */
|
||||
static HEAP *processHeap; /* main process heap */
|
||||
static HEAP *segptrHeap; /* main segptr heap */
|
||||
static HEAP *firstHeap; /* head of secondary heaps list */
|
||||
@ -541,9 +537,8 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
|
||||
/* Initialize critical section */
|
||||
|
||||
InitializeCriticalSection( &heap->critSection );
|
||||
if (!SystemHeap) MakeCriticalSectionGlobal( &heap->critSection );
|
||||
}
|
||||
|
||||
|
||||
/* Create the first free block */
|
||||
|
||||
HEAP_CreateFreeBlock( subheap, (LPBYTE)subheap + subheap->headerSize,
|
||||
@ -1029,6 +1024,42 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* HEAP_CreateSystemHeap
|
||||
*
|
||||
* Create the system heap.
|
||||
*/
|
||||
static HANDLE HEAP_CreateSystemHeap(void)
|
||||
{
|
||||
int created;
|
||||
|
||||
HANDLE map = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE,
|
||||
0, HEAP_DEF_SIZE, "__SystemHeap" );
|
||||
if (!map) return 0;
|
||||
created = (GetLastError() != ERROR_ALREADY_EXISTS);
|
||||
|
||||
if (!(systemHeap = MapViewOfFileEx( map, FILE_MAP_ALL_ACCESS, 0, 0, 0, SYSTEM_HEAP_BASE )))
|
||||
{
|
||||
/* pre-defined address not available, use any one */
|
||||
ERR( "system heap base address %p not available\n", SYSTEM_HEAP_BASE );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (created) /* newly created heap */
|
||||
{
|
||||
HEAP_InitSubHeap( systemHeap, systemHeap, HEAP_SHARED, 0, HEAP_DEF_SIZE );
|
||||
MakeCriticalSectionGlobal( &systemHeap->critSection );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* wait for the heap to be initialized */
|
||||
while (!systemHeap->critSection.LockSemaphore) Sleep(1);
|
||||
}
|
||||
CloseHandle( map );
|
||||
return (HANDLE)systemHeap;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* HeapCreate (KERNEL32.336)
|
||||
* RETURNS
|
||||
@ -1044,7 +1075,8 @@ HANDLE WINAPI HeapCreate(
|
||||
|
||||
if ( flags & HEAP_SHARED ) {
|
||||
WARN( "Shared Heap requested, returning system heap.\n" );
|
||||
return SystemHeap;
|
||||
if (!systemHeap) HEAP_CreateSystemHeap();
|
||||
return (HANDLE)systemHeap;
|
||||
}
|
||||
|
||||
/* Allocate the heap block */
|
||||
@ -1095,14 +1127,14 @@ BOOL WINAPI HeapDestroy( HANDLE heap /* [in] Handle of heap */ )
|
||||
HEAP *heapPtr = HEAP_GetPtr( heap );
|
||||
SUBHEAP *subheap;
|
||||
|
||||
if ( heap == SystemHeap ) {
|
||||
WARN( "attempt to destroy system heap, returning TRUE!\n" );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TRACE("%08x\n", heap );
|
||||
if (!heapPtr) return FALSE;
|
||||
|
||||
if (heapPtr == systemHeap)
|
||||
{
|
||||
WARN( "attempt to destroy system heap, returning TRUE!\n" );
|
||||
return TRUE;
|
||||
}
|
||||
if (heapPtr == processHeap) /* cannot delete the main process heap */
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
@ -1603,74 +1635,6 @@ HW_end:
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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_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)
|
||||
*/
|
||||
@ -1841,7 +1805,7 @@ HANDLE WINAPI Local32Init16( WORD segment, DWORD tableSize,
|
||||
LPBYTE oldBase = (LPBYTE)GetSelectorBase( segment );
|
||||
memcpy( base, oldBase, segSize );
|
||||
GLOBAL_MoveBlock( segment, base, totSize );
|
||||
HeapFree( SystemHeap, 0, oldBase );
|
||||
HeapFree( GetProcessHeap(), 0, oldBase );
|
||||
}
|
||||
|
||||
return (HANDLE)header;
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "drive.h"
|
||||
#include "module.h"
|
||||
#include "file.h"
|
||||
#include "heap.h"
|
||||
#include "thread.h"
|
||||
#include "winerror.h"
|
||||
#include "server.h"
|
||||
@ -103,6 +102,9 @@ extern struct _ENVDB *ENV_BuildEnvironment(void);
|
||||
extern BOOL ENV_BuildCommandLine( char **argv );
|
||||
extern STARTUPINFOA current_startupinfo;
|
||||
|
||||
/* scheduler/pthread.c */
|
||||
extern void PTHREAD_init_done(void);
|
||||
|
||||
extern BOOL MAIN_MainInit(void);
|
||||
|
||||
|
||||
@ -303,10 +305,12 @@ static BOOL process_init( char *argv[] )
|
||||
if (create_flags & CREATE_NEW_CONSOLE)
|
||||
set_console_handles( current_startupinfo.hStdOutput );
|
||||
|
||||
/* Create the system and process heaps */
|
||||
if (!HEAP_CreateSystemHeap()) return FALSE;
|
||||
/* Create the process heap */
|
||||
current_process.heap = HeapCreate( HEAP_GROWABLE, 0, 0 );
|
||||
|
||||
/* Now we can use the pthreads routines */
|
||||
PTHREAD_init_done();
|
||||
|
||||
/* Copy the parent environment */
|
||||
if (!(current_process.env_db = ENV_BuildEnvironment())) return FALSE;
|
||||
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "winbase.h"
|
||||
#include "heap.h"
|
||||
#include "thread.h"
|
||||
|
||||
/* Currently this probably works only for glibc2,
|
||||
@ -88,6 +87,13 @@ typedef const void *key_data;
|
||||
|
||||
#define P_OUTPUT(stuff) write(2,stuff,strlen(stuff))
|
||||
|
||||
static int init_done;
|
||||
|
||||
void PTHREAD_init_done(void)
|
||||
{
|
||||
init_done = 1;
|
||||
}
|
||||
|
||||
void __pthread_initialize(void)
|
||||
{
|
||||
}
|
||||
@ -106,7 +112,7 @@ strong_alias(__pthread_once, pthread_once);
|
||||
void __pthread_kill_other_threads_np(void)
|
||||
{
|
||||
/* FIXME: this is supposed to be preparation for exec() */
|
||||
if (SystemHeap) P_OUTPUT("fixme:pthread_kill_other_threads_np\n");
|
||||
if (init_done) P_OUTPUT("fixme:pthread_kill_other_threads_np\n");
|
||||
}
|
||||
strong_alias(__pthread_kill_other_threads_np, pthread_kill_other_threads_np);
|
||||
|
||||
@ -125,13 +131,13 @@ int __pthread_atfork(void (*prepare)(void),
|
||||
void (*parent)(void),
|
||||
void (*child)(void))
|
||||
{
|
||||
if (SystemHeap) EnterCriticalSection( &atfork_section );
|
||||
if (init_done) EnterCriticalSection( &atfork_section );
|
||||
assert( atfork_count < MAX_ATFORK );
|
||||
atfork_prepare[atfork_count] = prepare;
|
||||
atfork_parent[atfork_count] = parent;
|
||||
atfork_child[atfork_count] = child;
|
||||
atfork_count++;
|
||||
if (SystemHeap) LeaveCriticalSection( &atfork_section );
|
||||
if (init_done) LeaveCriticalSection( &atfork_section );
|
||||
return 0;
|
||||
}
|
||||
strong_alias(__pthread_atfork, pthread_atfork);
|
||||
@ -178,19 +184,19 @@ strong_alias(__pthread_mutex_init, pthread_mutex_init);
|
||||
|
||||
static void mutex_real_init( pthread_mutex_t *mutex )
|
||||
{
|
||||
CRITICAL_SECTION *critsect = HeapAlloc(SystemHeap, 0, sizeof(CRITICAL_SECTION));
|
||||
CRITICAL_SECTION *critsect = HeapAlloc(GetProcessHeap(), 0, sizeof(CRITICAL_SECTION));
|
||||
InitializeCriticalSection(critsect);
|
||||
|
||||
if (InterlockedCompareExchange((PVOID*)&(((wine_mutex)mutex)->critsect),critsect,NULL) != NULL) {
|
||||
/* too late, some other thread already did it */
|
||||
DeleteCriticalSection(critsect);
|
||||
HeapFree(SystemHeap, 0, critsect);
|
||||
HeapFree(GetProcessHeap(), 0, critsect);
|
||||
}
|
||||
}
|
||||
|
||||
int __pthread_mutex_lock(pthread_mutex_t *mutex)
|
||||
{
|
||||
if (!SystemHeap) return 0;
|
||||
if (!init_done) return 0;
|
||||
if (!((wine_mutex)mutex)->critsect)
|
||||
mutex_real_init( mutex );
|
||||
|
||||
@ -201,7 +207,7 @@ strong_alias(__pthread_mutex_lock, pthread_mutex_lock);
|
||||
|
||||
int __pthread_mutex_trylock(pthread_mutex_t *mutex)
|
||||
{
|
||||
if (!SystemHeap) return 0;
|
||||
if (!init_done) return 0;
|
||||
if (!((wine_mutex)mutex)->critsect)
|
||||
mutex_real_init( mutex );
|
||||
|
||||
@ -233,7 +239,7 @@ int __pthread_mutex_destroy(pthread_mutex_t *mutex)
|
||||
#endif
|
||||
}
|
||||
DeleteCriticalSection(((wine_mutex)mutex)->critsect);
|
||||
HeapFree(SystemHeap, 0, ((wine_mutex)mutex)->critsect);
|
||||
HeapFree(GetProcessHeap(), 0, ((wine_mutex)mutex)->critsect);
|
||||
return 0;
|
||||
}
|
||||
strong_alias(__pthread_mutex_destroy, pthread_mutex_destroy);
|
||||
|
Loading…
x
Reference in New Issue
Block a user