windows-nt/Source/XPSP1/NT/inetsrv/query/bigtable/tmem.cxx
2020-09-26 16:20:57 +08:00

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