Source code of Windows XP (NT5)
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.

716 lines
18 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: page.hxx
  7. //
  8. // Contents: Paging classes for MSF
  9. //
  10. // Classes: CMSFPage
  11. // CMSFPageTable
  12. //
  13. // Functions:
  14. //
  15. // History: 28-Oct-92 PhilipLa Created
  16. //
  17. //----------------------------------------------------------------------------
  18. #ifndef __PAGE_HXX__
  19. #define __PAGE_HXX__
  20. class CPagedVector;
  21. #define STG_S_NEWPAGE \
  22. MAKE_SCODE(SEVERITY_SUCCESS, FACILITY_STORAGE, 0x2FF)
  23. #define FB_NONE 0x00000000
  24. #define FB_DIRTY 0x00000001
  25. #define FB_NEW 0x00000002
  26. #define FB_TOUCHED 0x10000000
  27. class CMSFPageTable;
  28. class CMSFPage;
  29. SAFE_DFBASED_PTR(CBasedPagedVectorPtr, CPagedVector);
  30. SAFE_DFBASED_PTR(CBasedMSFPageTablePtr, CMSFPageTable);
  31. SAFE_DFBASED_PTR(CBasedMSFPagePtr, CMSFPage);
  32. //+---------------------------------------------------------------------------
  33. //
  34. // Class: CMSFPage (mp)
  35. //
  36. // Purpose: Contain MSF data in a form that is swappable to disk
  37. //
  38. // Interface: See below.
  39. //
  40. // History: 20-Oct-92 PhilipLa Created
  41. //
  42. // Notes:
  43. //
  44. //----------------------------------------------------------------------------
  45. #if _MSC_VER == 700
  46. #pragma warning(disable:4001)
  47. #elif _MSC_VER >= 800
  48. #pragma warning(disable:4200)
  49. #endif
  50. class CMSFPage : public CMallocBased
  51. {
  52. public:
  53. void * operator new(size_t size, IMalloc * const pMalloc,
  54. size_t sizeData);
  55. #if DBG == 1
  56. CMSFPage(CMSFPage *pmpNext, CMSFPageTable *pmpt);
  57. #else
  58. CMSFPage(CMSFPage *pmpNext);
  59. #endif
  60. inline ~CMSFPage();
  61. inline void AddRef(void);
  62. inline void Release(void);
  63. inline CMSFPage *GetNext(void) const;
  64. inline CMSFPage *GetPrev(void) const;
  65. inline SID GetSid(void) const;
  66. inline ULONG GetOffset(void) const;
  67. inline SECT GetSect(void) const;
  68. inline void *GetData(void) const;
  69. inline DWORD GetFlags(void) const;
  70. inline CPagedVector * GetVector(void) const;
  71. inline void Remove(void);
  72. inline void SetChain(CMSFPage *const pmpPrev,
  73. CMSFPage *const pmpNext);
  74. inline void SetPrev(CMSFPage *const pmpPrev);
  75. inline void SetNext(CMSFPage *const pmpNext);
  76. inline void SetSid(const SID sid);
  77. inline void SetOffset(const ULONG ulOffset);
  78. #ifndef SORTPAGETABLE
  79. inline void SetSect(const SECT sect);
  80. #endif
  81. inline void SetFlags(const DWORD dwFlags);
  82. inline void SetVector(CPagedVector *ppv);
  83. inline void SetDirty(void);
  84. inline void ResetDirty(void);
  85. inline BOOL IsDirty(void) const;
  86. inline BOOL IsInUse(void) const;
  87. inline BOOL IsFlushable(void) const;
  88. private:
  89. #ifdef SORTPAGETABLE
  90. friend CMSFPageTable;
  91. inline void SetSect(const SECT sect);
  92. #endif
  93. CBasedMSFPagePtr _pmpNext;
  94. CBasedMSFPagePtr _pmpPrev;
  95. #if DBG == 1
  96. CBasedMSFPageTablePtr _pmpt;
  97. #endif
  98. SID _sid;
  99. ULONG _ulOffset;
  100. CBasedPagedVectorPtr _ppv;
  101. SECT _sect;
  102. DWORD _dwFlags;
  103. LONG _cReferences;
  104. #if DBG == 1 || defined(_WIN64)
  105. ULONGLONG ulPadding; // alignment for unbuffered I/O and IA64
  106. #endif
  107. BYTE _ab[];
  108. };
  109. SAFE_DFBASED_PTR(CBasedMSFPagePtrPtr, CBasedMSFPagePtr);
  110. #if _MSC_VER == 700
  111. #pragma warning(default:4001)
  112. #elif _MSC_VER >= 800
  113. #pragma warning(default:4200)
  114. #endif
  115. //+---------------------------------------------------------------------------
  116. //
  117. // Member: CMSFPage::~CMSFPage, public
  118. //
  119. // Synopsis: Destructor
  120. //
  121. // History: 20-Oct-92 PhilipLa Created
  122. //
  123. //----------------------------------------------------------------------------
  124. inline CMSFPage::~CMSFPage()
  125. {
  126. msfAssert(_cReferences == 0);
  127. Remove();
  128. }
  129. //+---------------------------------------------------------------------------
  130. //
  131. // Member: CMSFPage::Remove, public
  132. //
  133. // Synopsis: Remove page from list
  134. //
  135. // History: 20-Oct-92 PhilipLa Created
  136. //
  137. //----------------------------------------------------------------------------
  138. inline void CMSFPage::Remove(void)
  139. {
  140. //Avoid using SetNext and SetPrev so we don't need to unbase and
  141. // then rebase everything.
  142. _pmpPrev->_pmpNext = _pmpNext;
  143. _pmpNext->_pmpPrev = _pmpPrev;
  144. _pmpNext = _pmpPrev = NULL;
  145. }
  146. //+---------------------------------------------------------------------------
  147. //
  148. // Member: CMSFPage::operator new, public
  149. //
  150. // Synopsis: Overloaded new operator for CMSFPage.
  151. //
  152. // Arguments: [size] -- Default size field
  153. // [pMalloc] -- Allocator
  154. // [sizeData] -- Size of byte array to allocate.
  155. //
  156. // Returns: Pointer to new CMSFPage object
  157. //
  158. // History: 20-Oct-92 PhilipLa Created
  159. // 21-May-93 AlexT Added allocator
  160. //
  161. // Notes: *Finish This*
  162. //
  163. //----------------------------------------------------------------------------
  164. inline void * CMSFPage::operator new(size_t size, IMalloc * const pMalloc,
  165. size_t sizeData)
  166. {
  167. msfAssert(size == sizeof(CMSFPage));
  168. return(CMallocBased::operator new(sizeData + sizeof(CMSFPage), pMalloc));
  169. }
  170. //+---------------------------------------------------------------------------
  171. //
  172. // Member: CMSFPage::GetNext, public
  173. //
  174. // Synopsis: Returns the next page in the list
  175. //
  176. // History: 20-Oct-92 PhilipLa Created
  177. //
  178. //----------------------------------------------------------------------------
  179. inline CMSFPage * CMSFPage::GetNext(void) const
  180. {
  181. return BP_TO_P(CMSFPage *, _pmpNext);
  182. }
  183. //+---------------------------------------------------------------------------
  184. //
  185. // Member: CMSFPage::GetPrev, public
  186. //
  187. // Synopsis: Returns the next page in the list
  188. //
  189. // History: 20-Oct-92 PhilipLa Created
  190. //
  191. //----------------------------------------------------------------------------
  192. inline CMSFPage * CMSFPage::GetPrev(void) const
  193. {
  194. return BP_TO_P(CMSFPage *, _pmpPrev);
  195. }
  196. //+---------------------------------------------------------------------------
  197. //
  198. // Member: CMSFPage::GetSid, public
  199. //
  200. // Synopsis: Returns the SID for this page
  201. //
  202. // History: 20-Oct-92 PhilipLa Created
  203. //
  204. //----------------------------------------------------------------------------
  205. inline SID CMSFPage::GetSid(void) const
  206. {
  207. return _sid;
  208. }
  209. //+---------------------------------------------------------------------------
  210. //
  211. // Member: CMSFPage::GetOffset, public
  212. //
  213. // Synopsis: Returns the array offset for this page
  214. //
  215. // History: 20-Oct-92 PhilipLa Created
  216. //
  217. //----------------------------------------------------------------------------
  218. inline ULONG CMSFPage::GetOffset(void) const
  219. {
  220. return _ulOffset;
  221. }
  222. //+---------------------------------------------------------------------------
  223. //
  224. // Member: CMSFPage::GetSect, public
  225. //
  226. // Synopsis: Returns the SECT for this page
  227. //
  228. // History: 20-Oct-92 PhilipLa Created
  229. //
  230. //----------------------------------------------------------------------------
  231. inline SECT CMSFPage::GetSect(void) const
  232. {
  233. return _sect;
  234. }
  235. //+---------------------------------------------------------------------------
  236. //
  237. // Member: CMSFPage::GetFlags, public
  238. //
  239. // Synopsis: Returns the flags for this page
  240. //
  241. // History: 20-Oct-92 PhilipLa Created
  242. //
  243. //----------------------------------------------------------------------------
  244. inline DWORD CMSFPage::GetFlags(void) const
  245. {
  246. return _dwFlags;
  247. }
  248. //+---------------------------------------------------------------------------
  249. //
  250. // Member: CMSFPage::GetData, public
  251. //
  252. // Synopsis: Returns a pointer to the page storage for this page
  253. //
  254. // History: 20-Oct-92 PhilipLa Created
  255. //
  256. //----------------------------------------------------------------------------
  257. inline void * CMSFPage::GetData(void) const
  258. {
  259. return (void *) _ab;
  260. }
  261. //+---------------------------------------------------------------------------
  262. //
  263. // Member: CMSFPage::GetVector, public
  264. //
  265. // Synopsis: Returns a pointer to the vector holding this page
  266. //
  267. // History: 20-Oct-92 PhilipLa Created
  268. //
  269. //----------------------------------------------------------------------------
  270. inline CPagedVector * CMSFPage::GetVector(void) const
  271. {
  272. return BP_TO_P(CPagedVector *, _ppv);
  273. }
  274. //+---------------------------------------------------------------------------
  275. //
  276. // Member: CMSFPage::SetChain, public
  277. //
  278. // Synopsis: Sets the chain pointers for this page
  279. //
  280. // History: 20-Oct-92 PhilipLa Created
  281. //
  282. //----------------------------------------------------------------------------
  283. inline void CMSFPage::SetChain(
  284. CMSFPage *const pmpPrev,
  285. CMSFPage *const pmpNext)
  286. {
  287. _pmpPrev = P_TO_BP(CBasedMSFPagePtr, pmpPrev);
  288. _pmpNext = P_TO_BP(CBasedMSFPagePtr, pmpNext);
  289. }
  290. //+---------------------------------------------------------------------------
  291. //
  292. // Member: CMSFPage::SetPrev, public
  293. //
  294. // Synopsis: Sets the prev pointer for this page
  295. //
  296. // History: 20-Oct-92 PhilipLa Created
  297. //
  298. //----------------------------------------------------------------------------
  299. inline void CMSFPage::SetPrev(CMSFPage *const pmpPrev)
  300. {
  301. _pmpPrev = P_TO_BP(CBasedMSFPagePtr, pmpPrev);
  302. }
  303. //+---------------------------------------------------------------------------
  304. //
  305. // Member: CMSFPage::SetNext, public
  306. //
  307. // Synopsis: Sets the next pointer for this page
  308. //
  309. // History: 20-Oct-92 PhilipLa Created
  310. //
  311. //----------------------------------------------------------------------------
  312. inline void CMSFPage::SetNext(CMSFPage *const pmpNext)
  313. {
  314. _pmpNext = P_TO_BP(CBasedMSFPagePtr, pmpNext);
  315. }
  316. //+---------------------------------------------------------------------------
  317. //
  318. // Member: CMSFPage::SetSid, public
  319. //
  320. // Synopsis: Sets the SID for this page
  321. //
  322. // History: 20-Oct-92 PhilipLa Created
  323. //
  324. //----------------------------------------------------------------------------
  325. inline void CMSFPage::SetSid(const SID sid)
  326. {
  327. _sid = sid;
  328. }
  329. //+---------------------------------------------------------------------------
  330. //
  331. // Member: CMSFPage::SetOffset, public
  332. //
  333. // Synopsis: Sets the offset for this page
  334. //
  335. // History: 20-Oct-92 PhilipLa Created
  336. //
  337. //----------------------------------------------------------------------------
  338. inline void CMSFPage::SetOffset(const ULONG ulOffset)
  339. {
  340. _ulOffset = ulOffset;
  341. }
  342. //+---------------------------------------------------------------------------
  343. //
  344. // Member: CMSFPage::SetSect, public
  345. //
  346. // Synopsis: Sets the SECT for this page
  347. //
  348. // History: 20-Oct-92 PhilipLa Created
  349. //
  350. //----------------------------------------------------------------------------
  351. #ifndef SORTPAGETABLE
  352. inline void CMSFPage::SetSect(const SECT sect)
  353. {
  354. _sect = sect;
  355. }
  356. #endif
  357. //+---------------------------------------------------------------------------
  358. //
  359. // Member: CMSFPage::SetFlags, public
  360. //
  361. // Synopsis: Sets the flags for this page
  362. //
  363. // History: 20-Oct-92 PhilipLa Created
  364. //
  365. //----------------------------------------------------------------------------
  366. inline void CMSFPage::SetFlags(const DWORD dwFlags)
  367. {
  368. _dwFlags = dwFlags;
  369. }
  370. //+---------------------------------------------------------------------------
  371. //
  372. // Member: CMSFPage::SetVector, public
  373. //
  374. // Synopsis: Sets the pointer to the vector holding this page
  375. //
  376. // History: 20-Oct-92 PhilipLa Created
  377. //
  378. //----------------------------------------------------------------------------
  379. inline void CMSFPage::SetVector(CPagedVector *ppv)
  380. {
  381. _ppv = P_TO_BP(CBasedPagedVectorPtr, ppv);
  382. }
  383. //+---------------------------------------------------------------------------
  384. //
  385. // Member: CMSFPage::SetDirty, public
  386. //
  387. // Synopsis: Sets the dirty bit for this page
  388. //
  389. // History: 20-Oct-92 PhilipLa Created
  390. //
  391. //----------------------------------------------------------------------------
  392. inline void CMSFPage::SetDirty(void)
  393. {
  394. _dwFlags = _dwFlags | FB_DIRTY;
  395. }
  396. //+---------------------------------------------------------------------------
  397. //
  398. // Member: CMSFPage::ResetDirty, public
  399. //
  400. // Synopsis: Resets the dirty bit for this page
  401. //
  402. // History: 20-Oct-92 PhilipLa Created
  403. //
  404. //----------------------------------------------------------------------------
  405. inline void CMSFPage::ResetDirty(void)
  406. {
  407. _dwFlags = _dwFlags & ~FB_DIRTY;
  408. }
  409. //+---------------------------------------------------------------------------
  410. //
  411. // Member: CMSFPage::IsDirty, public
  412. //
  413. // Synopsis: Returns TRUE if the dirty bit is set on this page
  414. //
  415. // History: 20-Oct-92 PhilipLa Created
  416. //
  417. //----------------------------------------------------------------------------
  418. inline BOOL CMSFPage::IsDirty(void) const
  419. {
  420. return (_dwFlags & FB_DIRTY) != 0;
  421. }
  422. //+---------------------------------------------------------------------------
  423. //
  424. // Member: CMSFPage::IsInUse, public
  425. //
  426. // Synopsis: Returns TRUE if the page is currently in use
  427. //
  428. // History: 05-Nov-92 PhilipLa Created
  429. //
  430. //----------------------------------------------------------------------------
  431. inline BOOL CMSFPage::IsInUse(void) const
  432. {
  433. return (_cReferences != 0);
  434. }
  435. //+---------------------------------------------------------------------------
  436. //
  437. // Member: CMSFPage::IsFlushable, public
  438. //
  439. // Synopsis: Returns TRUE if the page can be flushed to disk
  440. //
  441. // History: 05-Nov-92 PhilipLa Created
  442. //
  443. //----------------------------------------------------------------------------
  444. inline BOOL CMSFPage::IsFlushable(void) const
  445. {
  446. return (IsDirty() && !IsInUse());
  447. }
  448. //+---------------------------------------------------------------------------
  449. //
  450. // Class: CMSFPageTable
  451. //
  452. // Purpose: Page allocator and handler for MSF
  453. //
  454. // Interface: See below
  455. //
  456. // History: 20-Oct-92 PhilipLa Created
  457. //
  458. // Notes:
  459. //
  460. //----------------------------------------------------------------------------
  461. class CMSFPageTable : public CMallocBased
  462. {
  463. public:
  464. CMSFPageTable(
  465. CMStream *const pmsParent,
  466. const ULONG _cMinPages,
  467. const ULONG _cMaxPages);
  468. ~CMSFPageTable();
  469. inline void AddRef();
  470. inline void Release();
  471. SCODE Init(void);
  472. SCODE GetPage(
  473. CPagedVector *ppv,
  474. SID sid,
  475. ULONG ulOffset,
  476. SECT sectKnown,
  477. CMSFPage **ppmp);
  478. SCODE CopyPage(
  479. CPagedVector *ppv,
  480. CMSFPage *pmpOld,
  481. CBasedMSFPagePtr *ppmp);
  482. SCODE FindPage(
  483. CPagedVector *ppv,
  484. SID sid,
  485. ULONG ulOffset,
  486. CMSFPage **ppmp);
  487. SCODE GetFreePage(CMSFPage **ppmp);
  488. void ReleasePage(CPagedVector *ppv, SID sid, ULONG ulOffset);
  489. void FreePages(CPagedVector *ppv);
  490. #ifdef SORTPAGETABLE
  491. void SetSect(CMSFPage *pmp, SECT sect);
  492. #endif
  493. SCODE Flush(void);
  494. SCODE FlushPage(CMSFPage *pmp);
  495. inline void SetParent(CMStream *pms);
  496. #if DBG == 1
  497. void AddPageRef(void);
  498. void ReleasePageRef(void);
  499. #endif
  500. private:
  501. inline CMSFPage * GetNewPage(void);
  502. CMSFPage * FindSwapPage(void);
  503. CBasedMStreamPtr _pmsParent;
  504. const ULONG _cbSector;
  505. const ULONG _cMinPages;
  506. const ULONG _cMaxPages;
  507. ULONG _cActivePages;
  508. ULONG _cPages;
  509. CBasedMSFPagePtr _pmpCurrent;
  510. #ifdef SORTPAGETABLE
  511. CBasedMSFPagePtr _pmpStart;
  512. inline BOOL IsSorted(CMSFPage *pmp);
  513. #endif
  514. LONG _cReferences;
  515. #if DBG == 1
  516. ULONG _cCurrentPageRef;
  517. ULONG _cMaxPageRef;
  518. #endif
  519. };
  520. //+---------------------------------------------------------------------------
  521. //
  522. // Member: CMSFPage::AddRef, public
  523. //
  524. // Synopsis: Increment the reference count
  525. //
  526. // History: 28-Oct-92 PhilipLa Created
  527. //
  528. //----------------------------------------------------------------------------
  529. inline void CMSFPage::AddRef(void)
  530. {
  531. msfAssert(_cReferences >= 0);
  532. #if DBG == 1
  533. if (_cReferences == 0)
  534. {
  535. _pmpt->AddPageRef();
  536. }
  537. #endif
  538. AtomicInc(&_cReferences);
  539. }
  540. //+---------------------------------------------------------------------------
  541. //
  542. // Member: CMSFPage::Release, public
  543. //
  544. // Synopsis: Decrement the reference count
  545. //
  546. // History: 28-Oct-92 PhilipLa Created
  547. //
  548. //----------------------------------------------------------------------------
  549. inline void CMSFPage::Release(void)
  550. {
  551. LONG lRet;
  552. msfAssert(_cReferences > 0);
  553. lRet = AtomicDec(&_cReferences);
  554. #if DBG == 1
  555. if (lRet == 0)
  556. {
  557. _pmpt->ReleasePageRef();
  558. }
  559. #endif
  560. }
  561. //+---------------------------------------------------------------------------
  562. //
  563. // Member: CMSFPageTable::AddRef, public
  564. //
  565. // Synopsis: Increment the ref coutn
  566. //
  567. // History: 05-Nov-92 PhilipLa Created
  568. //
  569. //----------------------------------------------------------------------------
  570. inline void CMSFPageTable::AddRef(void)
  571. {
  572. AtomicInc(&_cReferences);
  573. }
  574. //+---------------------------------------------------------------------------
  575. //
  576. // Member: CMSFPageTable::Release, public
  577. //
  578. // Synopsis: Decrement the ref count, delete if necessary
  579. //
  580. // History: 05-Nov-92 PhilipLa Created
  581. //
  582. //----------------------------------------------------------------------------
  583. inline void CMSFPageTable::Release(void)
  584. {
  585. LONG lRet;
  586. msfAssert(_cReferences > 0);
  587. lRet = AtomicDec(&_cReferences);
  588. if (lRet == 0)
  589. {
  590. delete this;
  591. }
  592. }
  593. //+---------------------------------------------------------------------------
  594. //
  595. // Member: CMSFPageTable::SetParent, public
  596. //
  597. // Synopsis: Set the parent of this page table
  598. //
  599. // Arguments: [pms] -- Pointer to new parent
  600. //
  601. // History: 05-Nov-92 PhilipLa Created
  602. //
  603. //----------------------------------------------------------------------------
  604. inline void CMSFPageTable::SetParent(CMStream *pms)
  605. {
  606. _pmsParent = P_TO_BP(CBasedMStreamPtr, pms);
  607. }
  608. #endif // #ifndef __PAGE_HXX__