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.
135 lines
3.6 KiB
135 lines
3.6 KiB
/***************************************************************************\
|
|
*
|
|
* File: TempHelp.cpp
|
|
*
|
|
* Description:
|
|
* TempHelp.h implements a "lightweight heap", designed to continuously grow
|
|
* until all memory is freed. This is valuable as a temporary heap that can
|
|
* be used to "collect" data and processed slightly later.
|
|
*
|
|
*
|
|
* History:
|
|
* 3/30/2000: JStall: Created
|
|
*
|
|
* Copyright (C) 2000 by Microsoft Corporation. All rights reserved.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "Base.h"
|
|
#include "TempHeap.h"
|
|
|
|
#include "SimpleHeap.h"
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* class TempHeap
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//------------------------------------------------------------------------------
|
|
TempHeap::TempHeap(int cbPageAlloc, int cbLargeThreshold)
|
|
{
|
|
m_ppageCur = NULL;
|
|
m_ppageLarge = NULL;
|
|
m_pbFree = NULL;
|
|
m_cbFree = 0;
|
|
m_cbPageAlloc = cbPageAlloc;
|
|
m_cbLargeThreshold = cbLargeThreshold;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void *
|
|
TempHeap::Alloc(int cbAlloc)
|
|
{
|
|
AssertMsg(cbAlloc > 0, "Must specify a valid allocation size");
|
|
|
|
if (cbAlloc > m_cbLargeThreshold) {
|
|
//
|
|
// Allocating a very large block, so allocate it directly.
|
|
//
|
|
|
|
Page * pageNew = (Page *) ClientAlloc(sizeof(Page) + cbAlloc);
|
|
if (pageNew == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
pageNew->pNext = m_ppageLarge;
|
|
m_ppageLarge = pageNew;
|
|
return pageNew->GetData();
|
|
}
|
|
|
|
if ((m_ppageCur == NULL) || (cbAlloc > m_cbFree)) {
|
|
Page * pageNew = (Page *) ClientAlloc(sizeof(Page) + m_cbPageAlloc);
|
|
if (pageNew == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
pageNew->pNext = m_ppageCur;
|
|
m_ppageCur = pageNew;
|
|
m_cbFree = m_cbPageAlloc;
|
|
m_pbFree = pageNew->GetData();
|
|
}
|
|
|
|
AssertMsg(m_cbFree >= cbAlloc, "Should have enough space to allocate by now");
|
|
|
|
void * pvNew = m_pbFree;
|
|
m_cbFree -= cbAlloc;
|
|
m_pbFree += cbAlloc;
|
|
|
|
return pvNew;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
TempHeap::FreeAll(BOOL fComplete)
|
|
{
|
|
Page * pageNext;
|
|
Page * pageTemp;
|
|
|
|
//
|
|
// Free large-block allocations
|
|
//
|
|
|
|
pageTemp = m_ppageLarge;
|
|
while (pageTemp != NULL) {
|
|
pageNext = pageTemp->pNext;
|
|
ClientFree(pageTemp);
|
|
pageTemp = pageNext;
|
|
}
|
|
m_ppageLarge = NULL;
|
|
|
|
|
|
//
|
|
// Free small-block allocations
|
|
//
|
|
pageTemp = m_ppageCur;
|
|
while (pageTemp != NULL) {
|
|
pageNext = pageTemp->pNext;
|
|
if ((pageNext == NULL) && (!fComplete)) {
|
|
//
|
|
// Don't free the first block, since we will immediately turn around
|
|
// and allocate it again. Instead, renew it.
|
|
//
|
|
|
|
m_ppageCur = pageTemp;
|
|
m_cbFree = m_cbPageAlloc;
|
|
m_pbFree = pageTemp->GetData();
|
|
break;
|
|
}
|
|
|
|
ClientFree(pageTemp);
|
|
pageTemp = pageNext;
|
|
}
|
|
|
|
if (fComplete) {
|
|
m_ppageCur = NULL;
|
|
m_pbFree = NULL;
|
|
m_cbFree = 0;
|
|
}
|
|
}
|