|
|
#ifndef _HEAP_HPP_
#define _HEAP_HPP_
// Ruler
// 1 2 3 4 5 6 7 8
//345678901234567890123456789012345678901234567890123456789012345678901234567890
/********************************************************************/ /* */ /* The standard layout. */ /* */ /* The standard layout for 'hpp' files for this code is as */ /* follows: */ /* */ /* 1. Include files. */ /* 2. Constants exported from the class. */ /* 3. Data structures exported from the class. */ /* 4. Forward references to other data structures. */ /* 5. Class specifications (including inline functions). */ /* 6. Additional large inline functions. */ /* */ /* Any portion that is not required is simply omitted. */ /* */ /********************************************************************/
#include "Global.hpp"
#include "Environment.hpp"
#include "Common.hpp"
#include "Find.hpp"
#include "NewPage.hpp"
#include "Prefetch.hpp"
#include "Rockall.hpp"
/********************************************************************/ /* */ /* Class forward references. */ /* */ /* We need to refer to the following classes before they are */ /* fully specified so here we list them as forward references. */ /* */ /********************************************************************/
class BUCKET; class CACHE;
/********************************************************************/ /* */ /* The heap interface. */ /* */ /* The traditional memory allocation interface only supports */ /* a single allocation heap. This memory allocator supports */ /* multiple allocation heaps. However, the interface nicely */ /* hides this so at this point we are back to the traditional */ /* single heap interface. */ /* */ /********************************************************************/
class HEAP : public ENVIRONMENT, public COMMON { //
// Private data.
//
// The heap is the top level container of all the
// functionality in the other classes. The 'Active'
// flag indicates if the heap has been initialized.
// The 'MaxFreePages' controls the amount of free
// space the heap will slave before it starts to
// return it the the external allocator. The
// 'SmallestParentMask' is mask that shows which
// parts of an address can be safely masked off
// and still ensure a hit in the find lookaside
// cache. The 'ThreadSafe' flag indicates whether
// locking being used.
//
BOOLEAN Active; SBIT32 MaxFreePages; BIT32 SmallestParentMask; BOOLEAN ThreadSafe;
//
// A heap is merely a collection of fixed sized
// allocation buckets (each with an optional cache).
// The 'CachesSize' is the total number of buckets.
// The 'MinCacheSize' is the allocation size of the
// smallest bucket. The 'MidCacheSize' is the size
// of the bucket where the stride changes. The
// 'MaxCacheSize' is the allocation size of the
// largest bucket externally visable.
//
SBIT32 CachesSize; SBIT32 MinCacheSize; SBIT32 MidCacheSize; SBIT32 MaxCacheSize;
//
// A key function of the heap is to convert the
// requested allocation size into a pointer to
// the appropriate bucket (and cache). This has
// to be very fast and is achieved using a direct
// lookup (i.e. an array). The lookup array
// consists of two sections (i.e. for small sizes
// and large sizes) to minimize space. The
// 'MaxTable1' and 'MaxTable2' variables contain
// the size of each section of the array. The
// 'ShiftSize1' and 'ShiftSize2' variables contain
// the shift that should be applied to the size to
// obtain the appropriate index. The 'SizeToCache1'
// and 'SizeToCache2' pointers refer to the direct
// lookup tables.
//
SBIT32 MaxTable1; SBIT32 MaxTable2; SBIT32 ShiftSize1; SBIT32 ShiftSize2; CACHE **SizeToCache1; CACHE **SizeToCache2;
//
// The heap needs to have access to most of the
// other classes. The 'Caches' class sits on
// top of an allocation bucket which owns all
// the allocated memory for a given size. The
// 'ExternalCache' is a special bucket that
// contains weird sized pages. The 'Find' class
// translates allocation addresses to page
// descriptions. The 'Rockall' class is needed
// to gain access to the external allocation APIs.
// The 'NewPage' class owns all page descriptions
// and plays a significant role in whole heap
// operations. The 'TopCache' is the largest
// bucket size and owns almost all the externally
// allocated memory.
//
CACHE **Caches; CACHE *ExternalCache; FIND *Find; NEW_PAGE *NewPage; PREFETCH Prefetch; ROCKALL *Rockall; CACHE *TopCache; #ifdef ENABLE_HEAP_STATISTICS
//
// Statistics data.
//
// A key feature of this heap is its ability to be
// significantly reconfigured at run time. A great
// deal of complexity could have been removed if
// certain static choices had been made. Although
// this flexibility is nice the support of statistics
// here allows precise information to be collected so
// to enable the value of this to be maximized.
//
//
SBIT32 CopyMisses; SBIT32 MaxCopySize; SBIT32 MaxNewSize; SBIT32 NewMisses; SBIT32 Reallocations; SBIT32 *Statistics; SBIT32 TotalCopySize; SBIT32 TotalNewSize; #endif
public: //
// Public functions.
//
// The heap exports the high level interface
// out to the world. Any request a developer
// can make must come through one of these
// functions.
//
HEAP ( CACHE *Caches1[], CACHE *Caches2[], SBIT32 MaxFreeSpace, FIND *NewFind, NEW_PAGE *NewPages, ROCKALL *NewRockall, SBIT32 Size1, SBIT32 Size2, SBIT32 Stride1, SBIT32 Stride2, BOOLEAN NewThredSafe );
BOOLEAN Delete( VOID *Address,SBIT32 Size = NoSize );
VOID DeleteAll( BOOLEAN Recycle = True );
BOOLEAN Details( VOID *Address,SBIT32 *Size = NULL );
VOID LockAll( VOID );
BOOLEAN MultipleDelete ( SBIT32 Actual, VOID *Array[], SBIT32 Size = NoSize );
BOOLEAN MultipleNew ( SBIT32 *Actual, VOID *Array[], SBIT32 Requested, SBIT32 Size, SBIT32 *Space = NULL, BOOLEAN Zero = False );
VOID *New ( SBIT32 Size, SBIT32 *Space = NULL, BOOLEAN Zero = False );
VOID *Resize ( VOID *Address, SBIT32 NewSize, SBIT32 Move = 1, SBIT32 *Space = NULL, BOOLEAN NoDelete = False, BOOLEAN Zero = False );
BOOLEAN Truncate( SBIT32 MaxFreeSpace = 0 );
VOID UnlockAll( BOOLEAN Partial = False );
BOOLEAN Verify( VOID *Address,SBIT32 *Size = NULL );
BOOLEAN Walk ( BOOLEAN *Active, VOID **Address, SBIT32 *Size );
~HEAP( VOID );
//
// Public inline functions.
//
// Although these functions are public they mostly
// intended for internal consumption and are not
// to be called externally.
//
INLINE SBIT32 GetMaxFreePages( VOID ) { return MaxFreePages; }
INLINE BOOLEAN KnownArea( VOID *Address ) { return (Find -> KnownArea( Address,TopCache )); }
INLINE VOID *SpecialNew( SBIT32 Size ) { return NewPage -> NewCacheStack( Size ); }
private: //
// Private functions.
//
// All of the statistical information is
// generated and output when the heaps
// destructor executes.
//
CACHE *FindCache( SBIT32 Size ); #ifdef ENABLE_HEAP_STATISTICS
VOID PrintDebugStatistics( VOID ); #endif
//
// Private inline functions.
//
// The notion that resizing an allocation is
// cheap has worked its way into the minds of
// a large number of developers. As a result
// parameter has been added to the function to
// allow the actual behavior to be controlled.
//
INLINE BOOLEAN ResizeTest( SBIT32 Delta,SBIT32 Move ) { return ( ((Move > 0) && ((((Delta >= 0) ? Delta : -Delta) >= Move))) || ((Move < 0) && ((Delta > 0) || (Delta <= Move))) ); }
//
// Disabled operations.
//
// All copy constructors and class assignment
// operations are disabled.
//
HEAP( CONST HEAP & Copy );
VOID operator=( CONST HEAP & Copy ); }; #endif
|