mempager.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:11k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /****************************************************************************
  36.  *  Includes
  37.  */
  38. #include "mempager.h"
  39. #include "hxfswch.h"
  40. #include "hxassert.h"
  41. #include "qtffrefcounter.h"
  42. #ifndef QTCONFIG_SPEED_OVER_SIZE
  43. #include "mempager_inline.h"
  44. #endif // QTCONFIG_SPEED_OVER_SIZE
  45. /****************************************************************************
  46.  *  Local Defines
  47.  */
  48. #if defined(HELIX_FEATURE_MIN_HEAP)
  49. #define MEMPAGER_DFLT_MIN_PAGE_SIZE 0x00000400  // 1K
  50. #else // HELIX_FEATURE_MIN_HEAP
  51. #define MEMPAGER_DFLT_MIN_PAGE_SIZE 0x0000FFFF  // 64K
  52. #endif // HELIX_FEATURE_MIN_HEAP
  53. #define MEMPAGER_BASE_VIRTUAL_ADDR  0x00000001
  54. /****************************************************************************
  55.  *  Class CMemPager
  56.  */
  57. /****************************************************************************
  58.  *  Constructor/Destructor
  59.  */
  60. CMemPager::CMemPager(void)
  61.     : m_pFileSwitcher(NULL)
  62.     , m_pResponse(NULL)
  63.     , m_State(MEMPGR_Offline)
  64.     , m_pBaseVirtualAddr(NULL)
  65.     , m_pPageVirtualAddr(NULL)
  66.     , m_pPagePhysicalAddr(NULL)
  67.     , m_ulPageSize(0)
  68.     , m_pFaultedPageVirtualAddr(NULL)
  69.     , m_ulFaultedPageSize(0)
  70.     , m_ulAddrSpaceOffset(0)
  71.     , m_ulAddrSpaceSize(0)
  72.     , m_ulMinPageSize(MEMPAGER_DFLT_MIN_PAGE_SIZE)
  73.     , m_pPageBuffer(NULL)
  74.     , m_bSyncMode(FALSE)
  75.     , m_lRefCount(0)
  76. {
  77.     g_nRefCount_qtff++;
  78. }
  79. CMemPager::~CMemPager()
  80. {
  81.     Reset();
  82.     g_nRefCount_qtff--;
  83. }
  84. /****************************************************************************
  85.  *  CMemPager private methods
  86.  */
  87. /****************************************************************************
  88.  *  Reset
  89.  */
  90. void CMemPager::Reset(void)
  91. {
  92.     HX_RELEASE(m_pFileSwitcher);
  93.     HX_RELEASE(m_pResponse);
  94.     HX_RELEASE(m_pPageBuffer);
  95.     m_pBaseVirtualAddr = NULL;
  96.     m_pPageVirtualAddr = NULL;
  97.     m_pPagePhysicalAddr = NULL;
  98.     m_ulPageSize = 0;
  99.     m_pFaultedPageVirtualAddr = NULL;
  100.     m_ulFaultedPageSize = 0;
  101.     m_ulAddrSpaceOffset = 0;
  102.     m_ulAddrSpaceSize = 0;
  103.     m_ulMinPageSize = MEMPAGER_DFLT_MIN_PAGE_SIZE;
  104.     m_State = MEMPGR_Offline;
  105. }
  106. /****************************************************************************
  107.  *  CMemPager methods - Main interface
  108.  */
  109. /****************************************************************************
  110.  *  Init
  111.  */
  112. HX_RESULT CMemPager::Init(IUnknown* pSource,
  113.   ULONG32 ulOffset,
  114.   ULONG32 ulSize,
  115.   UINT8** ppVirtualBaseAddr)
  116. {
  117.     HX_RESULT retVal = HXR_OK;
  118.     if (m_State != MEMPGR_Offline)
  119.     {
  120. retVal = HXR_UNEXPECTED;
  121.     }
  122.     if (SUCCEEDED(retVal))
  123.     {
  124. Reset();
  125. // Find Input Interface
  126. retVal = pSource->QueryInterface(IID_IHXFileSwitcher, 
  127.  (void**) &m_pFileSwitcher);
  128.     }
  129.     if (SUCCEEDED(retVal))
  130.     {
  131. m_ulAddrSpaceOffset = ulOffset;
  132. m_ulAddrSpaceSize = ulSize;
  133. m_pBaseVirtualAddr = (UINT8*) MEMPAGER_BASE_VIRTUAL_ADDR;
  134. m_pFaultedPageVirtualAddr = m_pBaseVirtualAddr;
  135. m_ulFaultedPageSize = m_ulMinPageSize;
  136. if (m_ulFaultedPageSize > m_ulAddrSpaceSize)
  137. {
  138.     m_ulFaultedPageSize = m_ulAddrSpaceSize;
  139. }
  140.    
  141. if (ppVirtualBaseAddr)
  142. {
  143.     *ppVirtualBaseAddr = m_pBaseVirtualAddr;
  144. }
  145. m_State = MEMPGR_Ready;
  146.     }
  147.     return retVal;
  148. }
  149. /****************************************************************************
  150.  *  _PageIn
  151.  */
  152. HX_RESULT CMemPager::_PageIn(UINT8* pVirtualAddr,
  153.      ULONG32 ulSize,
  154.      UINT8* &pPhysicalBaseAddr)
  155. {
  156.     HX_RESULT retVal = HXR_UNEXPECTED;
  157.     if (m_pFileSwitcher && (m_State == MEMPGR_Ready))
  158.     {
  159. retVal = HXR_NO_DATA;
  160. m_pFaultedPageVirtualAddr = pVirtualAddr;
  161. m_ulFaultedPageSize = ulSize;
  162. if (m_ulFaultedPageSize < m_ulMinPageSize)
  163. {
  164.     m_ulFaultedPageSize = m_ulMinPageSize;
  165. }
  166. if ((m_pBaseVirtualAddr + m_ulAddrSpaceSize) < 
  167.     (m_pFaultedPageVirtualAddr + m_ulFaultedPageSize))
  168. {
  169.     m_ulFaultedPageSize = (m_pBaseVirtualAddr + m_ulAddrSpaceSize) -
  170.   m_pFaultedPageVirtualAddr;
  171. }
  172. if (m_ulFaultedPageSize == 0)
  173. {
  174.     m_pFaultedPageVirtualAddr = NULL;
  175.     return HXR_FAIL;
  176. }
  177. // Page in here only if it can be done synchronously
  178. if (SUCCEEDED(m_pFileSwitcher->Advise(HX_FILEADVISE_SYNCACCESS)))
  179. {
  180.     m_bSyncMode = TRUE;
  181.     retVal = _LoadPage();
  182.     if (retVal == HXR_OK)
  183.     {
  184. retVal = HXR_FAIL;
  185. if ((m_ulFaultedPageSize == 0) &&
  186.     m_pPagePhysicalAddr)
  187. {
  188.     pPhysicalBaseAddr = m_pPagePhysicalAddr;
  189.     retVal = HXR_OK;
  190. }
  191.     }
  192.     m_bSyncMode = FALSE;
  193.     m_pFileSwitcher->Advise(HX_FILEADVISE_ASYNCACCESS);
  194. }
  195.     }
  196.     return retVal;
  197. }
  198. /****************************************************************************
  199.  *  _LoadPage
  200.  */
  201. HX_RESULT CMemPager::_LoadPage(void)
  202. {
  203.     ULONG32 ulOffset;
  204.     HX_RESULT retVal;
  205.     m_State = MEMPGR_ProcLoad;
  206.     ReleasePage();
  207.     HX_ASSERT(m_ulFaultedPageSize);
  208.     ulOffset = m_pFaultedPageVirtualAddr - 
  209.        m_pBaseVirtualAddr + 
  210.        m_ulAddrSpaceOffset;
  211.     retVal = m_pFileSwitcher->Seek(ulOffset,
  212.    FALSE,
  213.    (IHXFileResponse*) this);
  214.     if (FAILED(retVal))
  215.     {
  216. retVal = HandleResponse(retVal, NULL);
  217.     }
  218.     return retVal;
  219. }
  220. /****************************************************************************
  221.  *  ReleasePage
  222.  */
  223. void CMemPager::ReleasePage(void)
  224. {
  225.     m_ulPageSize = 0;
  226.     m_pPageVirtualAddr = NULL;
  227.     m_pPagePhysicalAddr = NULL;
  228.     HX_RELEASE(m_pPageBuffer);
  229. }
  230. /****************************************************************************
  231.  *  IHXFileResponse methods
  232.  */
  233. /****************************************************************************
  234.  *  InitDone
  235.  */
  236. STDMETHODIMP CMemPager::InitDone(HX_RESULT status)
  237. {
  238.     HX_RESULT retVal = HXR_UNEXPECTED;
  239.     return retVal;
  240. }
  241. /****************************************************************************
  242.  *  CloseDone
  243.  */
  244. STDMETHODIMP CMemPager::CloseDone(HX_RESULT status)
  245. {
  246.     HX_RESULT retVal = HXR_UNEXPECTED;
  247.     return retVal;
  248. }
  249. /****************************************************************************
  250.  *  ReadDone
  251.  */
  252. STDMETHODIMP CMemPager::ReadDone(HX_RESULT status,
  253.  IHXBuffer* pBuffer)
  254. {
  255.     HX_RESULT retVal = HXR_UNEXPECTED;
  256.     if (m_State == MEMPGR_ProcLoad)
  257.     {
  258. if (SUCCEEDED(status))
  259. {
  260.     status = HXR_FAIL;
  261.     if (pBuffer)
  262.     {
  263. ULONG32 ulSize = pBuffer->GetSize();
  264. if (ulSize == m_ulFaultedPageSize)
  265. {
  266.     HX_ASSERT(m_pPageBuffer == NULL);
  267.     m_pPageBuffer = pBuffer;
  268.     pBuffer->AddRef();
  269.     
  270.     m_pPageVirtualAddr = m_pFaultedPageVirtualAddr;
  271.     m_ulPageSize = m_ulFaultedPageSize;
  272.     m_pPagePhysicalAddr = pBuffer->GetBuffer() - 
  273.   (m_pPageVirtualAddr - 
  274.    m_pBaseVirtualAddr);
  275.     m_pFaultedPageVirtualAddr = NULL;
  276.     m_ulFaultedPageSize = 0;
  277.     status = HXR_OK;
  278. }
  279.     }
  280.     retVal = HandleResponse(status, pBuffer);
  281. }
  282.     }
  283.     return retVal;
  284. }
  285. /****************************************************************************
  286.  *  WriteDone
  287.  */
  288. STDMETHODIMP CMemPager::WriteDone(HX_RESULT status)
  289. {
  290.     HX_RESULT retVal = HXR_UNEXPECTED;
  291.     return retVal;
  292. }
  293. /****************************************************************************
  294.  *  SeekDone
  295.  */
  296. STDMETHODIMP CMemPager::SeekDone(HX_RESULT status)
  297. {
  298.     HX_RESULT retVal = HXR_UNEXPECTED;
  299.     HX_ASSERT(m_State == MEMPGR_ProcLoad);
  300.     if (m_State == MEMPGR_ProcLoad)
  301.     {
  302. HX_ASSERT(m_pFileSwitcher);
  303. if (SUCCEEDED(status))
  304. {
  305.     retVal = m_pFileSwitcher->Read(m_ulFaultedPageSize,
  306.    (IHXFileResponse*) this);
  307. }
  308. else
  309. {
  310.     retVal = HandleResponse(status);
  311. }
  312.     }
  313.     return retVal;
  314. }
  315. /****************************************************************************
  316.  *  HandleResponse
  317.  */
  318. HX_RESULT CMemPager::HandleResponse(HX_RESULT status, IHXBuffer* pBuffer)
  319. {
  320.     HX_RESULT retVal = status;
  321.     if (m_State == MEMPGR_ProcLoad)
  322.     {
  323. m_State = MEMPGR_Ready;
  324. if ((!m_bSyncMode) && m_pResponse)
  325. {
  326.     retVal = m_pResponse->ReadDone(status, pBuffer);
  327. }
  328.     }
  329.     
  330.     return retVal;
  331. }
  332. /****************************************************************************
  333.  *  IHXThreadSafeMethods method
  334.  */
  335. /****************************************************************************
  336.  *  IsThreadSafe
  337.  */
  338. STDMETHODIMP_(UINT32)
  339. CMemPager::IsThreadSafe()
  340. {
  341.     return HX_THREADSAFE_METHOD_FSR_READDONE;
  342. }
  343. /****************************************************************************
  344.  *  IUnknown methods
  345.  */
  346. /////////////////////////////////////////////////////////////////////////
  347. //  Method:
  348. // IUnknown::QueryInterface
  349. //
  350. STDMETHODIMP CMemPager::QueryInterface(REFIID riid, void** ppvObj)
  351. {
  352.     if (IsEqualIID(riid, IID_IHXFileResponse))
  353.     {
  354. AddRef();
  355. *ppvObj = (IHXFileResponse*) this;
  356. return HXR_OK;
  357.     }
  358.     else if (IsEqualIID(riid, IID_IUnknown))
  359.     {
  360. AddRef();
  361. *ppvObj = this;
  362. return HXR_OK;
  363.     }
  364.     else if (IsEqualIID(riid, IID_IHXThreadSafeMethods))
  365.     {
  366. AddRef();
  367. *ppvObj = (IHXThreadSafeMethods*) this;
  368. return HXR_OK;
  369.     }
  370.     *ppvObj = NULL;
  371.     return HXR_NOINTERFACE;
  372. }
  373. /////////////////////////////////////////////////////////////////////////
  374. //  Method:
  375. // IUnknown::AddRef
  376. //
  377. STDMETHODIMP_(ULONG32) CMemPager::AddRef()
  378. {
  379.     return InterlockedIncrement(&m_lRefCount);
  380. }
  381. /////////////////////////////////////////////////////////////////////////
  382. //  Method:
  383. // IUnknown::Release
  384. //
  385. STDMETHODIMP_(ULONG32) CMemPager::Release()
  386. {
  387.     if (InterlockedDecrement(&m_lRefCount) > 0)
  388.     {
  389.         return m_lRefCount;
  390.     }
  391.     delete this;
  392.     return 0;
  393. }