266 lines
5.9 KiB
C++
266 lines
5.9 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999.
|
|
//
|
|
// File: tmem.cxx
|
|
//
|
|
// Contents: tmem - test mem allocators for big tables.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "pch.cxx"
|
|
#pragma hdrstop
|
|
|
|
DECLARE_INFOLEVEL(tb)
|
|
|
|
#include "tblalloc.hxx"
|
|
|
|
BYTE MemPool[4096];
|
|
|
|
//BYTE* PoolPtrs[409];
|
|
//ULONG PoolOffs[409];
|
|
|
|
BOOL fInMemPool = TRUE;
|
|
|
|
|
|
//
|
|
// ReportHeap - report heap blocks
|
|
//
|
|
|
|
void ReportHeap(
|
|
void* pBlock,
|
|
USHORT cbSize,
|
|
USHORT fFree
|
|
) {
|
|
BYTE* pbBlock = (BYTE*) pBlock;
|
|
printf("%08x %d%s\n", pbBlock, cbSize, fFree? " FREE": "");
|
|
|
|
if (fInMemPool &&
|
|
(pbBlock < &MemPool[0] ||
|
|
pbBlock + cbSize > &MemPool[ sizeof MemPool ])) {
|
|
printf("\007***\tpBlock outside mem pool\t***\007");
|
|
}
|
|
}
|
|
|
|
//
|
|
// FreeBlocks -- free some of the allocated blocks
|
|
//
|
|
|
|
void FreeBlocks(
|
|
BYTE* apbPtrs[],
|
|
unsigned cPtrs,
|
|
int fVerbose,
|
|
CWindowDataAllocator& Alloc
|
|
) {
|
|
unsigned i;
|
|
|
|
// Free every third allocated block
|
|
|
|
for (i = 2; i < cPtrs; i += 3) {
|
|
if (apbPtrs[i]) {
|
|
Alloc.Free((void*)apbPtrs[i]);
|
|
apbPtrs[i] = 0;
|
|
}
|
|
}
|
|
|
|
if (fVerbose) {
|
|
printf("\nAfter freeing every third allocation\n");
|
|
Alloc.WalkHeap(ReportHeap);
|
|
}
|
|
|
|
// Free every other allocated block, will cause some coalescing
|
|
|
|
for (i = 0; i < cPtrs; i += 2) {
|
|
if (apbPtrs[i]) {
|
|
Alloc.Free((void*)apbPtrs[i]);
|
|
apbPtrs[i] = 0;
|
|
}
|
|
}
|
|
if (fVerbose) {
|
|
printf("\nAfter freeing every other allocation\n");
|
|
Alloc.WalkHeap(ReportHeap);
|
|
}
|
|
|
|
// Finally, Free every fourth allocated block, will cause more coalescing
|
|
|
|
for (i = 3; i < cPtrs; i += 4) {
|
|
if (apbPtrs[i]) {
|
|
Alloc.Free((void*)apbPtrs[i]);
|
|
apbPtrs[i] = 0;
|
|
}
|
|
}
|
|
if (fVerbose) {
|
|
printf("\nAfter freeing every other allocation\n");
|
|
Alloc.WalkHeap(ReportHeap);
|
|
}
|
|
}
|
|
|
|
|
|
__cdecl main(int argc, char** argv)
|
|
{
|
|
BYTE* pMem = MemPool;
|
|
int fVerbose = 0;
|
|
unsigned i;
|
|
|
|
for (i=1; i<(unsigned)argc; i++) {
|
|
if (argv[i][0] == '-' &&
|
|
tolower(argv[i][1]) == 'v')
|
|
fVerbose++;
|
|
else {
|
|
printf("Usage: %s [-v]\n", argv[0]);
|
|
}
|
|
}
|
|
|
|
// Test the simple allocator with forward allocation.
|
|
memset(pMem, 0xD5, sizeof MemPool);
|
|
CVarBufferAllocator Alloc1(pMem, sizeof MemPool);
|
|
BYTE* pbuf;
|
|
BOOL fBreak = FALSE;
|
|
|
|
for (i=0; i<0xFFFFFFFF && !fBreak; i++)
|
|
{
|
|
TRY
|
|
{
|
|
pbuf = 0;
|
|
pbuf = (BYTE *)Alloc1.Allocate(10);
|
|
}
|
|
CATCH (CException, e)
|
|
{
|
|
if (e.GetErrorCode() == E_OUTOFMEMORY)
|
|
fBreak = TRUE;
|
|
else
|
|
RETHROW();
|
|
}
|
|
END_CATCH
|
|
|
|
if (pbuf)
|
|
memset(pbuf, '0' + i%10, 10);
|
|
}
|
|
Win4Assert(i == sizeof MemPool/10);
|
|
|
|
for (i=0; i<sizeof MemPool - (sizeof MemPool % 10); i++) {
|
|
Win4Assert(MemPool[i] == ((i/10) % 10 + '0'));
|
|
}
|
|
|
|
#if 0
|
|
// Test the simple allocator with top-down allocation.
|
|
memset(pMem, 0xD5, sizeof MemPool);
|
|
CVarBufferAllocator Alloc2(pMem, sizeof MemPool, TRUE);
|
|
|
|
for (i=0; pbuf = (BYTE *)Alloc2.Allocate(10); i++) {
|
|
memset(pbuf, '0' + i%10, 10);
|
|
}
|
|
Win4Assert(i == sizeof MemPool/10);
|
|
|
|
for (i=0; i<sizeof MemPool; i++) {
|
|
if (i < (sizeof MemPool % 10)) {
|
|
Win4Assert(MemPool[i] == 0xD5);
|
|
} else {
|
|
Win4Assert(MemPool[i] ==
|
|
((((sizeof MemPool - 1) - i)/10) % 10 + '0'));
|
|
}
|
|
}
|
|
#endif //0
|
|
|
|
// Test the heap allocator
|
|
memset(pMem, 0, sizeof MemPool);
|
|
|
|
BYTE **paPoolPtrs = (BYTE**)&MemPool;
|
|
unsigned cPoolPtrs = sizeof MemPool / sizeof (BYTE *);
|
|
|
|
CWindowDataAllocator Alloc3;
|
|
|
|
fInMemPool = FALSE;
|
|
for (i=0; pbuf = (BYTE *)Alloc3.Allocate(10); i++) {
|
|
if (i == cPoolPtrs)
|
|
break;
|
|
paPoolPtrs[i] = pbuf;
|
|
memset(pbuf, '0' + i%10, 10);
|
|
}
|
|
Win4Assert(i == cPoolPtrs);
|
|
|
|
for (i=0; i<sizeof MemPool; i++) {
|
|
Win4Assert(paPoolPtrs[i/10][i%10] == ((i/10) % 10 + '0'));
|
|
}
|
|
|
|
if (fVerbose) {
|
|
printf("Grow forward allocation\n");
|
|
Alloc3.WalkHeap(ReportHeap);
|
|
}
|
|
|
|
FreeBlocks(paPoolPtrs, cPoolPtrs, fVerbose, Alloc3);
|
|
|
|
|
|
// Test the fixed/variable allocator
|
|
memset(pMem, 0, sizeof MemPool);
|
|
|
|
Win4Assert(sizeof (BYTE*) == sizeof (ULONG));
|
|
|
|
paPoolPtrs = (BYTE **)&MemPool;
|
|
cPoolPtrs = (sizeof MemPool / sizeof (BYTE *)) / 2;
|
|
|
|
ULONG *paPoolOffs = (ULONG *)&paPoolPtrs[cPoolPtrs];
|
|
|
|
memset(paPoolPtrs, 0, sizeof (BYTE *) * cPoolPtrs);
|
|
memset(paPoolOffs, 0, sizeof (BYTE *) * cPoolPtrs);
|
|
CFixedVarAllocator Alloc4(TRUE, TRUE, 10);
|
|
|
|
// for (i=0; i<sizeof MemPool; i++) {
|
|
// Alloc4.SetLimit(i);
|
|
// Win4Assert(Alloc4.Limit() == i);
|
|
// }
|
|
//
|
|
// Alloc4.SetLimit(1000);
|
|
|
|
for (i=0; (pbuf = (BYTE *)Alloc4.Allocate(10)) && i < cPoolPtrs; i++) {
|
|
memset(pbuf, '0' + i%10, 10);
|
|
paPoolOffs[i] = Alloc4.PointerToOffset(pbuf);
|
|
|
|
pbuf = (BYTE*)Alloc4.AllocFixed();
|
|
memset(pbuf, '9' - i%10, 10);
|
|
}
|
|
Win4Assert(i == cPoolPtrs);
|
|
|
|
CWindowDataAllocator* pVAlloc = Alloc4.VarAllocator();
|
|
if (fVerbose && pVAlloc) {
|
|
printf("\nFixed/Var allocation\n");
|
|
pVAlloc->WalkHeap(ReportHeap);
|
|
}
|
|
|
|
if (pVAlloc) {
|
|
for (i=0; i<cPoolPtrs; i++) {
|
|
if (paPoolOffs[i]) {
|
|
paPoolPtrs[i] = (BYTE*)Alloc4.OffsetToPointer(paPoolOffs[i]);
|
|
}
|
|
}
|
|
FreeBlocks(paPoolPtrs, cPoolPtrs, fVerbose, *pVAlloc);
|
|
}
|
|
|
|
|
|
// Test the fixed/variable allocator
|
|
memset(pMem, 0, sizeof MemPool);
|
|
|
|
Win4Assert(sizeof (BYTE*) == sizeof (ULONG));
|
|
|
|
paPoolPtrs = (BYTE **)&MemPool;
|
|
cPoolPtrs = (sizeof MemPool / sizeof (BYTE *));
|
|
|
|
memset(paPoolPtrs, 0, sizeof (BYTE *) * cPoolPtrs);
|
|
CFixedVarAllocator Alloc5(TRUE, TRUE, 0x28);
|
|
|
|
for (i=0; (pbuf = (BYTE *)Alloc5.AllocFixed()) && i < cPoolPtrs; i++) {
|
|
memset(pbuf, '0' + i%10, 0x28);
|
|
}
|
|
Win4Assert(i == cPoolPtrs);
|
|
|
|
for (i=0; i<cPoolPtrs; i++) {
|
|
if (paPoolOffs[i]) {
|
|
paPoolPtrs[i] = (BYTE*)Alloc5.OffsetToPointer(paPoolOffs[i]);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|