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.
260 lines
9.1 KiB
260 lines
9.1 KiB
#ifndef _BUCKET_HPP_
|
|
#define _BUCKET_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 "Connections.hpp"
|
|
#include "Page.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 CACHE;
|
|
class HEAP;
|
|
|
|
/********************************************************************/
|
|
/* */
|
|
/* A collection of pages. */
|
|
/* */
|
|
/* A bucket is a collection of pages capable of allocating */
|
|
/* fixed sized memory elements. The pages are allocated from */
|
|
/* from larger buckets and are stored in a linked list in */
|
|
/* order of ascending of page addresses. */
|
|
/* */
|
|
/********************************************************************/
|
|
|
|
class BUCKET : public CONNECTIONS
|
|
{
|
|
//
|
|
// Private type definitions.
|
|
//
|
|
// All allocations are registered in bit vectors.
|
|
// Here we have some prototypes for seriously
|
|
// optimized functions to do address to bit
|
|
// vector computations.
|
|
//
|
|
typedef VOID *(BUCKET::*COMPUTE_ADDRESS)
|
|
(
|
|
CHAR *Address,
|
|
SBIT32 Offset
|
|
);
|
|
|
|
typedef SBIT32 (BUCKET::*COMPUTE_OFFSET)
|
|
(
|
|
SBIT32 Displacement,
|
|
BOOLEAN *Found
|
|
);
|
|
|
|
//
|
|
// Private data.
|
|
//
|
|
// A bucket owns all the memory of a given size
|
|
// and manages it. Above it is a cache to
|
|
// protect it from huge number of calls and
|
|
// below it are the connections to various
|
|
// other classes. The 'AllocationSize' is the
|
|
// buckets allocation size. The 'ChunkSize' is
|
|
// chunking size which is typically half way
|
|
// between the 'AllocationSize' and the 'PageSize'.
|
|
// The 'PageSize' is the size of the bucket
|
|
// where this bucket gets its space.
|
|
//
|
|
//
|
|
SBIT32 AllocationSize;
|
|
SBIT32 ChunkSize;
|
|
SBIT32 PageSize;
|
|
|
|
//
|
|
// It is the job of the bucket to keep track of
|
|
// all the information relating to allocations
|
|
// of a given 'AllocationSize'. The 'ActivePages'
|
|
// keeps track of the number of available pages
|
|
// in the 'BucketList'. The 'BucketList' is a
|
|
// linked list of pages that have available space.
|
|
// The 'CurrentPage' contains the highest address
|
|
// of the first page in the 'BucketList'.
|
|
//
|
|
SBIT32 ActivePages;
|
|
LIST BucketList;
|
|
VOID *CurrentPage;
|
|
|
|
//
|
|
// A bucket needs to be able to quickly convert
|
|
// bit vector offsets to addresses (and vice versa).
|
|
// The 'AllocationShift' is set when the
|
|
// 'AllocationSize' is a power of two to avoid
|
|
// any divides. The 'ChunkShift' is set when the
|
|
// 'ChunckSize' is a power of two to avoid some
|
|
// divides. The 'ComputeAddressFunction' and
|
|
// 'ComputeOffsetFunction' point to optimized
|
|
// functions to do conversions that are selected
|
|
// by the constructor.
|
|
//
|
|
SBIT32 AllocationShift;
|
|
SBIT32 ChunkShift;
|
|
COMPUTE_ADDRESS ComputeAddressFunction;
|
|
COMPUTE_OFFSET ComputeOffsetFunction;
|
|
|
|
//
|
|
// A bucket typically contains a collection of
|
|
// pages. As all pages are the same data that
|
|
// should really be stored in page descriptions
|
|
// is instead stored in the bucket to save space.
|
|
// The 'NumberOfElements' contains the number of
|
|
// elements in each pages bit vector. The
|
|
// 'SizeOfChunks' contains the pre-computed chunk
|
|
// size. The 'SizeOfElements' contains the number
|
|
// of words in the pages bit vector. The 'SizeKey'
|
|
// contains an index which selects the size of the
|
|
// bit vector when a new page is created.
|
|
//
|
|
SBIT16 NumberOfElements;
|
|
SBIT16 SizeOfChunks;
|
|
SBIT16 SizeOfElements;
|
|
SBIT16 SizeKey;
|
|
|
|
public:
|
|
//
|
|
// Public functions.
|
|
//
|
|
// The functionality provided by this class pretty
|
|
// much matches the external API. Nonetheless, these
|
|
// APIs are protected from excessive calls by a fast
|
|
// cache that is derived from this class.
|
|
//
|
|
BUCKET
|
|
(
|
|
SBIT32 NewAllocationSize,
|
|
SBIT32 NewChunkSize,
|
|
SBIT32 NewPageSize
|
|
);
|
|
|
|
BOOLEAN Delete( VOID *Address,PAGE *Page,SBIT32 Version );
|
|
|
|
VOID DeleteFromBucketList( PAGE *Page );
|
|
|
|
VOID InsertInBucketList( PAGE *Page );
|
|
|
|
BOOLEAN MultipleDelete
|
|
(
|
|
ADDRESS_AND_PAGE *Array,
|
|
SBIT32 *Deleted,
|
|
SBIT32 Size
|
|
);
|
|
|
|
BOOLEAN MultipleNew
|
|
(
|
|
SBIT32 *Actual,
|
|
VOID *Array[],
|
|
SBIT32 Requested
|
|
);
|
|
|
|
VOID *New( BOOLEAN SubDivided,SBIT32 NewSize = NoSize );
|
|
|
|
VOID ReleaseSpace( SBIT32 MaxActivePages );
|
|
|
|
VOID UpdateBucket
|
|
(
|
|
FIND *NewFind,
|
|
HEAP *NewHeap,
|
|
NEW_PAGE *NewPages,
|
|
CACHE *NewParentCache
|
|
);
|
|
|
|
~BUCKET( VOID );
|
|
|
|
//
|
|
// Public inline functions.
|
|
//
|
|
// It saves a significant amount of space by putting
|
|
// common information in the bucket instead of a
|
|
// separate copy in each page description. Nonetheless,
|
|
// it means that both classes are very much dependent
|
|
// upon each other.
|
|
//
|
|
INLINE VOID *ComputeAddress( CHAR *Address,SBIT32 Offset )
|
|
{ return (this ->* ComputeAddressFunction)( Address,Offset ); }
|
|
|
|
INLINE SBIT32 ComputeOffset( SBIT32 Displacement,BOOLEAN *Found )
|
|
{ return (this ->* ComputeOffsetFunction)( Displacement,Found ); }
|
|
|
|
INLINE SBIT32 GetAllocationSize( VOID )
|
|
{ return AllocationSize; }
|
|
|
|
INLINE SBIT32 GetChunkSize( VOID )
|
|
{ return ChunkSize; }
|
|
|
|
VOID *GetCurrentPage( VOID )
|
|
{ return CurrentPage; }
|
|
|
|
INLINE SBIT16 GetNumberOfElements( VOID )
|
|
{ return NumberOfElements; }
|
|
|
|
INLINE SBIT32 GetPageSize( VOID )
|
|
{ return PageSize; }
|
|
|
|
INLINE SBIT16 GetSizeOfChunks( VOID )
|
|
{ return SizeOfChunks; }
|
|
|
|
INLINE SBIT16 GetSizeOfElements( VOID )
|
|
{ return SizeOfElements; }
|
|
|
|
INLINE SBIT16 GetSizeKey( VOID )
|
|
{ return SizeKey; }
|
|
|
|
private:
|
|
//
|
|
// Private functions.
|
|
//
|
|
// When we need to convert an address to a bit
|
|
// offset (or vice versa) we use one of the following
|
|
// functions.
|
|
//
|
|
VOID *ComputeAddressBestCase( CHAR *Address,SBIT32 Offset );
|
|
VOID *ComputeAddressGoodCase( CHAR *Address,SBIT32 Offset );
|
|
VOID *ComputeAddressPoorCase( CHAR *Address,SBIT32 Offset );
|
|
VOID *ComputeAddressWorstCase( CHAR *Address,SBIT32 Offset );
|
|
|
|
SBIT32 ComputeOffsetBestCase( SBIT32 Displacement,BOOLEAN *Found );
|
|
SBIT32 ComputeOffsetGoodCase( SBIT32 Displacement,BOOLEAN *Found );
|
|
SBIT32 ComputeOffsetPoorCase( SBIT32 Displacement,BOOLEAN *Found );
|
|
SBIT32 ComputeOffsetWorstCase( SBIT32 Displacement,BOOLEAN *Found );
|
|
|
|
//
|
|
// Disabled operations.
|
|
//
|
|
// All copy constructors and class assignment
|
|
// operations are disabled.
|
|
//
|
|
BUCKET( CONST BUCKET & Copy );
|
|
|
|
VOID operator=( CONST BUCKET & Copy );
|
|
};
|
|
#endif
|