//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1992. // // File: page.hxx // // Contents: Paging classes for MSF // // Classes: CMSFPage // CMSFPageTable // // Functions: // // History: 28-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- #ifndef __PAGE_HXX__ #define __PAGE_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 CMSFPageTable; class CMSFPage; SAFE_DFBASED_PTR(CBasedPagedVectorPtr, CPagedVector); SAFE_DFBASED_PTR(CBasedMSFPageTablePtr, CMSFPageTable); SAFE_DFBASED_PTR(CBasedMSFPagePtr, CMSFPage); //+--------------------------------------------------------------------------- // // Class: CMSFPage (mp) // // Purpose: Contain MSF data in a form that is swappable to disk // // Interface: See below. // // History: 20-Oct-92 PhilipLa Created // // Notes: // //---------------------------------------------------------------------------- #ifndef REF #if _MSC_VER == 700 #pragma warning(disable:4001) #elif _MSC_VER >= 800 #pragma warning(disable:4200) #endif #endif //!REF class CMSFPage : public CMallocBased { public: void * operator new(size_t size, IMalloc * const pMalloc, size_t sizeData); #if DBG == 1 CMSFPage(CMSFPage *pmpNext, CMSFPageTable *pmpt); #else CMSFPage(CMSFPage *pmpNext); #endif 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 Remove(void); 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); #ifndef SORTPAGETABLE inline void SetSect(const SECT sect); #endif 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; inline BOOL IsFlushable(void) const; private: #ifdef SORTPAGETABLE friend CMSFPageTable; inline void SetSect(const SECT sect); #endif CBasedMSFPagePtr _pmpNext; CBasedMSFPagePtr _pmpPrev; #if DBG == 1 CBasedMSFPageTablePtr _pmpt; #endif SID _sid; ULONG _ulOffset; CBasedPagedVectorPtr _ppv; SECT _sect; DWORD _dwFlags; LONG _cReferences; BYTE _ab[]; }; SAFE_DFBASED_PTR(CBasedMSFPagePtrPtr, CBasedMSFPagePtr); #ifndef REF #if _MSC_VER == 700 #pragma warning(default:4001) #elif _MSC_VER >= 800 #pragma warning(default:4200) #endif #endif //!REF //+--------------------------------------------------------------------------- // // Member: CMSFPage::~CMSFPage, public // // Synopsis: Destructor // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- #ifdef CODESEGMENTS #pragma code_seg(SEG_CMSFPage_1CMSFPage) #endif inline CMSFPage::~CMSFPage() { msfAssert(_cReferences == 0); Remove(); } //+--------------------------------------------------------------------------- // // Member: CMSFPage::Remove, public // // Synopsis: Remove page from list // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPage::Remove(void) { //Avoid using SetNext and SetPrev so we don't need to unbase and // then rebase everything. _pmpPrev->_pmpNext = _pmpNext; _pmpNext->_pmpPrev = _pmpPrev; _pmpNext = _pmpPrev = NULL; } #ifdef CODESEGMENTS #pragma code_seg() #endif //+--------------------------------------------------------------------------- // // Member: CMSFPage::operator new, public // // Synopsis: Overloaded new operator for CMSFPage. // // Arguments: [size] -- Default size field // [pMalloc] -- Allocator // [sizeData] -- Size of byte array to allocate. // // Returns: Pointer to new CMSFPage object // // History: 20-Oct-92 PhilipLa Created // 21-May-93 AlexT Added allocator // // Notes: *Finish This* // //---------------------------------------------------------------------------- inline void * CMSFPage::operator new(size_t size, IMalloc * const pMalloc, size_t sizeData) { msfAssert(size == sizeof(CMSFPage)); return(CMallocBased::operator new(sizeData + sizeof(CMSFPage), pMalloc)); } //+--------------------------------------------------------------------------- // // Member: CMSFPage::GetNext, public // // Synopsis: Returns the next page in the list // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline CMSFPage * CMSFPage::GetNext(void) const { return BP_TO_P(CMSFPage *, _pmpNext); } //+--------------------------------------------------------------------------- // // Member: CMSFPage::GetPrev, public // // Synopsis: Returns the next page in the list // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline CMSFPage * CMSFPage::GetPrev(void) const { return BP_TO_P(CMSFPage *, _pmpPrev); } //+--------------------------------------------------------------------------- // // Member: CMSFPage::GetSid, public // // Synopsis: Returns the SID for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline SID CMSFPage::GetSid(void) const { return _sid; } //+--------------------------------------------------------------------------- // // Member: CMSFPage::GetOffset, public // // Synopsis: Returns the array offset for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline ULONG CMSFPage::GetOffset(void) const { return _ulOffset; } //+--------------------------------------------------------------------------- // // Member: CMSFPage::GetSect, public // // Synopsis: Returns the SECT for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline SECT CMSFPage::GetSect(void) const { return _sect; } //+--------------------------------------------------------------------------- // // Member: CMSFPage::GetFlags, public // // Synopsis: Returns the flags for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline DWORD CMSFPage::GetFlags(void) const { return _dwFlags; } //+--------------------------------------------------------------------------- // // Member: CMSFPage::GetData, public // // Synopsis: Returns a pointer to the page storage for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void * CMSFPage::GetData(void) const { return (void *) _ab; } //+--------------------------------------------------------------------------- // // Member: CMSFPage::GetVector, public // // Synopsis: Returns a pointer to the vector holding this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline CPagedVector * CMSFPage::GetVector(void) const { return BP_TO_P(CPagedVector *, _ppv); } //+--------------------------------------------------------------------------- // // Member: CMSFPage::SetChain, public // // Synopsis: Sets the chain pointers for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPage::SetChain( CMSFPage *const pmpPrev, CMSFPage *const pmpNext) { _pmpPrev = P_TO_BP(CBasedMSFPagePtr, pmpPrev); _pmpNext = P_TO_BP(CBasedMSFPagePtr, pmpNext); } //+--------------------------------------------------------------------------- // // Member: CMSFPage::SetPrev, public // // Synopsis: Sets the prev pointer for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPage::SetPrev(CMSFPage *const pmpPrev) { _pmpPrev = P_TO_BP(CBasedMSFPagePtr, pmpPrev); } //+--------------------------------------------------------------------------- // // Member: CMSFPage::SetNext, public // // Synopsis: Sets the next pointer for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPage::SetNext(CMSFPage *const pmpNext) { _pmpNext = P_TO_BP(CBasedMSFPagePtr, pmpNext); } //+--------------------------------------------------------------------------- // // Member: CMSFPage::SetSid, public // // Synopsis: Sets the SID for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPage::SetSid(const SID sid) { _sid = sid; } //+--------------------------------------------------------------------------- // // Member: CMSFPage::SetOffset, public // // Synopsis: Sets the offset for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPage::SetOffset(const ULONG ulOffset) { _ulOffset = ulOffset; } //+--------------------------------------------------------------------------- // // Member: CMSFPage::SetSect, public // // Synopsis: Sets the SECT for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- #ifndef SORTPAGETABLE inline void CMSFPage::SetSect(const SECT sect) { _sect = sect; } #endif //+--------------------------------------------------------------------------- // // Member: CMSFPage::SetFlags, public // // Synopsis: Sets the flags for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPage::SetFlags(const DWORD dwFlags) { _dwFlags = dwFlags; } //+--------------------------------------------------------------------------- // // Member: CMSFPage::SetVector, public // // Synopsis: Sets the pointer to the vector holding this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPage::SetVector(CPagedVector *ppv) { _ppv = P_TO_BP(CBasedPagedVectorPtr, ppv); } //+--------------------------------------------------------------------------- // // Member: CMSFPage::SetDirty, public // // Synopsis: Sets the dirty bit for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPage::SetDirty(void) { _dwFlags = _dwFlags | FB_DIRTY; } //+--------------------------------------------------------------------------- // // Member: CMSFPage::ResetDirty, public // // Synopsis: Resets the dirty bit for this page // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- 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 // // History: 20-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- 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 // // History: 05-Nov-92 PhilipLa Created // //---------------------------------------------------------------------------- inline BOOL CMSFPage::IsInUse(void) const { return (_cReferences != 0); } //+--------------------------------------------------------------------------- // // Member: CMSFPage::IsFlushable, public // // Synopsis: Returns TRUE if the page can be flushed to disk // // History: 05-Nov-92 PhilipLa Created // //---------------------------------------------------------------------------- inline BOOL CMSFPage::IsFlushable(void) const { return (IsDirty() && !IsInUse()); } //+--------------------------------------------------------------------------- // // Class: CMSFPageTable // // Purpose: Page allocator and handler for MSF // // Interface: See below // // History: 20-Oct-92 PhilipLa Created // // Notes: // //---------------------------------------------------------------------------- class CMSFPageTable : public CMallocBased { 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, SECT sectKnown, CMSFPage **ppmp); #ifndef REF SCODE CopyPage( CPagedVector *ppv, CMSFPage *pmpOld, CBasedMSFPagePtr *ppmp); #endif //!REF 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); #ifdef SORTPAGETABLE void SetSect(CMSFPage *pmp, SECT sect); #endif SCODE Flush(void); SCODE FlushPage(CMSFPage *pmp); inline void SetParent(CMStream *pms); #if DBG == 1 void AddPageRef(void); void ReleasePageRef(void); #endif private: inline CMSFPage * GetNewPage(void); CMSFPage * FindSwapPage(void); CBasedMStreamPtr _pmsParent; const ULONG _cbSector; const ULONG _cMinPages; const ULONG _cMaxPages; ULONG _cActivePages; ULONG _cPages; CBasedMSFPagePtr _pmpCurrent; #ifdef SORTPAGETABLE CBasedMSFPagePtr _pmpStart; inline BOOL IsSorted(CMSFPage *pmp); #endif LONG _cReferences; #if DBG == 1 ULONG _cCurrentPageRef; ULONG _cMaxPageRef; #endif }; //+--------------------------------------------------------------------------- // // Member: CMSFPage::AddRef, public // // Synopsis: Increment the reference count // // History: 28-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPage::AddRef(void) { msfAssert(_cReferences >= 0); #if DBG == 1 if (_cReferences == 0) { _pmpt->AddPageRef(); } #endif AtomicInc(&_cReferences); } //+--------------------------------------------------------------------------- // // Member: CMSFPage::Release, public // // Synopsis: Decrement the reference count // // History: 28-Oct-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPage::Release(void) { LONG lRet; msfAssert(_cReferences > 0); lRet = AtomicDec(&_cReferences); #if DBG == 1 if (lRet == 0) { _pmpt->ReleasePageRef(); } #endif } //+--------------------------------------------------------------------------- // // Member: CMSFPageTable::AddRef, public // // Synopsis: Increment the ref coutn // // History: 05-Nov-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPageTable::AddRef(void) { AtomicInc(&_cReferences); } //+--------------------------------------------------------------------------- // // Member: CMSFPageTable::Release, public // // Synopsis: Decrement the ref count, delete if necessary // // History: 05-Nov-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPageTable::Release(void) { LONG lRet; msfAssert(_cReferences > 0); lRet = AtomicDec(&_cReferences); if (lRet == 0) { delete this; } } //+--------------------------------------------------------------------------- // // Member: CMSFPageTable::SetParent, public // // Synopsis: Set the parent of this page table // // Arguments: [pms] -- Pointer to new parent // // History: 05-Nov-92 PhilipLa Created // //---------------------------------------------------------------------------- inline void CMSFPageTable::SetParent(CMStream *pms) { _pmsParent = P_TO_BP(CBasedMStreamPtr, pms); } #endif // #ifndef __PAGE_HXX__