Source code of Windows XP (NT5)
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.
|
|
//
// REGMEM.C
//
// Copyright (C) Microsoft Corporation, 1995
//
// Upper-level memory management functions that discards unlocked memory blocks
// as required to fulfill allocation requests.
//
// For the ring zero version of this code, only large requests will call these
// functions. For most registry files, these requests will already be an
// integral number of pages, so it's best just to do page allocations. Small
// allocations, such as key handles, will use the heap services and not go
// through this code.
//
// For all other models of this code, all memory requests will go through this
// code and memory is allocated from the heap.
//
#include "pch.h"
DECLARE_DEBUG_COUNT(g_RgMemoryBlockCount);
// For the ring zero version, only large allocations that should be page
// aligned will pass through these functions.
#ifdef VXD
// Converts number of bytes to number of whole pages.
#define ConvertToMemoryUnits(cb) \
((((cb) + (PAGESIZE - 1)) & ~(PAGESIZE - 1)) >> PAGESHIFT)
// Generates smaller code if we don't just make this a macro...
LPVOID INTERNAL RgAllocMemoryUnits( UINT nPages ) {
return AllocPages(nPages);
}
// Generates smaller code if we don't just make this a macro...
LPVOID INTERNAL RgReAllocMemoryUnits( LPVOID lpMemory, UINT nPages ) {
return ReAllocPages(lpMemory, nPages);
}
#define RgFreeMemoryUnits FreePages
// For non-ring zero version of the registry code, all allocations will funnel
// through these functions. All allocations are off the heap.
#else
#define ConvertToMemoryUnits(cb) (cb)
#define RgAllocMemoryUnits AllocBytes
#define RgReAllocMemoryUnits ReAllocBytes
#define RgFreeMemoryUnits FreeBytes
#endif
//
// RgAllocMemory
//
LPVOID INTERNAL RgAllocMemory( UINT cbBytes ) {
UINT MemoryUnits; LPVOID lpMemory;
ASSERT(cbBytes > 0);
MemoryUnits = ConvertToMemoryUnits(cbBytes);
// Can we allocate from available memory?
if (!IsNullPtr((lpMemory = RgAllocMemoryUnits(MemoryUnits)))) { INCREMENT_DEBUG_COUNT(g_RgMemoryBlockCount); return lpMemory; }
RgEnumFileInfos(RgSweepFileInfo);
// Can we allocate after sweeping all old memory blocks?
if (!IsNullPtr((lpMemory = RgAllocMemoryUnits(MemoryUnits)))) { INCREMENT_DEBUG_COUNT(g_RgMemoryBlockCount); return lpMemory; }
// The first sweep will have cleared all the access bits of every memory
// block. This sweep will effectively discard all unlocked blocks.
RgEnumFileInfos(RgSweepFileInfo);
// Can we allocate after sweeping all unlocked and clean memory blocks?
if (!IsNullPtr((lpMemory = RgAllocMemoryUnits(MemoryUnits)))) { INCREMENT_DEBUG_COUNT(g_RgMemoryBlockCount); return lpMemory; }
// Flush out every dirty memory block and sweep again.
RgEnumFileInfos(RgFlushFileInfo); RgEnumFileInfos(RgSweepFileInfo);
// Can we allocate after sweeping all unlocked memory blocks?
if (!IsNullPtr((lpMemory = RgAllocMemoryUnits(MemoryUnits)))) { INCREMENT_DEBUG_COUNT(g_RgMemoryBlockCount); return lpMemory; }
DEBUG_OUT(("RgAllocMemory failure\n")); // Return lpMemory, which must be NULL if we're here, generates smaller
// code.
return lpMemory; // Must be NULL if we're here
}
//
// RgReAllocMemory
//
LPVOID INTERNAL RgReAllocMemory( LPVOID lpOldMemory, UINT cbBytes ) {
UINT MemoryUnits; LPVOID lpMemory;
ASSERT(!IsNullPtr(lpOldMemory)); ASSERT(cbBytes > 0);
MemoryUnits = ConvertToMemoryUnits(cbBytes);
// Can we allocate from available memory?
if (!IsNullPtr((lpMemory = RgReAllocMemoryUnits(lpOldMemory, MemoryUnits)))) return lpMemory;
RgEnumFileInfos(RgSweepFileInfo);
// Can we allocate after sweeping all old memory blocks?
if (!IsNullPtr((lpMemory = RgReAllocMemoryUnits(lpOldMemory, MemoryUnits)))) return lpMemory;
// The first sweep will have cleared all the access bits of every memory
// block. This sweep will effectively discard all unlocked blocks.
RgEnumFileInfos(RgSweepFileInfo);
// Can we allocate after sweeping all unlocked and clean memory blocks?
if (!IsNullPtr((lpMemory = RgReAllocMemoryUnits(lpOldMemory, MemoryUnits)))) return lpMemory;
// Flush out every dirty memory block and sweep again.
RgEnumFileInfos(RgFlushFileInfo); RgEnumFileInfos(RgSweepFileInfo);
// Can we allocate after sweeping all unlocked memory blocks?
if (!IsNullPtr((lpMemory = RgReAllocMemoryUnits(lpOldMemory, MemoryUnits)))) return lpMemory;
DEBUG_OUT(("RgReAllocMemory failure\n")); // Return lpMemory, which must be NULL if we're here, generates smaller
// code.
return lpMemory;
}
#ifdef DEBUG
//
// RgFreeMemory
//
VOID INTERNAL RgFreeMemory( LPVOID lpMemory ) {
ASSERT(!IsNullPtr(lpMemory));
DECREMENT_DEBUG_COUNT(g_RgMemoryBlockCount);
#ifdef ZEROONFREE
ZeroMemory(lpMemory, MemorySize(lpMemory)); #endif
RgFreeMemoryUnits(lpMemory);
} #endif
|