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.
|
|
/*************************************************************************/ /** 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
|