MMHeap.cpp revision 35629f6a5aa1bfd6a390794014c810c9700357eb
/* $Id$ */
/** @file
* MM - Memory Manager - Heap.
*/
/*
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_MM_HEAP
#include "MMInternal.h"
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
/**
* Allocate and initialize a heap structure and it's associated substructures.
*
* @returns VBox status.
* @param pVM The handle to the VM the heap should be associated with.
* @param ppHeap Where to store the heap pointer.
*/
{
if (pHeap)
{
if (RT_SUCCESS(rc))
{
/*
* Initialize the global stat record.
*/
#ifdef MMR3HEAP_WITH_STATISTICS
STAMR3RegisterU(pUVM, &pStat->cAllocations, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, "/MM/R3Heap/cAllocations", STAMUNIT_CALLS, "Number or MMR3HeapAlloc() calls.");
STAMR3RegisterU(pUVM, &pStat->cReallocations, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, "/MM/R3Heap/cReallocations", STAMUNIT_CALLS, "Number of MMR3HeapRealloc() calls.");
STAMR3RegisterU(pUVM, &pStat->cFrees, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, "/MM/R3Heap/cFrees", STAMUNIT_CALLS, "Number of MMR3HeapFree() calls.");
STAMR3RegisterU(pUVM, &pStat->cFailures, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, "/MM/R3Heap/cFailures", STAMUNIT_COUNT, "Number of failures.");
STAMR3RegisterU(pUVM, &pStat->cbCurAllocated, sizeof(pStat->cbCurAllocated) == sizeof(uint32_t) ? STAMTYPE_U32 : STAMTYPE_U64,
STAMVISIBILITY_ALWAYS, "/MM/R3Heap/cbCurAllocated", STAMUNIT_BYTES, "Number of bytes currently allocated.");
STAMR3RegisterU(pUVM, &pStat->cbAllocated, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, "/MM/R3Heap/cbAllocated", STAMUNIT_BYTES, "Total number of bytes allocated.");
STAMR3RegisterU(pUVM, &pStat->cbFreed, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, "/MM/R3Heap/cbFreed", STAMUNIT_BYTES, "Total number of bytes freed.");
#endif
return VINF_SUCCESS;
}
}
AssertMsgFailed(("failed to allocate heap structure\n"));
return VERR_NO_MEMORY;
}
/**
* Destroy a heap.
*
* @param pHeap Heap handle.
*/
{
/*
* Start by deleting the lock, that'll trap anyone
* attempting to use the heap.
*/
/*
* Walk the node list and free all the memory.
*/
while (pHdr)
{
}
/*
* Free the stat nodes.
*/
/** @todo free all nodes in a AVL tree. */
}
/**
* Allocate memory associating it with the VM for collective cleanup.
*
* The memory will be allocated from the default heap but a header
* is added in which we keep track of which VM it belongs to and chain
* all the allocations together so they can be freed in one go.
*
* This interface is typically used for memory block which will not be
* freed during the life of the VM.
*
* @returns Pointer to allocated memory.
* @param pUVM Pointer to the user mode VM structure.
* @param enmTag Statistics tag. Statistics are collected on a per tag
* basis in addition to a global one. Thus we can easily
* identify how memory is used by the VM.
* @param cbSize Size of the block.
*/
{
}
/**
* Allocate memory associating it with the VM for collective cleanup.
*
* The memory will be allocated from the default heap but a header
* is added in which we keep track of which VM it belongs to and chain
* all the allocations together so they can be freed in one go.
*
* This interface is typically used for memory block which will not be
* freed during the life of the VM.
*
* @returns Pointer to allocated memory.
* @param pVM VM handle.
* @param enmTag Statistics tag. Statistics are collected on a per tag
* basis in addition to a global one. Thus we can easily
* identify how memory is used by the VM.
* @param cbSize Size of the block.
*/
{
}
/**
* Same as MMR3HeapAllocU().
*
* @returns Pointer to allocated memory.
* @param pUVM Pointer to the user mode VM structure.
* @param enmTag Statistics tag. Statistics are collected on a per tag
* basis in addition to a global one. Thus we can easily
* identify how memory is used by the VM.
* @param cbSize Size of the block.
* @param ppv Where to store the pointer to the allocated memory on success.
*/
{
if (pv)
{
return VINF_SUCCESS;
}
return VERR_NO_MEMORY;
}
/**
* Same as MMR3HeapAlloc().
*
* @returns Pointer to allocated memory.
* @param pVM VM handle.
* @param enmTag Statistics tag. Statistics are collected on a per tag
* basis in addition to a global one. Thus we can easily
* identify how memory is used by the VM.
* @param cbSize Size of the block.
* @param ppv Where to store the pointer to the allocated memory on success.
*/
{
if (pv)
{
return VINF_SUCCESS;
}
return VERR_NO_MEMORY;
}
/**
* Same as MMR3HeapAlloc() only the memory is zeroed.
*
* @returns Pointer to allocated memory.
* @param pUVM Pointer to the user mode VM structure.
* @param enmTag Statistics tag. Statistics are collected on a per tag
* basis in addition to a global one. Thus we can easily
* identify how memory is used by the VM.
* @param cbSize Size of the block.
*/
{
}
/**
* Same as MMR3HeapAlloc() only the memory is zeroed.
*
* @returns Pointer to allocated memory.
* @param pVM VM handle.
* @param enmTag Statistics tag. Statistics are collected on a per tag
* basis in addition to a global one. Thus we can easily
* identify how memory is used by the VM.
* @param cbSize Size of the block.
*/
{
}
/**
* Same as MMR3HeapAllocZ().
*
* @returns Pointer to allocated memory.
* @param pUVM Pointer to the user mode VM structure.
* @param enmTag Statistics tag. Statistics are collected on a per tag
* basis in addition to a global one. Thus we can easily
* identify how memory is used by the VM.
* @param cbSize Size of the block.
* @param ppv Where to store the pointer to the allocated memory on success.
*/
{
if (pv)
{
return VINF_SUCCESS;
}
return VERR_NO_MEMORY;
}
/**
* Same as MMR3HeapAllocZ().
*
* @returns Pointer to allocated memory.
* @param pVM VM handle.
* @param enmTag Statistics tag. Statistics are collected on a per tag
* basis in addition to a global one. Thus we can easily
* identify how memory is used by the VM.
* @param cbSize Size of the block.
* @param ppv Where to store the pointer to the allocated memory on success.
*/
{
if (pv)
{
return VINF_SUCCESS;
}
return VERR_NO_MEMORY;
}
/**
* Allocate memory from the heap.
*
* @returns Pointer to allocated memory.
* @param pHeap Heap handle.
* @param enmTag Statistics tag. Statistics are collected on a per tag
* basis in addition to a global one. Thus we can easily
* identify how memory is used by the VM.
* @param cbSize Size of the block.
* @param fZero Whether or not to zero the memory block.
*/
{
#ifdef MMR3HEAP_WITH_STATISTICS
/*
*/
if (pStat)
{
pStat->cAllocations++;
}
else
{
if (!pStat)
{
AssertMsgFailed(("Failed to allocate heap stat record.\n"));
return NULL;
}
pStat->cAllocations++;
/* register the statistics */
STAMR3RegisterFU(pUVM, &pStat->cbCurAllocated, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Number of bytes currently allocated.", "/MM/R3Heap/%s", pszTag);
STAMR3RegisterFU(pUVM, &pStat->cAllocations, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS, "Number or MMR3HeapAlloc() calls.", "/MM/R3Heap/%s/cAllocations", pszTag);
STAMR3RegisterFU(pUVM, &pStat->cReallocations, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS, "Number of MMR3HeapRealloc() calls.", "/MM/R3Heap/%s/cReallocations", pszTag);
STAMR3RegisterFU(pUVM, &pStat->cFrees, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS, "Number of MMR3HeapFree() calls.", "/MM/R3Heap/%s/cFrees", pszTag);
STAMR3RegisterFU(pUVM, &pStat->cFailures, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Number of failures.", "/MM/R3Heap/%s/cFailures", pszTag);
STAMR3RegisterFU(pUVM, &pStat->cbAllocated, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Total number of bytes allocated.", "/MM/R3Heap/%s/cbAllocated", pszTag);
STAMR3RegisterFU(pUVM, &pStat->cbFreed, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Total number of bytes freed.", "/MM/R3Heap/%s/cbFreed", pszTag);
}
#endif
/*
* Validate input.
*/
if (cbSize == 0)
{
#ifdef MMR3HEAP_WITH_STATISTICS
#endif
return NULL;
}
/*
* Allocate heap block.
*/
if (!pHdr)
{
#ifdef MMR3HEAP_WITH_STATISTICS
#endif
return NULL;
}
/*
* Init and link in the header.
*/
else
#ifdef MMR3HEAP_WITH_STATISTICS
#else
#endif
/*
* Update statistics
*/
#ifdef MMR3HEAP_WITH_STATISTICS
#endif
return pHdr + 1;
}
/**
* Reallocate memory allocated with MMR3HeapAlloc() or MMR3HeapRealloc().
*
* @returns Pointer to reallocated memory.
* @param pv Pointer to the memory block to reallocate.
* Must not be NULL!
* @param cbNewSize New block size.
*/
{
if (!pv)
return NULL;
/*
* If newsize is zero then this is a free.
*/
if (!cbNewSize)
{
return NULL;
}
/*
* Validate header.
*/
{
return NULL;
}
#ifdef MMR3HEAP_WITH_STATISTICS
#endif
/*
* Rellocate the block.
*/
if (!pHdrNew)
{
#ifdef MMR3HEAP_WITH_STATISTICS
#endif
return NULL;
}
/*
* Update pointers.
*/
{
else
else
}
/*
* Update statistics.
*/
#ifdef MMR3HEAP_WITH_STATISTICS
#endif
return pHdrNew + 1;
}
/**
* Duplicates the specified string.
*
* @returns Pointer to the duplicate.
* @returns NULL on failure or when input NULL.
* @param pUVM Pointer to the user mode VM structure.
* @param enmTag Statistics tag. Statistics are collected on a per tag
* basis in addition to a global one. Thus we can easily
* identify how memory is used by the VM.
* @param psz The string to duplicate. NULL is allowed.
*/
{
if (!psz)
return NULL;
if (pszDup)
return pszDup;
}
/**
* Duplicates the specified string.
*
* @returns Pointer to the duplicate.
* @returns NULL on failure or when input NULL.
* @param pVM The VM handle.
* @param enmTag Statistics tag. Statistics are collected on a per tag
* basis in addition to a global one. Thus we can easily
* identify how memory is used by the VM.
* @param psz The string to duplicate. NULL is allowed.
*/
{
}
/**
* Allocating string printf.
*
* @returns Pointer to the string.
* @param pVM The VM
* @param enmTag The statistics tag.
* @param pszFormat The format string.
* @param ... Format arguments.
*/
{
return psz;
}
/**
* Allocating string printf.
*
* @returns Pointer to the string.
* @param pUVM Pointer to the user mode VM structure.
* @param enmTag The statistics tag.
* @param pszFormat The format string.
* @param ... Format arguments.
*/
{
return psz;
}
/**
* Allocating string printf.
*
* @returns Pointer to the string.
* @param pVM The VM
* @param enmTag The statistics tag.
* @param pszFormat The format string.
* @param va Format arguments.
*/
{
}
/**
* Allocating string printf.
*
* @returns Pointer to the string.
* @param pUVM Pointer to the user mode VM structure.
* @param enmTag The statistics tag.
* @param pszFormat The format string.
* @param va Format arguments.
*/
{
/*
* The lazy bird way.
*/
char *psz;
if (cch < 0)
return NULL;
if (pszRet)
return pszRet;
}
/**
* Releases memory allocated with MMR3HeapAlloc() or MMR3HeapRealloc().
*
* @param pv Pointer to the memory block to free.
*/
{
/* Ignore NULL pointers. */
if (!pv)
return;
/*
* Validate header.
*/
{
return;
}
/*
* Update statistics
*/
#ifdef MMR3HEAP_WITH_STATISTICS
#endif
/*
* Unlink it.
*/
else
else
/*
* Free the memory.
*/
}