Only create the system heap when we actually need it.

This commit is contained in:
Alexandre Julliard 2001-02-23 01:37:05 +00:00
parent 61d32b4e0d
commit 7f187e5043
4 changed files with 68 additions and 111 deletions

View file

@ -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 */

View file

@ -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;

View file

@ -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;

View file

@ -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);