Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
oscheap.c
Abstract:
This module contains "local" heap management code for OS Chooser.
Author:
Geoff Pease (gpease) May 28 1998
Revision History:
--*/
#ifdef i386
#include "bldrx86.h"
#endif
#if defined(_IA64_)
#include "bldria64.h"
#endif
#include "netfs.h"
#include "oscheap.h"
#define FREE_POOL_TAG 0x0
#define ALLOC_POOL_TAG 0x1
typedef struct _LOCAL_MEMORY_DESCRIPTOR {
//
// We create a union to make sure that this struct is always at least the size of a
// pointer, and thus will be pointer aligned.
//
union {
struct { ULONG Tag; ULONG Size; };
struct { void *Align; };
};
} LOCAL_MEMORY_DESCRIPTOR, *PLOCAL_MEMORY_DESCRIPTOR;
//
// Variable for holding our memory together.
//
#ifdef EFI
#define OSCHEAPSIZE 0x4000 // 16k
#else
#define OSCHEAPSIZE 0x2000 // 8k
#endif
CHAR OscHeap[ OSCHEAPSIZE ];
//
// Functions
//
void OscHeapInitialize( VOID ) /*++
Routine Description:
This routine initializes the internal memory management system.
Arguments:
None.
Return Value:
None.
--*/
{ PLOCAL_MEMORY_DESCRIPTOR LocalDescriptor;
LocalDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)OscHeap;
LocalDescriptor->Tag = FREE_POOL_TAG; LocalDescriptor->Size = OSCHEAPSIZE - sizeof(LOCAL_MEMORY_DESCRIPTOR);
memset((PVOID)(LocalDescriptor + 1), 0, LocalDescriptor->Size); }
PCHAR OscHeapAlloc( IN UINT iSize )
/*++
Routine Description:
This routine allocates memory from our internal structures.
Arguments:
iSize - Number of bytes the client wants. Return Value:
A pointer to the allocated block if successful, else NULL
--*/
{ PLOCAL_MEMORY_DESCRIPTOR LocalDescriptor; PLOCAL_MEMORY_DESCRIPTOR NextDescriptor; LONG ThisBlockSize; ULONG BytesToAllocate;
//
// Always allocate in increments of a pointer, minmally.
//
if (iSize & (sizeof(void *) - 1)) { iSize += sizeof(void *) - (iSize & (sizeof(void *) - 1)); }
LocalDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)OscHeap; ThisBlockSize = OSCHEAPSIZE - sizeof(LOCAL_MEMORY_DESCRIPTOR);
while (ThisBlockSize > 0) {
if ((LocalDescriptor->Tag == FREE_POOL_TAG) && (LocalDescriptor->Size >= iSize)) { goto FoundBlock; }
ThisBlockSize -= (LocalDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR)); LocalDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)(((PUCHAR)LocalDescriptor) + LocalDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR) ); }
//
// There is no memory block big enough to hold the request.
//
return NULL; FoundBlock:
//
// Jump to here when a memory descriptor of the right size has been found. It is expected that
// LocalDescriptor points to the correct block.
//
if (LocalDescriptor->Size > iSize + sizeof(LOCAL_MEMORY_DESCRIPTOR)) {
//
// Make a descriptor of the left over parts of this block.
//
NextDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)(((PUCHAR)LocalDescriptor) + sizeof(LOCAL_MEMORY_DESCRIPTOR) + iSize );
NextDescriptor->Tag = FREE_POOL_TAG; NextDescriptor->Size = (ULONG)(LocalDescriptor->Size - iSize - sizeof(LOCAL_MEMORY_DESCRIPTOR)); LocalDescriptor->Size = (ULONG)iSize;
}
LocalDescriptor->Tag = ALLOC_POOL_TAG;
memset((LocalDescriptor+1), 0, iSize);
return (PCHAR)(LocalDescriptor + 1);
}
PCHAR OscHeapFree( IN PCHAR Pointer )
/*++
Routine Description:
This routine frees a block previously allocated from the internal memory management system.
Arguments:
Pointer - A pointer to free.
Return Value:
NULL.
--*/
{ LONG ThisBlockSize; PLOCAL_MEMORY_DESCRIPTOR LocalDescriptor; PLOCAL_MEMORY_DESCRIPTOR PrevDescriptor; PLOCAL_MEMORY_DESCRIPTOR ThisDescriptor;
LocalDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)(((PUCHAR)Pointer) - sizeof(LOCAL_MEMORY_DESCRIPTOR));
//
// Find the memory block in the heap
//
PrevDescriptor = NULL; ThisDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)OscHeap; ThisBlockSize = OSCHEAPSIZE - sizeof(LOCAL_MEMORY_DESCRIPTOR);
while (ThisBlockSize > 0) { if (ThisDescriptor == LocalDescriptor) { goto FoundBlock; }
ThisBlockSize -= (ThisDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR)); PrevDescriptor = ThisDescriptor; ThisDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)(((PUCHAR)ThisDescriptor) + ThisDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR) ); }
return NULL;
FoundBlock:
//
// Jump to here when the proper memory descriptor has been found.
//
if (LocalDescriptor->Tag == FREE_POOL_TAG) { //
// Ouch! We tried to free something twice, skip it before bad things happen.
//
return NULL; }
LocalDescriptor->Tag = FREE_POOL_TAG;
//
// If possible, merge this memory block with the next one.
//
if ((ULONG)ThisBlockSize > (LocalDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR))) { ThisDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)(((PUCHAR)LocalDescriptor) + LocalDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR) ); if (ThisDescriptor->Tag == FREE_POOL_TAG) { LocalDescriptor->Size += ThisDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR); ThisDescriptor->Tag = 0; ThisDescriptor->Size = 0; }
}
//
// Now see if we can merge this block with a previous block.
//
if ((PrevDescriptor != NULL) && (PrevDescriptor->Tag == FREE_POOL_TAG)) { PrevDescriptor->Size += LocalDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR); LocalDescriptor->Tag = 0; LocalDescriptor->Size = 0; }
return NULL; }
|