|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996.
//
// File: page.hxx
//
// Contents: Paging classes for MSF
//
// Classes: CMSFPage
// CMSFPageTable
//
// Functions:
//
//----------------------------------------------------------------------------
#ifndef __PAGE_HXX__
#define __PAGE_HXX__
#include "vect.hxx"
class CPagedVector;
#define STG_S_NEWPAGE \
MAKE_SCODE(SEVERITY_SUCCESS, FACILITY_STORAGE, 0x2FF)
#define FB_NONE 0x00000000
#define FB_DIRTY 0x00000001
#define FB_NEW 0x00000002
#define FB_TOUCHED 0x10000000
//+---------------------------------------------------------------------------
//
// Class: CMSFPage (mp)
//
// Purpose: Contain MSF data in a form that is swappable to disk
//
// Interface: See below.
//
// Notes:
//
//----------------------------------------------------------------------------
class CMSFPage { public: void * operator new(size_t size, size_t sizeData);
CMSFPage(CMSFPage *pmpNext); inline ~CMSFPage();
inline void AddRef(void); inline void Release(void);
inline CMSFPage *GetNext(void) const; inline CMSFPage *GetPrev(void) const; inline SID GetSid(void) const; inline ULONG GetOffset(void) const; inline SECT GetSect(void) const; inline void *GetData(void) const; inline DWORD GetFlags(void) const; inline CPagedVector * GetVector(void) const;
inline void SetChain(CMSFPage *const pmpPrev, CMSFPage *const pmpNext); inline void SetPrev(CMSFPage *const pmpPrev); inline void SetNext(CMSFPage *const pmpNext);
inline void SetSid(const SID sid); inline void SetOffset(const ULONG ulOffset); inline void SetSect(const SECT sect); inline void SetFlags(const DWORD dwFlags); inline void SetVector(CPagedVector *ppv);
inline void SetDirty(void); inline void ResetDirty(void); inline BOOL IsDirty(void) const;
inline BOOL IsInUse(void) const; void ByteSwap(void);
private: CMSFPage *_pmpNext; CMSFPage *_pmpPrev;
SID _sid; ULONG _ulOffset; CPagedVector *_ppv; SECT _sect; DWORD _dwFlags; LONG _cReferences;
#ifdef _MSC_VER
// disable compiler warning C4200: nonstandard extension used :
// zero-sized array in struct/union
#pragma warning(disable: 4200)
BYTE _ab[0]; #pragma warning(default: 4200)
#endif
#ifdef __GNUC__
BYTE _ab[0]; #endif
};
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::~CMSFPage, public
//
// Synopsis: Destructor
//
//----------------------------------------------------------------------------
inline CMSFPage::~CMSFPage() { msfAssert(_cReferences == 0);
_pmpPrev->SetNext(_pmpNext); _pmpNext->SetPrev(_pmpPrev); }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::operator new, public
//
// Synopsis: Overloaded new operator for CMSFPage.
//
// Arguments: [size] -- Default size field
// [sizeData] -- Size of byte array to allocate.
//
// Returns: Pointer to new CMSFPage object
//
// Notes: *Finish This*
//
//----------------------------------------------------------------------------
inline void * CMSFPage::operator new(size_t size, size_t sizeData) { msfAssert(size == sizeof(CMSFPage)); UNREFERENCED_PARM(size); // for the retail build
return ::new BYTE[sizeData + sizeof(CMSFPage)]; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::GetNext, public
//
// Synopsis: Returns the next page in the list
//
//----------------------------------------------------------------------------
inline CMSFPage * CMSFPage::GetNext(void) const { return _pmpNext; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::GetPrev, public
//
// Synopsis: Returns the next page in the list
//
//----------------------------------------------------------------------------
inline CMSFPage * CMSFPage::GetPrev(void) const { return _pmpPrev; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::GetSid, public
//
// Synopsis: Returns the SID for this page
//
//----------------------------------------------------------------------------
inline SID CMSFPage::GetSid(void) const { return _sid; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::GetOffset, public
//
// Synopsis: Returns the array offset for this page
//
//----------------------------------------------------------------------------
inline ULONG CMSFPage::GetOffset(void) const { return _ulOffset; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::GetSect, public
//
// Synopsis: Returns the SECT for this page
//
//----------------------------------------------------------------------------
inline SECT CMSFPage::GetSect(void) const { return _sect; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::GetFlags, public
//
// Synopsis: Returns the flags for this page
//
//----------------------------------------------------------------------------
inline DWORD CMSFPage::GetFlags(void) const { return _dwFlags; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::GetData, public
//
// Synopsis: Returns a pointer to the page storage for this page
//
//----------------------------------------------------------------------------
inline void * CMSFPage::GetData(void) const { return (void *) _ab; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::GetVector, public
//
// Synopsis: Returns a pointer to the vector holding this page
//
//----------------------------------------------------------------------------
inline CPagedVector * CMSFPage::GetVector(void) const { return _ppv; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::SetChain, public
//
// Synopsis: Sets the chain pointers for this page
//
//----------------------------------------------------------------------------
inline void CMSFPage::SetChain( CMSFPage *const pmpPrev, CMSFPage *const pmpNext) { _pmpPrev = pmpPrev; _pmpNext = pmpNext; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::SetPrev, public
//
// Synopsis: Sets the prev pointer for this page
//
//----------------------------------------------------------------------------
inline void CMSFPage::SetPrev(CMSFPage *const pmpPrev) { _pmpPrev = pmpPrev; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::SetNext, public
//
// Synopsis: Sets the next pointer for this page
//
//----------------------------------------------------------------------------
inline void CMSFPage::SetNext(CMSFPage *const pmpNext) { _pmpNext = pmpNext; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::SetSid, public
//
// Synopsis: Sets the SID for this page
//
//----------------------------------------------------------------------------
inline void CMSFPage::SetSid(const SID sid) { _sid = sid; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::SetOffset, public
//
// Synopsis: Sets the offset for this page
//
//----------------------------------------------------------------------------
inline void CMSFPage::SetOffset(const ULONG ulOffset) { _ulOffset = ulOffset; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::SetSect, public
//
// Synopsis: Sets the SECT for this page
//
//----------------------------------------------------------------------------
inline void CMSFPage::SetSect(const SECT sect) { _sect = sect; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::SetSect, public
//
// Synopsis: Sets the SECT for this page
//
//----------------------------------------------------------------------------
inline void CMSFPage::SetFlags(const DWORD dwFlags) { _dwFlags = dwFlags; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::SetVector, public
//
// Synopsis: Sets the pointer to the vector holding this page
//
//----------------------------------------------------------------------------
inline void CMSFPage::SetVector(CPagedVector *ppv) { _ppv = ppv; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::SetDirty, public
//
// Synopsis: Sets the dirty bit for this page
//
//----------------------------------------------------------------------------
inline void CMSFPage::SetDirty(void) { _dwFlags = _dwFlags | FB_DIRTY; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::ResetDirty, public
//
// Synopsis: Resets the dirty bit for this page
//
//----------------------------------------------------------------------------
inline void CMSFPage::ResetDirty(void) { _dwFlags = _dwFlags & ~FB_DIRTY; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::IsDirty, public
//
// Synopsis: Returns TRUE if the dirty bit is set on this page
//
//----------------------------------------------------------------------------
inline BOOL CMSFPage::IsDirty(void) const { return (_dwFlags & FB_DIRTY) != 0; }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::IsInUse, public
//
// Synopsis: Returns TRUE if the page is currently in use
//
//----------------------------------------------------------------------------
inline BOOL CMSFPage::IsInUse(void) const { return (_cReferences != 0); }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::AddRef, public
//
// Synopsis: Increment the reference count
//
//----------------------------------------------------------------------------
inline void CMSFPage::AddRef(void) { msfAssert(_cReferences >= 0); AtomicInc(&_cReferences); }
//+---------------------------------------------------------------------------
//
// Member: CMSFPage::Release, public
//
// Synopsis: Decrement the reference count
//
//----------------------------------------------------------------------------
inline void CMSFPage::Release(void) { msfAssert(_cReferences > 0); AtomicDec(&_cReferences); }
//+---------------------------------------------------------------------------
//
// Class: CMSFPageTable
//
// Purpose: Page allocator and handler for MSF
//
// Interface: See below
//
// Notes:
//
//----------------------------------------------------------------------------
class CMSFPageTable { public: CMSFPageTable( CMStream *const pmsParent, const ULONG _cMinPages, const ULONG _cMaxPages); ~CMSFPageTable();
inline void AddRef(); inline void Release();
SCODE Init(void); SCODE GetPage( CPagedVector *ppv, SID sid, ULONG ulOffset, CMSFPage **ppmp);
SCODE FindPage( CPagedVector *ppv, SID sid, ULONG ulOffset, CMSFPage **ppmp); SCODE GetFreePage(CMSFPage **ppmp);
void ReleasePage(CPagedVector *ppv, SID sid, ULONG ulOffset);
void FreePages(CPagedVector *ppv);
SCODE Flush(void); SCODE FlushPage(CMSFPage *pmp);
inline void SetParent(CMStream *pms);
private: inline CMSFPage * GetNewPage(void); CMSFPage * FindSwapPage(void);
CMStream * _pmsParent; const ULONG _cbSector; const ULONG _cMinPages; const ULONG _cMaxPages;
ULONG _cActivePages; ULONG _cPages; CMSFPage *_pmpCurrent;
LONG _cReferences; #ifdef _MSC_VER
#pragma warning(disable:4512)
// since there is a const member, there should be no assignment operator
#endif // _MSC_VER
};
#ifdef _MSC_VER
#pragma warning(default:4512)
#endif // _MSC_VER
//+---------------------------------------------------------------------------
//
// Member: CMSFPageTable::GetNewPage, private
//
// Synopsis: Insert a new page into the list and return a pointer to it.
//
// Arguments: None.
//
// Returns: Pointer to new page. Null if there was an allocation error.
//
// Notes:
//
//----------------------------------------------------------------------------
inline CMSFPage * CMSFPageTable::GetNewPage(void) { return new((size_t)_cbSector) CMSFPage(_pmpCurrent); }
//+---------------------------------------------------------------------------
//
// Member: CMSFPageTable::AddRef, public
//
// Synopsis: Increment the ref coutn
//
//----------------------------------------------------------------------------
inline void CMSFPageTable::AddRef(void) { AtomicInc(&_cReferences); }
//+---------------------------------------------------------------------------
//
// Member: CMSFPageTable::Release, public
//
// Synopsis: Decrement the ref count, delete if necessary
//
//----------------------------------------------------------------------------
inline void CMSFPageTable::Release(void) { msfAssert(_cReferences > 0); AtomicDec(&_cReferences); if (_cReferences == 0) { delete this; } }
//+---------------------------------------------------------------------------
//
// Member: CMSFPageTable::SetParent, public
//
// Synopsis: Set the parent of this page table
//
// Arguments: [pms] -- Pointer to new parent
//
//----------------------------------------------------------------------------
inline void CMSFPageTable::SetParent(CMStream *pms) { _pmsParent = pms; }
#endif // #ifndef __PAGE_HXX__
|