Leaked source code of windows server 2003
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.

964 lines
24 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: Mem.CXX
  7. //
  8. // Contents: Memory tracking code
  9. //
  10. // Classes: CMemAlloc
  11. //
  12. // Functions: DfCreateSharedAllocator
  13. // DfPrintAllocs
  14. // DfGetMemAlloced
  15. //
  16. // History: 17-May-93 AlexT Created
  17. //
  18. //--------------------------------------------------------------------------
  19. #include <dfhead.cxx>
  20. #pragma hdrstop
  21. #if defined(WIN32)
  22. #include <smalloc.hxx>
  23. #include <olesem.hxx>
  24. #include <utils.hxx>
  25. // This global variable holds the base address of the shared memory region.
  26. // It is required by the based pointer stuff and is accessed directly.
  27. // Initialization is a side effect of calling DfCreateSharedAllocator or
  28. // DfSyncSharedMemory
  29. #ifdef MULTIHEAP
  30. //__declspec(thread) void *DFBASEPTR = NULL;
  31. #else
  32. void *DFBASEPTR = NULL;
  33. #endif
  34. #endif
  35. #if DBG == 1
  36. #include <dfdeb.hxx>
  37. #ifdef MEMTRACK
  38. #ifdef WIN32
  39. // Multithread protection for allocation list
  40. CStaticDfMutex _sdmtxAllocs(TSTR("DfAllocList"));
  41. #define TAKE_ALLOCS_MUTEX olVerSucc(_sdmtxAllocs.Take(INFINITE))
  42. #define RELEASE_ALLOCS_MUTEX _sdmtxAllocs.Release()
  43. #else
  44. #define TAKE_ALLOCS_MUTEX
  45. #define RELEASE_ALLOCS_MUTEX
  46. #endif
  47. #define GET_ALLOC_LIST_HEAD ((CMemAlloc *)DfGetResLimit(DBRI_ALLOC_LIST))
  48. #define SET_ALLOC_LIST_HEAD(pma) DfSetResLimit(DBRI_ALLOC_LIST, (LONG)(pma))
  49. #endif // MEMTRACK
  50. #define DEB_MEMORY 0x01000000
  51. #define DEB_LEAKS 0x01100000
  52. const int NEWMEM = 0xDEDE;
  53. const int OLDMEM = 0xEDED;
  54. //+--------------------------------------------------------------
  55. //
  56. // Class: CMemAlloc (ma)
  57. //
  58. // Purpose: Tracks memory allocations
  59. //
  60. // Interface: See below
  61. //
  62. // History: 08-Jul-92 DrewB Created
  63. // 17-May-93 AlexT Add idContext
  64. //
  65. //---------------------------------------------------------------
  66. class CMemAlloc
  67. {
  68. public:
  69. void *pvCaller;
  70. void *pvMem;
  71. ULONG cbSize;
  72. ContextId idContext;
  73. #ifdef MEMTRACK
  74. CMemAlloc *pmaPrev, *pmaNext;
  75. #endif
  76. };
  77. //+---------------------------------------------------------------------------
  78. //
  79. // Function: AddAlloc, private
  80. //
  81. // Synopsis: Puts an allocation into the allocation list
  82. //
  83. // Arguments: [pma] - Allocation descriptor
  84. // [pvCaller] - Allocator
  85. // [cbSize] - Real size
  86. // [pvMem] - Memory block
  87. // [cid] - Context ID
  88. //
  89. // History: 11-Jan-94 DrewB Created
  90. //
  91. //----------------------------------------------------------------------------
  92. #if DBG == 1
  93. static void AddAlloc(CMemAlloc *pma, void *pvCaller, ULONG cbSize,
  94. void *pvMem, ContextId cid)
  95. {
  96. pma->pvCaller = pvCaller;
  97. pma->cbSize = cbSize;
  98. pma->pvMem = pvMem;
  99. pma->idContext = cid;
  100. #ifdef MEMTRACK
  101. TAKE_ALLOCS_MUTEX;
  102. pma->pmaNext = GET_ALLOC_LIST_HEAD;
  103. if (pma->pmaNext)
  104. pma->pmaNext->pmaPrev = pma;
  105. pma->pmaPrev = NULL;
  106. SET_ALLOC_LIST_HEAD(pma);
  107. RELEASE_ALLOCS_MUTEX;
  108. ModifyResLimit(DBRQ_MEMORY_ALLOCATED, (LONG)cbSize);
  109. olDebugOut((DEB_MEMORY, "%s alloced %p:%lu, total %ld\n",
  110. cid != 0 ? "Task" : "Shrd",
  111. pvMem, pma->cbSize, DfGetResLimit(DBRQ_MEMORY_ALLOCATED)));
  112. #endif
  113. }
  114. #endif
  115. //+---------------------------------------------------------------------------
  116. //
  117. // Function: RemoveAlloc, private
  118. //
  119. // Synopsis: Takes an allocation out of the allocation list
  120. //
  121. // Arguments: [pma] - Allocation descriptor
  122. // [pvMem] - Real allocation
  123. // [cid] - Context ID
  124. //
  125. // History: 11-Jan-94 DrewB Created
  126. //
  127. //----------------------------------------------------------------------------
  128. #if DBG == 1
  129. static void RemoveAlloc(CMemAlloc *pma, void *pvMem, ContextId cid)
  130. {
  131. #ifdef MEMTRACK
  132. olAssert(pma->pvMem == pvMem && aMsg("Address mismatch"));
  133. olAssert(pma->idContext == cid && aMsg("Context mismatch"));
  134. TAKE_ALLOCS_MUTEX;
  135. if (pma->pmaPrev)
  136. {
  137. pma->pmaPrev->pmaNext = pma->pmaNext;
  138. }
  139. else
  140. {
  141. SET_ALLOC_LIST_HEAD(pma->pmaNext);
  142. }
  143. if (pma->pmaNext)
  144. {
  145. pma->pmaNext->pmaPrev = pma->pmaPrev;
  146. }
  147. RELEASE_ALLOCS_MUTEX;
  148. ModifyResLimit(DBR_MEMORY, (LONG)pma->cbSize);
  149. ModifyResLimit(DBRQ_MEMORY_ALLOCATED, -(LONG)pma->cbSize);
  150. olAssert(DfGetResLimit(DBRQ_MEMORY_ALLOCATED) >= 0);
  151. olDebugOut((DEB_MEMORY, "%s freed %p:%lu, total %ld\n",
  152. cid != 0 ? "Task" : "Shrd",
  153. pma->pvMem, pma->cbSize,
  154. DfGetResLimit(DBRQ_MEMORY_ALLOCATED)));
  155. #endif
  156. }
  157. #endif
  158. //+---------------------------------------------------------------------------
  159. //
  160. // Function: DfGetMemAlloced, private
  161. //
  162. // Synopsis: Returns the amount of memory currently allocated
  163. //
  164. // History: 08-Jul-92 DrewB Created
  165. //
  166. //----------------------------------------------------------------------------
  167. STDAPI_(LONG) DfGetMemAlloced(void)
  168. {
  169. return DfGetResLimit(DBRQ_MEMORY_ALLOCATED);
  170. }
  171. //+--------------------------------------------------------------
  172. //
  173. // Function: DfPrintAllocs, private
  174. //
  175. // Synopsis: Walks the allocation list and prints out their info
  176. //
  177. // History: 08-Jul-92 DrewB Created
  178. //
  179. //---------------------------------------------------------------
  180. STDAPI_(void) DfPrintAllocs(void)
  181. {
  182. #ifdef MEMTRACK
  183. CMemAlloc *pma;
  184. olDebugOut((DEB_ITRACE, "In DfPrintAllocs()\n"));
  185. TAKE_ALLOCS_MUTEX;
  186. pma = GET_ALLOC_LIST_HEAD;
  187. while (pma != NULL)
  188. {
  189. olDebugOut((DEB_LEAKS, "Alloc %s: %p alloc %p:%4lu bytes\n",
  190. pma->idContext ? "LOCAL" : "SHARED",
  191. pma->pvCaller, pma->pvMem, pma->cbSize));
  192. pma = pma->pmaNext;
  193. }
  194. RELEASE_ALLOCS_MUTEX;
  195. olDebugOut((DEB_ITRACE, "Out DfPrintAllocs\n"));
  196. #endif
  197. }
  198. #endif
  199. #ifdef MULTIHEAP
  200. CSmAllocator g_SmAllocator; // optimization for single threaded case
  201. CErrorSmAllocator g_ErrorSmAllocator;
  202. IMalloc *g_pTaskAllocator = 0;
  203. CSharedMemoryBlock g_smb; // optimize single threaded case
  204. ULONG g_ulHeapName = 0; // name of the above heap
  205. TEB * g_pteb = NtCurrentTeb();
  206. CSmAllocator& GetTlsSmAllocator()
  207. {
  208. HRESULT hr;
  209. COleTls otls(hr); // even for main thread, we need to initialize TLS
  210. memAssert (SUCCEEDED(hr) && "Error initializing TLS");
  211. if (g_pteb == NtCurrentTeb())
  212. {
  213. // return the static global allocator for main thread
  214. // DoThreadSpecificCleanup does not deallocate this allocator
  215. return g_SmAllocator;
  216. }
  217. if (otls->pSmAllocator == NULL)
  218. {
  219. if ((otls->pSmAllocator = new CSmAllocator()) == NULL)
  220. otls->pSmAllocator = &g_ErrorSmAllocator;
  221. // DoThreadSpecificCleanup will deallocate this when thread goes away
  222. }
  223. return *(otls->pSmAllocator);
  224. }
  225. //
  226. // This initialization used to be done in the global allocator
  227. // which is now a per thread allocator
  228. //
  229. class CResourceCriticalSection
  230. {
  231. public:
  232. CResourceCriticalSection ()
  233. {
  234. #if WIN32 == 100
  235. _nts = RtlInitializeCriticalSection(&g_csScratchBuffer);
  236. #else
  237. InitializeCriticalSection(&g_csScratchBuffer);
  238. #endif
  239. }
  240. ~CResourceCriticalSection ()
  241. {
  242. #if WIN32 == 100
  243. if (NT_SUCCESS(_nts))
  244. #endif
  245. DeleteCriticalSection(&g_csScratchBuffer);
  246. }
  247. #if WIN32 == 100
  248. HRESULT GetInitializationError ()
  249. {
  250. return NtStatusToScode(_nts);
  251. }
  252. private:
  253. NTSTATUS _nts;
  254. #endif
  255. };
  256. CResourceCriticalSection g_ResourceCriticalSection;
  257. #else
  258. CSmAllocator g_smAllocator;
  259. #endif // MULTIHEAP
  260. //+-------------------------------------------------------------------------
  261. //
  262. // Member: CMallocBased::operator new, public
  263. //
  264. // Synopsis: Overridden allocator
  265. //
  266. // Effects: Allocates memory from given allocator
  267. //
  268. // Arguments: [size] -- byte count to allocate
  269. // [pMalloc] -- allocator
  270. //
  271. // Returns: memory block address
  272. //
  273. // Algorithm:
  274. //
  275. // History: 21-May-93 AlexT Created
  276. //
  277. // Notes:
  278. //
  279. //--------------------------------------------------------------------------
  280. void *CMallocBased::operator new(size_t size, IMalloc * const pMalloc)
  281. {
  282. #ifndef WIN32
  283. olAssert(DfGetResLimit(DBRQ_MEMORY_ALLOCATED) >= 0);
  284. #endif
  285. olAssert(size > 0);
  286. #if DBG==1
  287. if (SimulateFailure(DBF_MEMORY))
  288. {
  289. return(NULL);
  290. }
  291. if (!HaveResource(DBR_MEMORY, (LONG)size))
  292. {
  293. // Artificial limit exceeded so force failure
  294. return NULL;
  295. }
  296. #endif
  297. void *pv = g_smAllocator.Alloc(
  298. #if DBG==1
  299. sizeof(CMemAlloc) +
  300. #endif
  301. size);
  302. if (pv == NULL)
  303. {
  304. #if DBG==1
  305. ModifyResLimit(DBR_MEMORY, (LONG)size);
  306. #endif
  307. return NULL;
  308. }
  309. #if DBG==1
  310. memset(pv, NEWMEM, sizeof(CMemAlloc) + size);
  311. #endif
  312. #if DBG==1
  313. // Put debug info in buffer
  314. // Note: This assumes CMemAlloc will end up properly aligned
  315. CMemAlloc *pma = (CMemAlloc *) pv;
  316. pv = (void *) ((CMemAlloc *) pv + 1);
  317. #if defined(_X86_)
  318. PVOID ra = *(((void **)&size)-1);
  319. #else
  320. PVOID ra = _ReturnAddress();
  321. #endif
  322. AddAlloc(pma, ra, (ULONG) size, pv, 0);
  323. #endif
  324. return pv;
  325. }
  326. //+-------------------------------------------------------------------------
  327. //
  328. // Member: CMallocBased::operator delete
  329. //
  330. // Synopsis: Overridden deallocator
  331. //
  332. // Effects: Frees memory block
  333. //
  334. // Arguments: [pv] -- memory block address
  335. //
  336. // Algorithm:
  337. //
  338. // History: 21-May-93 AlexT Created
  339. //
  340. // Notes:
  341. //
  342. //--------------------------------------------------------------------------
  343. void CMallocBased::operator delete(void *pv)
  344. {
  345. if (pv == NULL)
  346. return;
  347. #if DBG==1
  348. // Assumes ma ends up properly aligned
  349. CMemAlloc *pma = (CMemAlloc *) pv;
  350. pma--;
  351. RemoveAlloc(pma, pv, 0);
  352. pv = (void *) pma;
  353. memset(pv, OLDMEM, (size_t) pma->cbSize);
  354. #endif
  355. g_smAllocator.Free(pv);
  356. }
  357. //+-------------------------------------------------------------------------
  358. //
  359. // Member: CMallocBased::deleteNoMutex
  360. //
  361. // Synopsis: deallocator function without Mutex
  362. //
  363. // Effects: Frees memory block
  364. //
  365. // Arguments: [pv] -- memory block address
  366. // Algorithm:
  367. //
  368. // History: 19-Jul-95 SusiA Created
  369. //
  370. // Notes:
  371. //
  372. //--------------------------------------------------------------------------
  373. void CMallocBased::deleteNoMutex(void *pv)
  374. {
  375. if (pv == NULL)
  376. return;
  377. #if DBG==1
  378. // Assumes ma ends up properly aligned
  379. CMemAlloc *pma = (CMemAlloc *) pv;
  380. pma--;
  381. RemoveAlloc(pma, pv, 0);
  382. pv = (void *) pma;
  383. memset(pv, OLDMEM, (size_t) pma->cbSize);
  384. #endif
  385. g_smAllocator.FreeNoMutex(pv);
  386. }
  387. #if !defined(WIN32) && DBG==1
  388. //+-------------------------------------------------------------------------
  389. //
  390. // Class: CSharedMalloc
  391. //
  392. // Purpose: Track shared allocators
  393. //
  394. // Interface: IMalloc
  395. //
  396. // History: 28-May-93 AlexT Created
  397. //
  398. // Notes: This is only for builds that use CoCreateStandardMalloc
  399. // (which is non-WIN32 builds for now). We inherit from
  400. // CMallocBased to pick up memory tracking.
  401. //
  402. //--------------------------------------------------------------------------
  403. class CSharedMalloc : public IMalloc, public CMallocBased
  404. {
  405. public:
  406. CSharedMalloc(IMalloc *pMalloc);
  407. // *** IUnknown methods ***
  408. STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj);
  409. STDMETHOD_(ULONG,AddRef) (THIS);
  410. STDMETHOD_(ULONG,Release) (THIS);
  411. // *** IMalloc methods ***
  412. STDMETHOD_(void FAR*, Alloc) (THIS_ SIZE_T cb);
  413. STDMETHOD_(void FAR*, Realloc) (THIS_ void FAR* pv, SIZE_T cb);
  414. STDMETHOD_(void, Free) (THIS_ void FAR* pv);
  415. STDMETHOD_(SIZE_T, GetSize) (THIS_ void FAR* pv);
  416. STDMETHOD_(int, DidAlloc) (THIS_ void FAR* pv);
  417. STDMETHOD_(void, HeapMinimize) (THIS);
  418. private:
  419. IMalloc * const _pMalloc;
  420. };
  421. CSharedMalloc::CSharedMalloc(IMalloc *pMalloc)
  422. : _pMalloc(pMalloc)
  423. {
  424. _pMalloc->AddRef();
  425. }
  426. STDMETHODIMP CSharedMalloc::QueryInterface(THIS_ REFIID riid, LPVOID FAR* ppvObj)
  427. {
  428. olAssert(!aMsg("CSharedMalloc::QueryInterface unsupported"));
  429. return(ResultFromScode(E_UNEXPECTED));
  430. }
  431. STDMETHODIMP_(ULONG) CSharedMalloc::AddRef (THIS)
  432. {
  433. return(_pMalloc->AddRef());
  434. }
  435. STDMETHODIMP_(ULONG) CSharedMalloc::Release (THIS)
  436. {
  437. ULONG cRef = _pMalloc->Release();
  438. if (cRef == 0)
  439. delete this;
  440. return (ULONG) cRef;
  441. }
  442. STDMETHODIMP_(void FAR*) CSharedMalloc::Alloc (THIS_ SIZE_T cb)
  443. {
  444. return _pMalloc->Alloc(cb);
  445. }
  446. STDMETHODIMP_(void FAR*) CSharedMalloc::Realloc (THIS_ void FAR* pv, SIZE_T cb)
  447. {
  448. olAssert(!aMsg("CSharedMalloc::Realloc unsupported"));
  449. return(NULL);
  450. }
  451. STDMETHODIMP_(void) CSharedMalloc::Free (THIS_ void FAR* pv)
  452. {
  453. _pMalloc->Free(pv);
  454. }
  455. STDMETHODIMP_(SIZE_T) CSharedMalloc::GetSize (THIS_ void FAR* pv)
  456. {
  457. olAssert(!aMsg("CSharedMalloc::GetSize unsupported"));
  458. return(0);
  459. }
  460. STDMETHODIMP_(int) CSharedMalloc::DidAlloc (THIS_ void FAR* pv)
  461. {
  462. olAssert(!aMsg("CSharedMalloc::DidAlloc unsupported"));
  463. return(TRUE);
  464. }
  465. STDMETHODIMP_(void) CSharedMalloc::HeapMinimize (THIS)
  466. {
  467. olAssert(!aMsg("CSharedMalloc::HeapMinimize unsupported"));
  468. }
  469. #endif
  470. #if !defined(MULTIHEAP)
  471. COleStaticMutexSem mxsInitSm;
  472. BOOL fInitialisedSm = FALSE;
  473. //+-------------------------------------------------------------------------
  474. //
  475. // Function: DfCreateSharedAllocator
  476. //
  477. // Synopsis: Initialises the shared memory region for this process.
  478. //
  479. // Arguments: [ppm] -- return address for shared memory IMalloc*
  480. //
  481. // Returns: status code
  482. //
  483. // History: 27-May-94 MikeSe Created
  484. //
  485. // Notes: This routine is called indirectly through DfCreateSharedAllocator, in
  486. // such a way that in most circumstances it will be executed
  487. // exactly once per process. (Because we overwrite the contents
  488. // of DfCreateSharedAllocator if successful).
  489. //
  490. // However, in order to be multi-thread safe, we need a process
  491. // mutex to prevent execution of the initialisation code twice.
  492. //
  493. // Furthermore, since we are initialising system-wide state
  494. // (namely the shared memory region) we must provide cross-process
  495. // mutual exclusion over this activity.
  496. //
  497. //--------------------------------------------------------------------------
  498. HRESULT DfCreateSharedAllocator (IMalloc ** ppm, BOOL fTaskMemory )
  499. {
  500. // multi-thread safety
  501. mxsInitSm.Request();
  502. HRESULT hr = S_OK;
  503. if ( !fInitialisedSm )
  504. {
  505. // We need to do the initialisation. Obtain exclusion against
  506. // other processes.
  507. SECURITY_ATTRIBUTES secattr;
  508. secattr.nLength = sizeof(SECURITY_ATTRIBUTES);
  509. #ifndef _CHICAGO_
  510. CWorldSecurityDescriptor wsd;
  511. secattr.lpSecurityDescriptor = &wsd;
  512. #else
  513. secattr.lpSecurityDescriptor = NULL;
  514. #endif // !_CHICAGO_
  515. secattr.bInheritHandle = FALSE;
  516. HANDLE hMutex = CreateMutex ( &secattr, FALSE, TEXT("OleDfSharedMemoryMutex"));
  517. if ( hMutex == NULL && GetLastError() == ERROR_ACCESS_DENIED )
  518. hMutex = OpenMutex(SYNCHRONIZE, FALSE, TEXT("OleDfSharedMemoryMutex"));
  519. if ( hMutex != NULL )
  520. {
  521. WaitForSingleObject ( hMutex, INFINITE );
  522. hr = g_smAllocator.Init ( DOCFILE_SM_NAME );
  523. if ( SUCCEEDED(hr) )
  524. {
  525. *ppm = &g_smAllocator;
  526. // Also set up base address
  527. #ifdef USEBASED
  528. DFBASEPTR = g_smAllocator.GetBase();
  529. #endif
  530. fInitialisedSm = TRUE;
  531. }
  532. ReleaseMutex ( hMutex );
  533. }
  534. else
  535. hr = HRESULT_FROM_WIN32(GetLastError());
  536. }
  537. else // fInitialisedSm is TRUE
  538. {
  539. *ppm = &g_smAllocator;
  540. }
  541. mxsInitSm.Release();
  542. return hr;
  543. }
  544. #endif // !defined(MULTIHEAP)
  545. #ifdef MULTIHEAP
  546. //+-------------------------------------------------------------------------
  547. //
  548. // Function: DfCreateSharedAllocator
  549. //
  550. // Synopsis: Initialises a shared memory region for this process.
  551. //
  552. // Arguments: [ppm] -- return address for shared memory IMalloc*
  553. //
  554. // Returns: status code
  555. //
  556. // History: 20-Nov-95 HenryLee Created
  557. //
  558. // Notes: This routine is called indirectly by DfCreateSharedAllocator
  559. // such a way that in most circumstances it will be executed
  560. // exactly once per docfile open.
  561. //
  562. //--------------------------------------------------------------------------
  563. HRESULT DfCreateSharedAllocator (IMalloc ** ppm, BOOL fTaskMemory )
  564. {
  565. HRESULT hr = S_OK;
  566. #if WIN32 == 100
  567. hr = g_ResourceCriticalSection.GetInitializationError();
  568. if (!SUCCEEDED(hr))
  569. return hr;
  570. #endif
  571. COleTls otls(hr); // check if TLS is initialized
  572. if (!SUCCEEDED(hr))
  573. return hr;
  574. CSmAllocator *pMalloc = &g_smAllocator;
  575. *ppm = NULL;
  576. if ((gs_iSharedHeaps > (DOCFILE_SM_LIMIT / DOCFILE_SM_SIZE)) ||
  577. fTaskMemory)
  578. {
  579. // use task allocator if we eat up 1Gig of address space
  580. if (g_pTaskAllocator == NULL)
  581. {
  582. hr = CoGetMalloc (MEMCTX_TASK, &g_pTaskAllocator);
  583. if (!SUCCEEDED(hr))
  584. return hr;
  585. }
  586. // reset the allocator state to initialize it properly
  587. pMalloc->SetState (NULL, NULL, NULL, NULL, 0);
  588. DFBASEPTR = 0;
  589. *ppm = g_pTaskAllocator;
  590. }
  591. else
  592. {
  593. LUID luid; // generate a unique name
  594. if (AllocateLocallyUniqueId (&luid) == FALSE)
  595. return HRESULT_FROM_WIN32(GetLastError());
  596. // reset the allocator state to initialize it properly
  597. pMalloc->SetState (NULL, NULL, NULL, NULL, 0);
  598. hr = pMalloc->Init ( luid.LowPart, FALSE );
  599. if ( SUCCEEDED(hr) )
  600. {
  601. *ppm = pMalloc;
  602. DFBASEPTR = pMalloc->GetBase();
  603. pMalloc->AddRef();
  604. }
  605. }
  606. return hr;
  607. }
  608. #endif
  609. //+---------------------------------------------------------------------------
  610. //
  611. // Function: DfSyncSharedMemory, public
  612. //
  613. // Synopsis: Sync up shared memory
  614. //
  615. // Returns: Appropriate status code
  616. //
  617. // History: 08-Apr-94 PhilipLa Created
  618. //
  619. // Notes:
  620. //
  621. //----------------------------------------------------------------------------
  622. #ifdef MULTIHEAP
  623. SCODE DfSyncSharedMemory(ULONG ulHeapName)
  624. #else
  625. SCODE DfSyncSharedMemory(void)
  626. #endif
  627. {
  628. // make sure we have initialised
  629. HRESULT hr = S_OK;
  630. #ifdef MULTIHEAP
  631. CSmAllocator *pMalloc = &g_smAllocator;
  632. if (ulHeapName != 0) // reopen a shared heap for unmarshaling
  633. {
  634. // reset the allocator state to initialize it properly
  635. pMalloc->SetState (NULL, NULL, NULL, NULL, 0);
  636. hr = pMalloc->Init ( ulHeapName, TRUE);
  637. DFBASEPTR = pMalloc->GetBase();
  638. }
  639. else // try to create a new shared heap
  640. #else
  641. if (!fInitialisedSm)
  642. #endif // MULTIHEAP
  643. {
  644. IMalloc * pm;
  645. hr = DfCreateSharedAllocator ( &pm, FALSE );
  646. }
  647. if ( SUCCEEDED(hr) )
  648. #ifdef MULTIHEAP
  649. hr = pMalloc->Sync();
  650. #else
  651. hr = g_smAllocator.Sync();
  652. #endif
  653. return hr;
  654. }
  655. //+---------------------------------------------------------------------------
  656. //
  657. // Function: DfInitSharedMemBase, public
  658. //
  659. // Synopsis: Set up the base of shared memory
  660. //
  661. // History: 31-May-94 MikeSe Created
  662. //
  663. // Notes:
  664. //
  665. //----------------------------------------------------------------------------
  666. void DfInitSharedMemBase()
  667. {
  668. #if !defined MULTIHEAP
  669. // make sure we have initialised. This is sufficient to ensure
  670. // that DFBASEPTR is set up
  671. if (!fInitialisedSm)
  672. {
  673. IMalloc * pm;
  674. HRESULT hr = DfCreateSharedAllocator ( &pm );
  675. }
  676. #endif
  677. }
  678. #if DBG==1 && !defined(MULTIHEAP)
  679. //+-------------------------------------------------------------------------
  680. //
  681. // Method: CLocalAlloc::operator new, public
  682. //
  683. // Synopsis: Overloaded new operator to allocate objects from
  684. // task local space.
  685. //
  686. // Arguments: [size] -- Size of block to allocate
  687. //
  688. // Returns: Pointer to memory allocated.
  689. //
  690. // History: 17-Aug-92 PhilipLa Created.
  691. // 18-May-93 AlexT Switch to task IMalloc
  692. //
  693. //--------------------------------------------------------------------------
  694. void *CLocalAlloc::operator new(size_t size)
  695. {
  696. #ifndef WIN32
  697. olAssert(DfGetResLimit(DBRQ_MEMORY_ALLOCATED) >= 0);
  698. #endif
  699. olAssert(size > 0);
  700. if (SimulateFailure(DBF_MEMORY))
  701. {
  702. return(NULL);
  703. }
  704. if (!HaveResource(DBR_MEMORY, (LONG)size))
  705. {
  706. // Artificial limit exceeded so force failure
  707. return NULL;
  708. }
  709. void *pv = TaskMemAlloc(sizeof(CMemAlloc *) + size);
  710. if (pv != NULL)
  711. {
  712. void * const pvOrig = pv;
  713. memset(pv, NEWMEM, sizeof(CMemAlloc *) + size);
  714. CMemAlloc *pma = NULL;
  715. // Allocate tracking block (with shared memory)
  716. IMalloc *pMalloc;
  717. #ifdef WIN32
  718. #ifdef MULTIHEAP
  719. pMalloc = &g_smAllocator;
  720. #else
  721. if ( FAILED(DfCreateSharedAllocator ( &pMalloc )) )
  722. pMalloc = NULL;
  723. #endif // MULTIHEAP
  724. #else
  725. if (FAILED(DfGetScode(CoGetMalloc(MEMCTX_SHARED, &pMalloc))))
  726. pMalloc = NULL;
  727. #endif
  728. if (pMalloc)
  729. {
  730. pma = (CMemAlloc *) pMalloc->Alloc(sizeof(CMemAlloc));
  731. if (pma != NULL)
  732. {
  733. memset(pma, NEWMEM, sizeof(CMemAlloc));
  734. CMemAlloc **ppma = (CMemAlloc **) pv;
  735. pv = (void *) ((CMemAlloc **)pv + 1);
  736. *ppma = pma;
  737. AddAlloc(pma, *(((void **)&size)-1), size, pv,
  738. GetCurrentContextId());
  739. }
  740. pMalloc->Release();
  741. }
  742. if (pma == NULL)
  743. {
  744. // Couldn't allocate tracking block - fail allocation
  745. TaskMemFree(pvOrig);
  746. pv = NULL;
  747. }
  748. }
  749. if (pv == NULL)
  750. {
  751. ModifyResLimit(DBR_MEMORY, (LONG)size);
  752. }
  753. return(pv);
  754. }
  755. //+-------------------------------------------------------------------------
  756. //
  757. // Method: CLocalAlloc::operator delete, public
  758. //
  759. // Synopsis: Free memory from task local space
  760. //
  761. // Arguments: [pv] -- Pointer to memory to free
  762. //
  763. // History: 17-Aug-92 PhilipLa Created.
  764. // 18-May-93 AlexT Switch to task IMalloc
  765. //
  766. //--------------------------------------------------------------------------
  767. void CLocalAlloc::operator delete(void *pv)
  768. {
  769. if (pv == NULL)
  770. return;
  771. CMemAlloc **ppma = (CMemAlloc **)pv;
  772. ppma--;
  773. CMemAlloc *pma = *ppma;
  774. RemoveAlloc(pma, pv, GetCurrentContextId());
  775. pv = (void *) ppma;
  776. memset(pv, OLDMEM, (size_t) pma->cbSize);
  777. // Free tracking block
  778. IMalloc *pMalloc = NULL;
  779. #ifdef WIN32
  780. #ifdef MULTIHEAP
  781. pMalloc = &g_smAllocator;
  782. #else
  783. if ( FAILED(DfCreateSharedAllocator ( &pMalloc )) )
  784. pMalloc = NULL;
  785. #endif // MULTIHEAP
  786. #else
  787. if (FAILED(DfGetScode(CoGetMalloc(MEMCTX_SHARED, &pMalloc))))
  788. pMalloc = NULL;
  789. #endif
  790. if (pMalloc != NULL)
  791. {
  792. memset(pma, OLDMEM, sizeof(CMemAlloc));
  793. pMalloc->Free(pma);
  794. pMalloc->Release();
  795. }
  796. else
  797. olAssert(!aMsg("Unable to get shared allocator\n"));
  798. TaskMemFree(pv);
  799. }
  800. #endif // DBG==1 && !defined(MULTIHEAP)