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.
241 lines
9.1 KiB
241 lines
9.1 KiB
#ifndef _PAGE_HPP_
|
|
#define _PAGE_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 "NewPageList.hpp"
|
|
|
|
/********************************************************************/
|
|
/* */
|
|
/* Constants exported from the class. */
|
|
/* */
|
|
/* The constants supplied here control the number of bits in */
|
|
/* a page descriptions bit vector and its minimum size. */
|
|
/* */
|
|
/********************************************************************/
|
|
|
|
CONST SBIT32 MaxBitsPerWord = (sizeof(BIT32) * 8);
|
|
CONST SBIT32 MinVectorSize = 1;
|
|
CONST SBIT32 OverheadBits = 2;
|
|
CONST SBIT32 OverheadBitsPerWord = (MaxBitsPerWord / OverheadBits);
|
|
|
|
/********************************************************************/
|
|
/* */
|
|
/* 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;
|
|
|
|
/********************************************************************/
|
|
/* */
|
|
/* Data structures exported from the class. */
|
|
/* */
|
|
/* The page descriptions supported by this class are at the */
|
|
/* heart of the memory allocator. These pages are linked in */
|
|
/* various ways so they can be quickly found. The following */
|
|
/* structure contains the results of a search for a specific */
|
|
/* memory address and its related page information. */
|
|
/* */
|
|
/********************************************************************/
|
|
|
|
typedef struct
|
|
{
|
|
VOID *Address;
|
|
CACHE *Cache;
|
|
BOOLEAN Found;
|
|
PAGE *Page;
|
|
|
|
BIT32 AllocationMask;
|
|
BIT32 SubDivisionMask;
|
|
BIT32 *VectorWord;
|
|
|
|
SBIT32 ArrayOffset;
|
|
SBIT32 VectorOffset;
|
|
SBIT32 WordShift;
|
|
}
|
|
SEARCH_PAGE;
|
|
|
|
/********************************************************************/
|
|
/* */
|
|
/* The page allocation mechanism. */
|
|
/* */
|
|
/* The memory manager allocates storage in large chunks from */
|
|
/* the external memory allocator. It then sub-divides these */
|
|
/* chunks into various sized pages and keeps track of these */
|
|
/* allocations using a bit vector in each page description. */
|
|
/* */
|
|
/********************************************************************/
|
|
|
|
class PAGE : public NEW_PAGE_LIST
|
|
{
|
|
//
|
|
// Private data.
|
|
//
|
|
// The page description contains various details
|
|
// about the page. The 'Address' is the starting
|
|
// address of the allocation page. The 'PageSize'
|
|
// is typically empty but contains a value is the
|
|
// page size is weird and not realted to the
|
|
// assocated bucket. The 'Version' is a unique
|
|
// version number and is changed everytime a new
|
|
// page description is created or deleted. This
|
|
// version number allows a thread to see if anyone
|
|
// has been significantly playing with a page
|
|
// description since it last held the associated lock.
|
|
//
|
|
CHAR *Address;
|
|
SBIT32 PageSize;
|
|
SBIT32 Version;
|
|
|
|
//
|
|
// We keep track of the number of elements that
|
|
// are currently 'Allocated' and 'Available' on
|
|
// the page. Additionally, 'FirstFree' is the
|
|
// index of the first word in the bit vector that
|
|
// has at least one available slot.
|
|
//
|
|
SBIT16 Allocated;
|
|
SBIT16 Available;
|
|
SBIT16 FirstFree;
|
|
|
|
//
|
|
// We sometimes need to interact with other classes.
|
|
// The 'Cache' class typically owns a number of pages
|
|
// and keeps all the information about this size of
|
|
// allocation. The 'ParentPage' is a pointer to
|
|
// another cache from where this page was sub-allocated
|
|
// and where the space will need to be returned when
|
|
// it becomes free.
|
|
//
|
|
CACHE *Cache;
|
|
CACHE *ParentPage;
|
|
|
|
//
|
|
// The 'Vector' is the variable sized bit vector that
|
|
// contains allocation information. Each allocation
|
|
// is recorded using 2 bits. The first bit indicates
|
|
// whether the allocation is in use and the second bit
|
|
// indicates whether an active allocation has been
|
|
// sub-divided into smaller chunks. Any unused bits
|
|
// at the end of the final word are set to zero, assumed
|
|
// to be zero and should never be non-zero.
|
|
//
|
|
BIT32 Vector[MinVectorSize];
|
|
|
|
public:
|
|
//
|
|
// Public functions.
|
|
//
|
|
// The page description contains all the information
|
|
// relating to an allocation. There is no information
|
|
// stored with the allocation itself. A significant
|
|
// portion of the external API can find its way to
|
|
// this class if the many layers of caches fail to
|
|
// deal with the request first.
|
|
//
|
|
PAGE
|
|
(
|
|
VOID *NewAddress,
|
|
CACHE *NewCache,
|
|
SBIT32 NewPageSize,
|
|
CACHE *NewParentPage,
|
|
SBIT32 NewVersion
|
|
);
|
|
|
|
SBIT32 ActualSize( VOID );
|
|
|
|
BOOLEAN Delete( SEARCH_PAGE *Details );
|
|
|
|
VOID DeleteAll( VOID );
|
|
|
|
PAGE *FindPage
|
|
(
|
|
VOID *Address,
|
|
SEARCH_PAGE *Details,
|
|
BOOLEAN Recursive
|
|
);
|
|
|
|
BOOLEAN MultipleNew
|
|
(
|
|
SBIT32 *Available,
|
|
VOID *Array[],
|
|
SBIT32 Requested
|
|
);
|
|
|
|
VOID *New( BOOLEAN SubDivided );
|
|
|
|
BOOLEAN Walk( SEARCH_PAGE *Details );
|
|
|
|
~PAGE( VOID );
|
|
|
|
//
|
|
// Public inline functions.
|
|
//
|
|
// The page class is so central to the entire memory
|
|
// allocator that a number of other classes need to
|
|
// get at certain data from time to time. Thus, it
|
|
// is necessary for both brevity and performance to
|
|
// provide inline function for certain critical
|
|
// information relating to a page.
|
|
//
|
|
INLINE BOOLEAN Empty( VOID )
|
|
{ return (Allocated <= 0); }
|
|
|
|
INLINE BOOLEAN Full( VOID )
|
|
{ return (Available <= 0); }
|
|
|
|
INLINE VOID *GetAddress( VOID )
|
|
{ return ((VOID*) Address); }
|
|
|
|
INLINE CACHE *GetCache( VOID )
|
|
{ return Cache; }
|
|
|
|
INLINE SBIT32 GetPageSize( VOID )
|
|
{ return PageSize; }
|
|
|
|
INLINE CACHE *GetParentPage( VOID )
|
|
{ return ParentPage; }
|
|
|
|
INLINE SBIT32 GetVersion( VOID )
|
|
{ return Version; }
|
|
|
|
INLINE BOOLEAN ValidPage( VOID )
|
|
{ return ((BOOLEAN) ~(Version & 0x1)); }
|
|
|
|
private:
|
|
//
|
|
// Disabled operations.
|
|
//
|
|
// All copy constructors and class assignment
|
|
// operations are disabled.
|
|
//
|
|
PAGE( CONST PAGE & Copy );
|
|
|
|
VOID operator=( CONST PAGE & Copy );
|
|
};
|
|
#endif
|