5 #include "../../../C/Alloc.h"
\r
7 #include "MemBlocks.h"
\r
8 #include "StreamUtils.h"
\r
10 bool CMemBlockManager::AllocateSpace(size_t numBlocks)
\r
13 if (_blockSize < sizeof(void *) || numBlocks < 1)
\r
15 size_t totalSize = numBlocks * _blockSize;
\r
16 if (totalSize / _blockSize != numBlocks)
\r
18 _data = ::MidAlloc(totalSize);
\r
21 Byte *p = (Byte *)_data;
\r
22 for (size_t i = 0; i + 1 < numBlocks; i++, p += _blockSize)
\r
23 *(Byte **)p = (p + _blockSize);
\r
29 void CMemBlockManager::FreeSpace()
\r
36 void *CMemBlockManager::AllocateBlock()
\r
40 void *p = _headFree;
\r
41 _headFree = *(void **)_headFree;
\r
45 void CMemBlockManager::FreeBlock(void *p)
\r
49 *(void **)p = _headFree;
\r
54 HRes CMemBlockManagerMt::AllocateSpace(size_t numBlocks, size_t numNoLockBlocks)
\r
56 if (numNoLockBlocks > numBlocks)
\r
57 return E_INVALIDARG;
\r
58 if (!CMemBlockManager::AllocateSpace(numBlocks))
\r
59 return E_OUTOFMEMORY;
\r
60 size_t numLockBlocks = numBlocks - numNoLockBlocks;
\r
62 return Semaphore.Create((LONG)numLockBlocks, (LONG)numLockBlocks);
\r
65 HRes CMemBlockManagerMt::AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks)
\r
67 if (numNoLockBlocks > desiredNumberOfBlocks)
\r
68 return E_INVALIDARG;
\r
71 if (AllocateSpace(desiredNumberOfBlocks, numNoLockBlocks) == 0)
\r
73 if (desiredNumberOfBlocks == numNoLockBlocks)
\r
74 return E_OUTOFMEMORY;
\r
75 desiredNumberOfBlocks = numNoLockBlocks + ((desiredNumberOfBlocks - numNoLockBlocks) >> 1);
\r
79 void CMemBlockManagerMt::FreeSpace()
\r
82 CMemBlockManager::FreeSpace();
\r
85 void *CMemBlockManagerMt::AllocateBlock()
\r
87 // Semaphore.Lock();
\r
88 NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
\r
89 return CMemBlockManager::AllocateBlock();
\r
92 void CMemBlockManagerMt::FreeBlock(void *p, bool lockMode)
\r
97 NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
\r
98 CMemBlockManager::FreeBlock(p);
\r
101 Semaphore.Release();
\r
104 void CMemBlocks::Free(CMemBlockManagerMt *manager)
\r
106 while(Blocks.Size() > 0)
\r
108 manager->FreeBlock(Blocks.Back());
\r
109 Blocks.DeleteBack();
\r
114 void CMemBlocks::FreeOpt(CMemBlockManagerMt *manager)
\r
117 Blocks.ClearAndFree();
\r
120 HRESULT CMemBlocks::WriteToStream(size_t blockSize, ISequentialOutStream *outStream) const
\r
122 UInt64 totalSize = TotalSize;
\r
123 for (int blockIndex = 0; totalSize > 0; blockIndex++)
\r
125 UInt32 curSize = (UInt32)blockSize;
\r
126 if (totalSize < curSize)
\r
127 curSize = (UInt32)totalSize;
\r
128 if (blockIndex >= Blocks.Size())
\r
130 RINOK(WriteStream(outStream, Blocks[blockIndex], curSize));
\r
131 totalSize -= curSize;
\r
137 void CMemLockBlocks::FreeBlock(int index, CMemBlockManagerMt *memManager)
\r
139 memManager->FreeBlock(Blocks[index], LockMode);
\r
143 void CMemLockBlocks::Free(CMemBlockManagerMt *memManager)
\r
145 while (Blocks.Size() > 0)
\r
147 FreeBlock(Blocks.Size() - 1, memManager);
\r
148 Blocks.DeleteBack();
\r
153 HRes CMemLockBlocks::SwitchToNoLockMode(CMemBlockManagerMt *memManager)
\r
157 if (Blocks.Size() > 0)
\r
159 RINOK(memManager->ReleaseLockedBlocks(Blocks.Size()));
\r
166 void CMemLockBlocks::Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager)
\r
168 blocks.Free(memManager);
\r
169 blocks.LockMode = LockMode;
\r
170 UInt64 totalSize = 0;
\r
171 size_t blockSize = memManager->GetBlockSize();
\r
172 for (int i = 0; i < Blocks.Size(); i++)
\r
174 if (totalSize < TotalSize)
\r
175 blocks.Blocks.Add(Blocks[i]);
\r
177 FreeBlock(i, memManager);
\r
179 totalSize += blockSize;
\r
181 blocks.TotalSize = TotalSize;
\r