//+----------------------------------------------------------------------- // // File: pagealloc.hxx // // Contents: Special fast allocator to allocate fixed-sized entities. // // Classes: CPageAllocator // // History: 02-Feb-96 Rickhi Created // //------------------------------------------------------------------------- #ifndef _PAGEALLOC_HXX_ #define _PAGEALLOC_HXX_ //+------------------------------------------------------------------------ // // struct: PageEntry. This is one entry in the page alloctor. // //+------------------------------------------------------------------------ typedef struct tagPageEntry { struct tagPageEntry *pNext; // next page in list struct tagPageEntry *pPrev; // prev page in list } PageEntry; // Page Table constants for Index manipulation. // The high 16bits of the PageEntry index provides the index to the page // where the PageEntry is located. The lower 16bits provides the index // within the page where the PageEntry is located. #define PAGETBL_PAGESHIFT 16 #define PAGETBL_PAGEMASK 0x0000ffff //+------------------------------------------------------------------------ // // class: CPageAllocator // // Synopsis: special fast allocator for fixed-sized entities. // // Notes: The table has two-levels. The top level is an array of ptrs // to "pages" of entries. Each "page" is an array of entries // of a given size (specified at init time). This allows us to // grow the table by adding a new "page" and extending the top // level by one more pointer, while allowing the existing entries // to remain at the same address throughout their life times. // // A 32bit entry index can be computed for any entry. It consists // if two 16bit indices, one for the page pointer index, and // and one for the entry index on the page. There is also a // function to compute the entry address from its index. // // This allocator is used for various internal DCOM tables. // The main points are to keep related data close together // to reduce working set, minimize allocation time, allow // verifiable handles (indexs) that can be passed outside, and // to make debugging easier (since all data is kept in tables // its easier to find in the debugger). // // Tables using instances of this allocator are: // CMIDTable COXIDTable CIPIDTable CRIFTable // // History: 02-Feb-96 Rickhi Created // //------------------------------------------------------------------------- class CPageAllocator { public: PageEntry *AllocEntry(); // return ptr to first free entry void ReleaseEntry(PageEntry *); // return an entry to the free list void ReleaseEntryList(PageEntry *pFirst, PageEntry *pLast); LONG GetEntryIndex(PageEntry *pEntry); BOOL IsValidIndex(LONG iEntry); // TRUE if index is valid PageEntry *GetEntryPtr(LONG iEntry); // return ptr based on index // initialize the table void Initialize(LONG cbPerEntry, LONG cEntryPerPage); void Cleanup(); // cleanup the table private: void Grow(); // grows the table LONG _cPages; // count of pages in the page list PageEntry **_pPageListStart; // ptr to start of page list PageEntry **_pPageListEnd; // ptr to end of page list PageEntry *_pFirstFreeEntry; // ptr to first free page entry LONG _cbPerEntry; // count of bytes in a single page entry LONG _cEntriesPerPage; // # of page entries in a page }; #endif // _PAGEALLOC_HXX_