Leaked source code of windows server 2003
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.
 
 
 
 
 
 

199 lines
5.8 KiB

/*************************************************************************/
/** Copyright(c) Microsoft Corp., 1993-1999 **/
/*************************************************************************/
/**************************************************************************
File FreeListMgr.cxx
Title :Get and Put functions for the MIDL compiler
History :
13-Apr-94 GregJen Created from freelist.hxx
**************************************************************************/
#pragma warning ( disable : 4201 ) // Unnamed struct/union
#pragma warning ( disable : 4514 ) // Unreferenced inline function
/*************************************************************************
** includes
*************************************************************************/
#include "freelist.hxx"
#include <windef.h> // REVIEW: Just give up and include windows.h?
#include <basetsd.h>
// checked compiler has list checking
#ifndef NDEBUG
// turn on the below flag to get checked freelist
#define LIST_CHECK
#endif
/*************************************************************************
** definitions
*************************************************************************/
// The user should see allocated memory aligned at LONG_PTR alignment.
// The allocator returns us memory with this alignment so make sure the
// signature preserves it.
typedef LONG_PTR HeapSignature;
#define USED_SIGNATURE( pMgr, pNode ) \
( ((HeapSignature) pMgr) % ((HeapSignature) pNode) )
#define FREE_SIGNATURE( pMgr, pNode ) \
( ((HeapSignature) pMgr) - ((HeapSignature) pNode) )
void *
FreeListMgr::Get (size_t size)
{
void * pEntry;
#ifdef LIST_CHECK
HeapSignature * pSignature;
#endif
/* Count this call (even if it fails).
*/
#ifndef NDEBUG
GetCount++;
#endif
/* Make sure the "size" requested is the same as the previous
* requests.
*/
MIDL_ASSERT (size == element_size);
/* Get an entry from the free-list, if the free-list is not empty */
if (pHead != NULL)
{
pEntry = pHead;
pHead = pHead->next;
#ifdef LIST_CHECK
// check to make sure the entry is really OK
// signature is before entry pointer
// signature of free nodes is ( &mgr - &node )
// signature of used nodes is ( &mgr % &node )
pSignature = ((HeapSignature *)pEntry)-1;
MIDL_ASSERT( *pSignature == FREE_SIGNATURE( this, pEntry ) );
*pSignature = USED_SIGNATURE( this, pEntry );
memset( pEntry, 0xB3, size );
#endif
return (void *) pEntry;
}
/* Get it from the allocator, since the free-list is empty */
else
{
#ifdef LIST_CHECK
pSignature = (HeapSignature *)
AllocateOnceNew( size + sizeof( *pSignature ) );
pEntry = ( (char *) pSignature ) + sizeof( *pSignature );
*pSignature = USED_SIGNATURE( this, pEntry );
memset( pEntry, 0xB2, size );
return pEntry;
#else
return AllocateOnceNew(size);
#endif
}
} /* Get */
/*********************************************************************/
// This routine "releases" the given element, by putting it on
// the free-list for later re-use. The given element, must be
// the same size as the elements provided by the "Get" function.
/*********************************************************************/
void
FreeListMgr::Put (void * pEntry)
{
#ifdef LIST_CHECK
HeapSignature * pSignature;
#endif
// Count this call.
#ifndef NDEBUG
PutCount++;
#endif
// Put the given element on the head of the free-list.
#ifdef LIST_CHECK
// check to make sure the entry is really OK
// signature is before entry pointer
// signature of free nodes is ( &mgr - &node )
// signature of used nodes is ( &mgr % &node )
pSignature = ((HeapSignature *)pEntry)-1;
MIDL_ASSERT( *pSignature == USED_SIGNATURE( this, pEntry ) );
*pSignature = FREE_SIGNATURE( this, pEntry );
memset( pEntry, 0xA1, element_size );
#endif
( (FreeListType *) pEntry ) -> next = pHead;
pHead = (FreeListType *) pEntry;
}; /* Put */
#ifdef example
//
// Example of use...
//
// copy the following into a class definition and replace the X's with
// the name of the class
//
/*********************************************************************/
// here is the free list manager for a particular class. it should
// NOT be inherited unless the derived classes have no extra data members.
//
// Otherwise, the derived classes should have their own new and delete
// elsewhere.
/*********************************************************************/
private:
static
FreeListMgr MyFreeList( sizeof( X ) );
public:
/*********************************************************************/
// Return a new element of the specified size.
//
// The FreeListMgr "Get" routine is used, so that the element may be
// retrieved from a free-list, if possible, and extra get-memory calls
// can thus be avoided.
/*********************************************************************/
X *
operator new (size_t size)
{
return (MyFreeList.Get (size));
}
/*********************************************************************/
// Release an element allocated by the "New" routine.
//
/*********************************************************************/
void operator delete (X* pX)
{
MyFreeList.Put (pX);
}
#endif // example