1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 #include "oscl_mem_mempool.h"
19
20
21 /**
22 * OsclMemPoolFixedChunkAllocator section
23 **/
24
OsclMemPoolFixedChunkAllocator(const uint32 numchunk,const uint32 chunksize,Oscl_DefAlloc * gen_alloc)25 OSCL_EXPORT_REF OsclMemPoolFixedChunkAllocator::OsclMemPoolFixedChunkAllocator(const uint32 numchunk, const uint32 chunksize, Oscl_DefAlloc* gen_alloc) :
26 iNumChunk(1), iChunkSize(0), iChunkSizeMemAligned(0),
27 iMemPoolAllocator(gen_alloc), iMemPool(NULL),
28 iCheckNextAvailableFreeChunk(false), iObserver(NULL),
29 iNextAvailableContextData(NULL),
30 iRefCount(1),
31 iEnableNullPtrReturn(false)
32 {
33 iNumChunk = numchunk;
34 iChunkSize = chunksize;
35
36 if (iNumChunk == 0)
37 {
38 iNumChunk = 1;
39 }
40
41 if (iChunkSize > 0)
42 {
43 createmempool();
44 }
45 }
46
enablenullpointerreturn()47 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::enablenullpointerreturn()
48 {
49 iEnableNullPtrReturn = true;
50 }
51
addRef()52 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::addRef()
53 {
54 // Just increment the ref count
55 ++iRefCount;
56 }
57
removeRef()58 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::removeRef()
59 {
60 // Decrement the ref count
61 --iRefCount;
62
63 // If ref count reaches 0 then destroy this object automatically
64 if (iRefCount <= 0)
65 {
66 OSCL_DELETE(this);
67 }
68 }
69
70
~OsclMemPoolFixedChunkAllocator()71 OSCL_EXPORT_REF OsclMemPoolFixedChunkAllocator::~OsclMemPoolFixedChunkAllocator()
72 {
73 // Decrement the ref count
74 --iRefCount;
75
76 // If ref count reaches 0 then destroy this object
77 if (iRefCount <= 0)
78 {
79 destroymempool();
80 }
81 }
82
83
allocate(const uint32 n)84 OSCL_EXPORT_REF OsclAny* OsclMemPoolFixedChunkAllocator::allocate(const uint32 n)
85 {
86 // Create the memory pool if it hasn't been created yet.
87 // Use the allocation size, n, as the chunk size for memory pool
88 if (iChunkSize == 0)
89 {
90 iChunkSize = n;
91 createmempool();
92 }
93 else if (n > iChunkSize)
94 {
95 OSCL_LEAVE(OsclErrArgument);
96 // OSCL_UNUSED_RETURN(NULL); This statement was removed to avoid compiler warning for Unreachable Code
97
98 }
99
100 if (iFreeMemChunkList.empty())
101 {
102 // No free chunk is available
103 if (iEnableNullPtrReturn)
104 {
105 return NULL;
106 }
107 else
108 {
109 OSCL_LEAVE(OsclErrNoResources);
110 }
111 }
112
113 // Return the next available chunk from the pool
114 OsclAny* freechunk = iFreeMemChunkList.back();
115 // Remove the chunk from the free list
116 iFreeMemChunkList.pop_back();
117 addRef();
118 return freechunk;
119 }
120
121
deallocate(OsclAny * p)122 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::deallocate(OsclAny* p)
123 {
124 if (iMemPool == NULL)
125 {
126 // Memory pool hasn't been allocated yet so error
127 OSCL_LEAVE(OsclErrNotReady);
128 }
129
130 uint8* ptmp = (uint8*)p;
131 uint8* mptmp = (uint8*)iMemPool;
132
133 if ((ptmp < mptmp) || ptmp >= (mptmp + iNumChunk*iChunkSizeMemAligned))
134 {
135 // Returned memory is not part of this memory pool
136 OSCL_LEAVE(OsclErrArgument);
137 }
138
139 if (((ptmp - mptmp) % iChunkSizeMemAligned) != 0)
140 {
141 // Returned memory is not aligned to the chunk.
142 OSCL_LEAVE(OsclErrArgument);
143 }
144
145 // Put the returned chunk in the free pool
146 iFreeMemChunkList.push_back(p);
147
148 // Notify the observer about free chunk available if waiting for such callback
149 if (iCheckNextAvailableFreeChunk)
150 {
151 iCheckNextAvailableFreeChunk = false;
152 if (iObserver)
153 {
154 iObserver->freechunkavailable(iNextAvailableContextData);
155 }
156 }
157
158 // Decrement the refcount since deallocating succeeded
159 removeRef();
160 }
161
162
notifyfreechunkavailable(OsclMemPoolFixedChunkAllocatorObserver & obs,OsclAny * aContextData)163 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::notifyfreechunkavailable(OsclMemPoolFixedChunkAllocatorObserver& obs, OsclAny* aContextData)
164 {
165 iCheckNextAvailableFreeChunk = true;
166 iObserver = &obs;
167 iNextAvailableContextData = aContextData;
168 }
169
CancelFreeChunkAvailableCallback()170 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::CancelFreeChunkAvailableCallback()
171 {
172 iCheckNextAvailableFreeChunk = false;
173 iObserver = NULL;
174 iNextAvailableContextData = NULL;
175 }
176
createmempool()177 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::createmempool()
178 {
179 if (iChunkSize == 0 || iNumChunk == 0)
180 {
181 OSCL_LEAVE(OsclErrArgument);
182 }
183
184 // Create one block of memory for the memory pool
185 iChunkSizeMemAligned = oscl_mem_aligned_size(iChunkSize);
186 int32 leavecode = 0;
187 if (iMemPoolAllocator)
188 {
189 OSCL_TRY(leavecode, iMemPool = iMemPoolAllocator->ALLOCATE(iNumChunk * iChunkSizeMemAligned));
190 }
191 else
192 {
193 iMemPool = OSCL_MALLOC(iNumChunk * iChunkSizeMemAligned);
194 }
195
196 if (leavecode || iMemPool == NULL)
197 {
198 OSCL_LEAVE(OsclErrNoMemory);
199 }
200
201 #if OSCL_MEM_FILL_WITH_PATTERN
202 oscl_memset(iMemPool, 0x55, iNumChunk*iChunkSizeMemAligned);
203 #endif
204
205 // Set up the free mem chunk list vector
206 iFreeMemChunkList.reserve(iNumChunk);
207 uint8* chunkptr = (uint8*)iMemPool;
208
209 for (uint32 i = 0; i < iNumChunk; ++i)
210 {
211 iFreeMemChunkList.push_back((OsclAny*)chunkptr);
212 chunkptr += iChunkSizeMemAligned;
213 }
214 }
215
216
destroymempool()217 OSCL_EXPORT_REF void OsclMemPoolFixedChunkAllocator::destroymempool()
218 {
219 // If ref count reaches 0 then destroy this object
220 if (iRefCount <= 0)
221 {
222 #if OSCL_MEM_CHECK_ALL_MEMPOOL_CHUNKS_ARE_RETURNED
223 // Assert if all of the chunks were not returned
224 OSCL_ASSERT(iFreeMemChunkList.size() == iNumChunk);
225 #endif
226
227 iFreeMemChunkList.clear();
228
229 if (iMemPool)
230 {
231 if (iMemPoolAllocator)
232 {
233 iMemPoolAllocator->deallocate(iMemPool);
234 }
235 else
236 {
237 OSCL_FREE(iMemPool);
238 }
239
240 iMemPool = NULL;
241 }
242 }
243 }
244
245
246
247 /**
248 * OsclMemPoolResizableAllocator section
249 **/
250
251 #define OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER 10
252 #define OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN 0x55
253 #define OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN 0xAA
254 #define OSCLMEMPOOLRESIZABLEALLOCATOR_MIN_BUFFERSIZE 8
255
OsclMemPoolResizableAllocator(uint32 aMemPoolBufferSize,uint32 aMemPoolBufferNumLimit,uint32 aExpectedNumBlocksPerBuffer,Oscl_DefAlloc * gen_alloc)256 OSCL_EXPORT_REF OsclMemPoolResizableAllocator::OsclMemPoolResizableAllocator(uint32 aMemPoolBufferSize, uint32 aMemPoolBufferNumLimit, uint32 aExpectedNumBlocksPerBuffer, Oscl_DefAlloc* gen_alloc) :
257 iMemPoolBufferSize(aMemPoolBufferSize),
258 iMemPoolBufferNumLimit(aMemPoolBufferNumLimit),
259 iExpectedNumBlocksPerBuffer(aExpectedNumBlocksPerBuffer),
260 iMemPoolBufferAllocator(gen_alloc),
261 iCheckNextAvailable(false),
262 iRequestedNextAvailableSize(0),
263 iNextAvailableContextData(NULL),
264 iObserver(NULL),
265 iCheckFreeMemoryAvailable(false),
266 iRequestedAvailableFreeMemSize(0),
267 iFreeMemContextData(NULL),
268 iFreeMemPoolObserver(NULL),
269 iRefCount(1),
270 iEnableNullPtrReturn(false)
271 {
272 OSCL_ASSERT(aMemPoolBufferSize > OSCLMEMPOOLRESIZABLEALLOCATOR_MIN_BUFFERSIZE);
273
274 iMaxNewMemPoolBufferSz = 0;
275 // Calculate and save the mem aligned size of buffer and block info header structures
276 iBufferInfoAlignedSize = oscl_mem_aligned_size(sizeof(MemPoolBufferInfo));
277 iBlockInfoAlignedSize = oscl_mem_aligned_size(sizeof(MemPoolBlockInfo));
278
279 // Pre-allocate memory for vector
280 if (iMemPoolBufferNumLimit > 0)
281 {
282 iMemPoolBufferList.reserve(iMemPoolBufferNumLimit);
283 }
284 else
285 {
286 iMemPoolBufferList.reserve(2);
287 }
288
289 // Determine the size of memory pool buffer and create one
290 uint32 buffersize = oscl_mem_aligned_size(iMemPoolBufferSize) + iBufferInfoAlignedSize;
291 if (iExpectedNumBlocksPerBuffer > 0)
292 {
293 buffersize += (iExpectedNumBlocksPerBuffer * iBlockInfoAlignedSize);
294 }
295 else
296 {
297 buffersize += (OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER * iBlockInfoAlignedSize);
298 }
299
300 addnewmempoolbuffer(buffersize);
301 }
302
enablenullpointerreturn()303 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::enablenullpointerreturn()
304 {
305 iEnableNullPtrReturn = true;
306 }
307
allocate(const uint32 aNumBytes)308 OSCL_EXPORT_REF OsclAny* OsclMemPoolResizableAllocator::allocate(const uint32 aNumBytes)
309 {
310 MemPoolBlockInfo* freeblock = NULL;
311 uint32 alignednumbytes = oscl_mem_aligned_size(aNumBytes);
312
313 if (aNumBytes == 0)
314 {
315 OSCL_LEAVE(OsclErrArgument);
316 // OSCL_UNUSED_RETURN(NULL); This statement was removed to avoid compiler warning for Unreachable Code
317 }
318
319 // Find a free block that would accomodate the requested size with a block info header
320 freeblock = findfreeblock(alignednumbytes + iBlockInfoAlignedSize);
321 if (freeblock == NULL)
322 {
323 //We could not find the new buffer, the only way we can allocate the chunk is by allocating newmempool buffer
324 //Validate is size is less than the regrow size.
325 if (iMemPoolBufferNumLimit > 0 && iMaxNewMemPoolBufferSz > 0 && iMaxNewMemPoolBufferSz < alignednumbytes)
326 {
327 //cannot create the new buffer
328 if (iEnableNullPtrReturn)
329 {
330 return NULL;
331 }
332 else
333 {
334 // Leave with resource limitation
335 OSCL_LEAVE(OsclErrNoResources);
336 }
337
338 }
339 // Check if the requested size is bigger than the specified buffer size
340 if (alignednumbytes > iMemPoolBufferSize)
341 {
342 // Would need to create a new buffer to accomodate this request
343
344 // Check if another buffer can be created
345 if (iMemPoolBufferNumLimit > 0 && iMemPoolBufferList.size() >= iMemPoolBufferNumLimit)
346 {
347 // Check if there is a memory pool buffer that has no outstanding buffers
348 // If present then remove it so a new one can be added
349 bool emptybufferfound = false;
350 for (uint32 j = 0; j < iMemPoolBufferList.size(); ++j)
351 {
352 if (iMemPoolBufferList[j]->iNumOutstanding == 0)
353 {
354 // Free the memory
355 if (iMemPoolBufferAllocator)
356 {
357 iMemPoolBufferAllocator->deallocate((OsclAny*)iMemPoolBufferList[j]);
358 }
359 else
360 {
361 OSCL_FREE((OsclAny*)iMemPoolBufferList[j]);
362 }
363
364 // Remove the mempool buffer from the list
365 iMemPoolBufferList.erase(iMemPoolBufferList.begin() + j);
366 emptybufferfound = true;
367 break;
368 }
369 }
370
371 // Need to leave and return if empty buffer not found
372 if (!emptybufferfound)
373 {
374 if (iEnableNullPtrReturn)
375 {
376 return NULL;
377 }
378 else
379 {
380 // Leave with resource limitation
381 OSCL_LEAVE(OsclErrNoResources);
382 }
383 }
384
385 // Continue on to create a new buffer
386 OSCL_ASSERT(iMemPoolBufferList.size() < iMemPoolBufferNumLimit);
387 }
388
389 // Determine the size of memory pool buffer and create one
390 uint32 buffersize = alignednumbytes + iBufferInfoAlignedSize;
391 if (iExpectedNumBlocksPerBuffer > 0)
392 {
393 buffersize += (iExpectedNumBlocksPerBuffer * iBlockInfoAlignedSize);
394 }
395 else
396 {
397 buffersize += (OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER * iBlockInfoAlignedSize);
398 }
399
400 MemPoolBufferInfo* newbuffer = addnewmempoolbuffer(buffersize);
401 OSCL_ASSERT(newbuffer != NULL);
402 OSCL_ASSERT(newbuffer->iNextFreeBlock != NULL);
403 freeblock = (MemPoolBlockInfo*)(newbuffer->iNextFreeBlock);
404 OSCL_ASSERT(freeblock != NULL);
405 OSCL_ASSERT(freeblock->iBlockSize >= alignednumbytes);
406 }
407 else
408 {
409 // Check if another buffer can be created
410 if (iMemPoolBufferNumLimit > 0 && iMemPoolBufferList.size() >= iMemPoolBufferNumLimit)
411 {
412 if (iEnableNullPtrReturn)
413 {
414 return NULL;
415 }
416 else
417 {
418 // Leave with resource limitation
419 OSCL_LEAVE(OsclErrNoResources);
420 }
421 }
422
423 // Determine the size of memory pool buffer and create one
424 uint32 buffersize = oscl_mem_aligned_size(iMemPoolBufferSize) + iBufferInfoAlignedSize;
425 if (iExpectedNumBlocksPerBuffer > 0)
426 {
427 buffersize += (iExpectedNumBlocksPerBuffer * iBlockInfoAlignedSize);
428 }
429 else
430 {
431 buffersize += (OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER * iBlockInfoAlignedSize);
432 }
433
434 MemPoolBufferInfo* newbuffer = addnewmempoolbuffer(buffersize);
435 OSCL_ASSERT(newbuffer != NULL);
436 OSCL_ASSERT(newbuffer->iNextFreeBlock != NULL);
437 freeblock = (MemPoolBlockInfo*)(newbuffer->iNextFreeBlock);
438 OSCL_ASSERT(freeblock != NULL);
439 OSCL_ASSERT(freeblock->iBlockSize >= alignednumbytes);
440 }
441
442 }
443
444 // Use the free block and return the buffer pointer
445 OsclAny* bufptr = allocateblock(*freeblock, alignednumbytes);
446 if (bufptr)
447 {
448 addRef();
449 ++(freeblock->iParentBuffer->iNumOutstanding);
450 }
451 return bufptr;
452 }
453
454
deallocate(OsclAny * aPtr)455 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::deallocate(OsclAny* aPtr)
456 {
457 // Check that the returned pointer is from the memory pool
458 if (validateblock(aPtr) == false)
459 {
460 OSCL_LEAVE(OsclErrArgument);
461 }
462
463 // Retrieve the block info header and validate the info
464 uint8* byteptr = (uint8*)aPtr;
465 MemPoolBlockInfo* retblock = (MemPoolBlockInfo*)(byteptr - iBlockInfoAlignedSize);
466 OSCL_ASSERT(retblock != NULL);
467 OSCL_ASSERT(retblock->iBlockPreFence == OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN);
468 OSCL_ASSERT(retblock->iBlockPostFence == OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN);
469
470 // Return the block to the memory pool buffer
471 deallocateblock(*retblock);
472 --(retblock->iParentBuffer->iNumOutstanding);
473
474 // Check if user needs to be notified when block becomes available
475 if (iCheckNextAvailable)
476 {
477 // Check if user is waiting for certain size
478 if (iRequestedNextAvailableSize == 0)
479 {
480 // No so just make the callback
481 iCheckNextAvailable = false;
482 if (iObserver)
483 {
484 iObserver->freeblockavailable(iNextAvailableContextData);
485 }
486 }
487 else
488 {
489 // Check if the requested size is available now
490 if (findfreeblock(iRequestedNextAvailableSize + iBlockInfoAlignedSize) != NULL)
491 {
492 iCheckNextAvailable = false;
493 if (iObserver)
494 {
495 iObserver->freeblockavailable(iNextAvailableContextData);
496 }
497 }
498 else if (iRequestedNextAvailableSize > iMemPoolBufferSize)
499 {
500 // The requested size is bigger than the set buffer size
501
502 // Check if there is space to grow the buffer,
503 if (iMemPoolBufferNumLimit == 0 || iMemPoolBufferList.size() < iMemPoolBufferNumLimit)
504 {
505 // Available
506 iCheckNextAvailable = false;
507 if (iObserver)
508 {
509 iObserver->freeblockavailable(iNextAvailableContextData);
510 }
511 }
512 else
513 {
514 // Not available so see if there is a buffer with
515 // no outstanding buffers which can be destroyed
516 // in the next allocate() call.
517 bool emptybufferfound = false;
518 for (uint32 j = 0; j < iMemPoolBufferList.size(); ++j)
519 {
520 if (iMemPoolBufferList[j]->iNumOutstanding == 0)
521 {
522 emptybufferfound = true;
523 break;
524 }
525 }
526
527 if (emptybufferfound)
528 {
529 iCheckNextAvailable = false;
530 if (iObserver)
531 {
532 iObserver->freeblockavailable(iNextAvailableContextData);
533 }
534 }
535 }
536 }
537 }
538 }
539 if (iCheckFreeMemoryAvailable)
540 {
541 if (iRequestedAvailableFreeMemSize == 0)
542 {
543 // No so just make the callback
544 iCheckFreeMemoryAvailable = false;
545 if (iFreeMemPoolObserver)
546 {
547 iFreeMemPoolObserver->freememoryavailable(iFreeMemContextData);
548 }
549 }
550 else
551 {
552 // Check if the requested size is available now
553 if (getAvailableSize() >= iRequestedAvailableFreeMemSize)
554 {
555 iCheckFreeMemoryAvailable = false;
556 if (iFreeMemPoolObserver)
557 {
558 iFreeMemPoolObserver->freememoryavailable(iFreeMemContextData);
559 }
560 }
561 }
562 }
563
564 // Decrement the refcount since deallocating succeeded
565 removeRef();
566 }
567
568
trim(OsclAny * aPtr,uint32 aBytesToFree)569 OSCL_EXPORT_REF bool OsclMemPoolResizableAllocator::trim(OsclAny* aPtr, uint32 aBytesToFree)
570 {
571 // Amount to free has to be aligned
572 uint32 alignedbytestofree = oscl_mem_aligned_size(aBytesToFree);
573 if (alignedbytestofree > aBytesToFree)
574 {
575 // Not aligned so decrease amount to free by one alignment size
576 alignedbytestofree -= 8;
577 }
578 OSCL_ASSERT(alignedbytestofree <= aBytesToFree);
579
580 // Check that the returned pointer is from the memory pool
581 if (validateblock(aPtr) == false)
582 {
583 OSCL_LEAVE(OsclErrArgument);
584 // OSCL_UNUSED_RETURN(false); This statement was removed to avoid compiler warning for Unreachable Code
585 }
586
587 // Retrieve the block info header and validate the info
588 uint8* byteptr = (uint8*)aPtr;
589 MemPoolBlockInfo* resizeblock = (MemPoolBlockInfo*)(byteptr - iBlockInfoAlignedSize);
590 OSCL_ASSERT(resizeblock != NULL);
591 OSCL_ASSERT(resizeblock->iBlockPreFence == OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN);
592 OSCL_ASSERT(resizeblock->iBlockPostFence == OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN);
593
594 if ((resizeblock->iBlockSize - iBlockInfoAlignedSize) < alignedbytestofree)
595 {
596 // The bytes to free in the resize is bigger than the original buffer size
597 OSCL_LEAVE(OsclErrArgument);
598 // OSCL_UNUSED_RETURN(false); This statement was removed to avoid compiler warning for Unreachable Code
599 }
600
601 if (alignedbytestofree < (iBlockInfoAlignedSize + OSCLMEMPOOLRESIZABLEALLOCATOR_MIN_BUFFERSIZE))
602 {
603 // The resizing cannot be done since the amount to free doesn't have
604 // enough space to put in a block info header plus the minimum buffer for the new free block
605 // So don't do anything and return
606 return false;
607 }
608
609 // Create and fill in a block info header for the memory being freed back to memory pool
610 MemPoolBlockInfo* freeblock = (MemPoolBlockInfo*)((uint8*)resizeblock + resizeblock->iBlockSize - alignedbytestofree);
611 freeblock->iBlockPreFence = OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN;
612 freeblock->iNextFreeBlock = NULL;
613 freeblock->iPrevFreeBlock = NULL;
614 freeblock->iBlockSize = alignedbytestofree;
615 freeblock->iBlockBuffer = (uint8*)freeblock + iBlockInfoAlignedSize;
616 freeblock->iParentBuffer = resizeblock->iParentBuffer;
617 freeblock->iBlockPostFence = OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN;
618
619 // Return the free block to the memory pool buffer
620 deallocateblock(*freeblock);
621
622 // Adjust the block info for the block being resized
623 resizeblock->iBlockSize -= alignedbytestofree;
624 return true;
625 }
626
627
notifyfreeblockavailable(OsclMemPoolResizableAllocatorObserver & aObserver,uint32 aRequestedSize,OsclAny * aContextData)628 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::notifyfreeblockavailable(OsclMemPoolResizableAllocatorObserver& aObserver, uint32 aRequestedSize, OsclAny* aContextData)
629 {
630 // Save the parameters for the next deallocate() call
631 iCheckNextAvailable = true;
632 iObserver = &aObserver;
633 iRequestedNextAvailableSize = oscl_mem_aligned_size(aRequestedSize);
634 iNextAvailableContextData = aContextData;
635 }
636
CancelFreeChunkAvailableCallback()637 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::CancelFreeChunkAvailableCallback()
638 {
639 iCheckNextAvailable = false;
640 iObserver = NULL;
641 iRequestedNextAvailableSize = 0;
642 iNextAvailableContextData = NULL;
643 }
644
notifyfreememoryavailable(OsclMemPoolResizableAllocatorMemoryObserver & aObserver,uint32 aRequestedSize,OsclAny * aContextData)645 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::notifyfreememoryavailable(OsclMemPoolResizableAllocatorMemoryObserver& aObserver, uint32 aRequestedSize, OsclAny* aContextData)
646 {
647 // Save the parameters for the next deallocate() call
648 iCheckFreeMemoryAvailable = true;
649 iFreeMemPoolObserver = &aObserver;
650 iRequestedAvailableFreeMemSize = oscl_mem_aligned_size(aRequestedSize);
651 iFreeMemContextData = aContextData;
652 }
653
CancelFreeMemoryAvailableCallback()654 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::CancelFreeMemoryAvailableCallback()
655 {
656 iCheckFreeMemoryAvailable = false;
657 iFreeMemPoolObserver = NULL;
658 iRequestedAvailableFreeMemSize = 0;
659 iFreeMemContextData = NULL;
660 }
661
addRef()662 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::addRef()
663 {
664 // Just increment the ref count
665 ++iRefCount;
666 }
667
668
removeRef()669 OSCL_EXPORT_REF void OsclMemPoolResizableAllocator::removeRef()
670 {
671 // Decrement the ref count
672 --iRefCount;
673
674 // If ref count reaches 0 then destroy this object automatically
675 if (iRefCount <= 0)
676 {
677 OSCL_DELETE(this);
678 }
679 }
680
681
~OsclMemPoolResizableAllocator()682 OSCL_EXPORT_REF OsclMemPoolResizableAllocator::~OsclMemPoolResizableAllocator()
683 {
684 destroyallmempoolbuffers();
685 }
686
687
addnewmempoolbuffer(uint32 aBufferAlignedSize)688 OsclMemPoolResizableAllocator::MemPoolBufferInfo* OsclMemPoolResizableAllocator::addnewmempoolbuffer(uint32 aBufferAlignedSize)
689 {
690 OSCL_ASSERT(aBufferAlignedSize > 0);
691 OSCL_ASSERT(aBufferAlignedSize == oscl_mem_aligned_size(aBufferAlignedSize));
692
693 // Allocate memory for one buffer
694 uint8* newbuffer = NULL;
695 if (iMemPoolBufferAllocator)
696 {
697 // Use the outside allocator
698 newbuffer = (uint8*)iMemPoolBufferAllocator->ALLOCATE(aBufferAlignedSize);
699 }
700 else
701 {
702 // Allocate directly from heap
703 newbuffer = (uint8*)OSCL_MALLOC(aBufferAlignedSize);
704 }
705
706 if (newbuffer == NULL)
707 {
708 OSCL_LEAVE(OsclErrNoMemory);
709 // OSCL_UNUSED_RETURN(NULL); This statement was removed to avoid compiler warning for Unreachable Code
710 }
711
712 #if OSCL_MEM_FILL_WITH_PATTERN
713 oscl_memset(newbuffer, 0x55, aBufferAlignedSize);
714 #endif
715
716 // Fill in the buffer info header
717 MemPoolBufferInfo* newbufferinfo = (MemPoolBufferInfo*)newbuffer;
718 newbufferinfo->iBufferPreFence = OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN;
719 newbufferinfo->iStartAddr = (OsclAny*)(newbuffer + iBufferInfoAlignedSize);
720 newbufferinfo->iEndAddr = (OsclAny*)(newbuffer + aBufferAlignedSize - 1);
721 newbufferinfo->iBufferSize = aBufferAlignedSize;
722 newbufferinfo->iNumOutstanding = 0;
723 newbufferinfo->iNextFreeBlock = (MemPoolBlockInfo*)(newbufferinfo->iStartAddr);
724 newbufferinfo->iAllocatedSz = 0;
725 newbufferinfo->iBufferPostFence = OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN;
726
727 // Put in one free block in the new buffer
728 MemPoolBlockInfo* freeblockinfo = (MemPoolBlockInfo*)(newbufferinfo->iStartAddr);
729 freeblockinfo->iBlockPreFence = OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN;
730 freeblockinfo->iNextFreeBlock = NULL;
731 freeblockinfo->iPrevFreeBlock = NULL;
732 freeblockinfo->iBlockSize = aBufferAlignedSize - iBufferInfoAlignedSize;
733 freeblockinfo->iBlockBuffer = (uint8*)freeblockinfo + iBlockInfoAlignedSize;
734 freeblockinfo->iParentBuffer = newbufferinfo;
735 freeblockinfo->iBlockPostFence = OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN;
736
737 // Add the new buffer to the list
738 iMemPoolBufferList.push_front(newbufferinfo);
739
740 return newbufferinfo;
741 }
742
743
destroyallmempoolbuffers()744 void OsclMemPoolResizableAllocator::destroyallmempoolbuffers()
745 {
746 while (iMemPoolBufferList.empty() == false)
747 {
748 MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[0];
749 // Check the buffer
750 OSCL_ASSERT(bufferinfo != NULL);
751 OSCL_ASSERT(bufferinfo->iBufferPreFence == OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN);
752 OSCL_ASSERT(bufferinfo->iBufferPostFence == OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN);
753 OSCL_ASSERT(bufferinfo->iNumOutstanding == 0);
754
755 // Free the memory
756 if (iMemPoolBufferAllocator)
757 {
758 iMemPoolBufferAllocator->deallocate((OsclAny*)bufferinfo);
759 }
760 else
761 {
762 OSCL_FREE((OsclAny*)bufferinfo);
763 }
764
765 iMemPoolBufferList.erase(iMemPoolBufferList.begin());
766 }
767 }
768
769
findfreeblock(uint32 aBlockAlignedSize)770 OsclMemPoolResizableAllocator::MemPoolBlockInfo* OsclMemPoolResizableAllocator::findfreeblock(uint32 aBlockAlignedSize)
771 {
772 OSCL_ASSERT(aBlockAlignedSize > 0);
773 OSCL_ASSERT(aBlockAlignedSize == oscl_mem_aligned_size(aBlockAlignedSize));
774
775 // Go through each mempool buffer and return the first free block that
776 // is bigger than the specified size
777
778 if (aBlockAlignedSize == 0)
779 {
780 // Request should be non-zero
781 OSCL_LEAVE(OsclErrArgument);
782 // OSCL_UNUSED_RETURN(NULL); This statement was removed to avoid compiler warning for Unreachable Code
783 }
784
785 for (uint32 i = 0; i < iMemPoolBufferList.size(); ++i)
786 {
787 MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
788 MemPoolBlockInfo* blockinfo = bufferinfo->iNextFreeBlock;
789 while (blockinfo != NULL)
790 {
791 if ((blockinfo->iBlockSize/* - iBlockInfoAlignedSize*/) >= aBlockAlignedSize)
792 {
793 // This free block fits the request
794 return blockinfo;
795 }
796
797 // Go to the next free block
798 blockinfo = blockinfo->iNextFreeBlock;
799 }
800 }
801
802 return NULL;
803 }
804
805
allocateblock(MemPoolBlockInfo & aBlockPtr,uint32 aNumAlignedBytes)806 OsclAny* OsclMemPoolResizableAllocator::allocateblock(MemPoolBlockInfo& aBlockPtr, uint32 aNumAlignedBytes)
807 {
808 OSCL_ASSERT(aNumAlignedBytes > 0);
809 OSCL_ASSERT(aNumAlignedBytes == oscl_mem_aligned_size(aNumAlignedBytes));
810
811 if (aNumAlignedBytes == 0)
812 {
813 OSCL_LEAVE(OsclErrArgument);
814 // OSCL_UNUSED_RETURN(NULL); This statement was removed to avoid compiler warning for Unreachable Code
815 }
816
817 // Remove the free block from the double linked list
818 if (aBlockPtr.iPrevFreeBlock == NULL && aBlockPtr.iNextFreeBlock != NULL)
819 {
820 // Removing from the beginning of the free list
821 aBlockPtr.iNextFreeBlock->iPrevFreeBlock = NULL;
822 aBlockPtr.iParentBuffer->iNextFreeBlock = aBlockPtr.iNextFreeBlock;
823 }
824 else if (aBlockPtr.iPrevFreeBlock != NULL && aBlockPtr.iNextFreeBlock == NULL)
825 {
826 // Removing from the end of the free list
827 aBlockPtr.iPrevFreeBlock->iNextFreeBlock = NULL;
828 }
829 else if (aBlockPtr.iPrevFreeBlock == NULL && aBlockPtr.iNextFreeBlock == NULL)
830 {
831 // Free list becomes empty so update the parent buffer's link
832 aBlockPtr.iParentBuffer->iNextFreeBlock = NULL;
833 }
834 else
835 {
836 // Removing from middle of the free list
837 aBlockPtr.iPrevFreeBlock->iNextFreeBlock = aBlockPtr.iNextFreeBlock;
838 aBlockPtr.iNextFreeBlock->iPrevFreeBlock = aBlockPtr.iPrevFreeBlock;
839 }
840
841 aBlockPtr.iNextFreeBlock = NULL;
842 aBlockPtr.iPrevFreeBlock = NULL;
843
844 aBlockPtr.iParentBuffer->iAllocatedSz += aBlockPtr.iBlockSize;
845
846 // Resize the block if too large
847 uint32 extraspace = aBlockPtr.iBlockSize - iBlockInfoAlignedSize - aNumAlignedBytes;
848 if (extraspace > (iBlockInfoAlignedSize + OSCLMEMPOOLRESIZABLEALLOCATOR_MIN_BUFFERSIZE))
849 {
850 trim(aBlockPtr.iBlockBuffer, extraspace);
851 }
852
853 #if OSCL_MEM_FILL_WITH_PATTERN
854 oscl_memset(aBlockPtr.iBlockBuffer, 0x55, (aBlockPtr.iBlockSize - iBlockInfoAlignedSize));
855 #endif
856 return aBlockPtr.iBlockBuffer;
857 }
858
859
deallocateblock(MemPoolBlockInfo & aBlockPtr)860 void OsclMemPoolResizableAllocator::deallocateblock(MemPoolBlockInfo& aBlockPtr)
861 {
862 OSCL_ASSERT(aBlockPtr.iParentBuffer);
863
864 MemPoolBufferInfo* bufferinfo = aBlockPtr.iParentBuffer;
865 MemPoolBlockInfo* rightblockinfo = bufferinfo->iNextFreeBlock;
866 MemPoolBlockInfo* leftblockinfo = NULL;
867
868 // Go through the free block list and find the free block which would
869 // become the right neighbor of the block being freed
870 while (rightblockinfo != NULL)
871 {
872 if (&aBlockPtr < rightblockinfo)
873 {
874 break;
875 }
876 leftblockinfo = rightblockinfo;
877 rightblockinfo = rightblockinfo->iNextFreeBlock;
878 }
879
880 // Check where the newly freed block is in the list
881 if (leftblockinfo == NULL && rightblockinfo == NULL)
882 {
883 // The free block list is empty.
884 // Trivial case so add to list and return to list without merge
885 bufferinfo->iNextFreeBlock = &aBlockPtr;
886 aBlockPtr.iNextFreeBlock = NULL;
887 aBlockPtr.iPrevFreeBlock = NULL;
888 aBlockPtr.iParentBuffer->iAllocatedSz -= aBlockPtr.iBlockSize;
889 return;
890 }
891 else if (leftblockinfo != NULL && rightblockinfo == NULL)
892 {
893 // Adding to the end of the list
894 OSCL_ASSERT(leftblockinfo->iNextFreeBlock == NULL);
895
896 // Check that the newly freed block doesn't overlap with an existing free block
897 if (((uint8*)leftblockinfo + leftblockinfo->iBlockSize) > (uint8*)&aBlockPtr)
898 {
899 OSCL_LEAVE(OsclErrArgument);
900 }
901
902 leftblockinfo->iNextFreeBlock = &aBlockPtr;
903 aBlockPtr.iPrevFreeBlock = leftblockinfo;
904 aBlockPtr.iNextFreeBlock = NULL;
905 }
906 else if (leftblockinfo == NULL && rightblockinfo != NULL)
907 {
908 // Adding to the beginning of the list
909 OSCL_ASSERT(rightblockinfo->iPrevFreeBlock == NULL);
910
911 // Check that the newly freed block doesn't overlap with an existing free block
912 if (((uint8*)&aBlockPtr + aBlockPtr.iBlockSize) > (uint8*)rightblockinfo)
913 {
914 OSCL_LEAVE(OsclErrArgument);
915 }
916
917 bufferinfo->iNextFreeBlock = &aBlockPtr;
918 rightblockinfo->iPrevFreeBlock = &aBlockPtr;
919 aBlockPtr.iPrevFreeBlock = NULL;
920 aBlockPtr.iNextFreeBlock = rightblockinfo;
921 }
922 else
923 {
924 // Adding to the middle of the list
925 OSCL_ASSERT(leftblockinfo->iNextFreeBlock == rightblockinfo);
926 OSCL_ASSERT(rightblockinfo->iPrevFreeBlock == leftblockinfo);
927
928 // Check that the newly freed block doesn't overlap with the existing free blocks
929 if (((uint8*)&aBlockPtr + aBlockPtr.iBlockSize) > (uint8*)rightblockinfo ||
930 ((uint8*)leftblockinfo + leftblockinfo->iBlockSize) > (uint8*)&aBlockPtr)
931 {
932 OSCL_LEAVE(OsclErrArgument);
933 }
934
935 leftblockinfo->iNextFreeBlock = &aBlockPtr;
936 rightblockinfo->iPrevFreeBlock = &aBlockPtr;
937 aBlockPtr.iPrevFreeBlock = leftblockinfo;
938 aBlockPtr.iNextFreeBlock = rightblockinfo;
939 }
940 aBlockPtr.iParentBuffer->iAllocatedSz -= aBlockPtr.iBlockSize;
941
942 // Merge the newly freed block with neighbors if contiguous
943 // Check which neighbors are contiguous in memory space
944 bool rightadj = false;
945 bool leftadj = false;
946 if (aBlockPtr.iPrevFreeBlock)
947 {
948 MemPoolBlockInfo* leftnb = aBlockPtr.iPrevFreeBlock;
949 if (((uint8*)leftnb + leftnb->iBlockSize) == (uint8*)&aBlockPtr)
950 {
951 leftadj = true;
952 }
953 }
954 if (aBlockPtr.iNextFreeBlock)
955 {
956 MemPoolBlockInfo* rightnb = aBlockPtr.iNextFreeBlock;
957 if (((uint8*)&aBlockPtr + aBlockPtr.iBlockSize) == (uint8*)rightnb)
958 {
959 rightadj = true;
960 }
961 }
962
963 // Do the merge based on the check
964 if (leftadj == false && rightadj == true)
965 {
966 // Merge the right neighbor with the newly freed block
967 // Update newly freed block's size and remove the right neighbor from the list
968 MemPoolBlockInfo* midblock = &aBlockPtr;
969 MemPoolBlockInfo* rightblock = aBlockPtr.iNextFreeBlock;
970 // Size update
971 midblock->iBlockSize += rightblock->iBlockSize;
972 // Right neighbor removal
973 if (rightblock->iNextFreeBlock)
974 {
975 rightblock->iNextFreeBlock->iPrevFreeBlock = midblock;
976 }
977 midblock->iNextFreeBlock = rightblock->iNextFreeBlock;
978 }
979 else if (leftadj == true && rightadj == false)
980 {
981 // Merge the newly freed block with the left neighbor
982 // Update the left neighbor's block size to include the newly freed block and
983 // remove the newly freed block from the list
984 MemPoolBlockInfo* midblock = &aBlockPtr;
985 MemPoolBlockInfo* leftblock = aBlockPtr.iPrevFreeBlock;
986 // Size update
987 leftblock->iBlockSize += midblock->iBlockSize;
988 // Newly freed block removal
989 if (midblock->iNextFreeBlock)
990 {
991 midblock->iNextFreeBlock->iPrevFreeBlock = leftblock;
992 }
993 leftblock->iNextFreeBlock = midblock->iNextFreeBlock;
994 }
995 else if (leftadj == true && rightadj == true)
996 {
997 // Merge the newly freed block and right neighbor with the left neighbor
998 // and remove the newly freed block and right neighbor from the list
999 MemPoolBlockInfo* midblock = &aBlockPtr;
1000 MemPoolBlockInfo* leftblock = aBlockPtr.iPrevFreeBlock;
1001 MemPoolBlockInfo* rightblock = aBlockPtr.iNextFreeBlock;
1002 // Size update
1003 leftblock->iBlockSize += (midblock->iBlockSize + rightblock->iBlockSize);
1004 // Newly freed and right neighbor block removal
1005 if (rightblock->iNextFreeBlock)
1006 {
1007 rightblock->iNextFreeBlock->iPrevFreeBlock = leftblock;
1008 }
1009 leftblock->iNextFreeBlock = rightblock->iNextFreeBlock;
1010 }
1011 }
1012
1013
validateblock(OsclAny * aBlockBufPtr)1014 bool OsclMemPoolResizableAllocator::validateblock(OsclAny* aBlockBufPtr)
1015 {
1016 uint32 i = 0;
1017
1018 if (aBlockBufPtr == NULL)
1019 {
1020 // Invalid pointer
1021 return false;
1022 }
1023
1024 // Check if the pointer falls within one of the memory pool buffer's memory address
1025 for (i = 0; i < iMemPoolBufferList.size(); ++i)
1026 {
1027 MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
1028 if (aBlockBufPtr > bufferinfo->iStartAddr && aBlockBufPtr < bufferinfo->iEndAddr)
1029 {
1030 break;
1031 }
1032 }
1033 if (i >= iMemPoolBufferList.size())
1034 {
1035 // Parent buffer is not part of this memory pool instance
1036 return false;
1037 }
1038
1039 // Retrieve the block info header
1040 MemPoolBlockInfo* chkblock = (MemPoolBlockInfo*)((uint8*)aBlockBufPtr - iBlockInfoAlignedSize);
1041
1042 if (chkblock->iBlockPreFence != OSCLMEMPOOLRESIZABLEALLOCATOR_PREFENCE_PATTERN ||
1043 chkblock->iBlockPostFence != OSCLMEMPOOLRESIZABLEALLOCATOR_POSTFENCE_PATTERN)
1044 {
1045 // Memory fence checking failed
1046 return false;
1047 }
1048
1049 // Check the parent buffer is one in the list
1050 MemPoolBufferInfo* parentbuffer = chkblock->iParentBuffer;
1051 if (parentbuffer == NULL)
1052 {
1053 return false;
1054 }
1055 for (i = 0; i < iMemPoolBufferList.size(); ++i)
1056 {
1057 if (parentbuffer == iMemPoolBufferList[i])
1058 {
1059 break;
1060 }
1061 }
1062 if (i >= iMemPoolBufferList.size())
1063 {
1064 // Parent buffer is not part of this memory pool instance
1065 return false;
1066 }
1067
1068 if (aBlockBufPtr < parentbuffer->iStartAddr || aBlockBufPtr > parentbuffer->iEndAddr)
1069 {
1070 // The address of the buffer is not part of the parent buffer
1071 return false;
1072 }
1073
1074 if ((OsclAny*)((uint8*)chkblock + chkblock->iBlockSize - 1) > (parentbuffer->iEndAddr))
1075 {
1076 // The block size is too big
1077 return false;
1078 }
1079
1080 return true;
1081 }
1082
1083
getBufferSize() const1084 OSCL_EXPORT_REF uint32 OsclMemPoolResizableAllocator::getBufferSize() const
1085 {
1086 if (iMemPoolBufferNumLimit == 0)
1087 OSCL_LEAVE(OsclErrNotSupported);
1088
1089 uint32 bufferSize = 0;
1090 for (uint32 i = 0; i < iMemPoolBufferList.size(); ++i)
1091 {
1092 MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
1093 bufferSize += getMemPoolBufferSize(bufferinfo);
1094 }
1095
1096 return bufferSize;
1097 }
1098
getAllocatedSize() const1099 OSCL_EXPORT_REF uint32 OsclMemPoolResizableAllocator::getAllocatedSize() const
1100 {
1101 //const uint32 expectedNumBlocksPerBuffer = iExpectedNumBlocksPerBuffer > 0 ? iExpectedNumBlocksPerBuffer : OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER;
1102 uint32 allocatedSz = 0;
1103 for (uint32 i = 0; i < iMemPoolBufferList.size(); ++i)
1104 {
1105 MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
1106 allocatedSz += getMemPoolBufferAllocatedSize(bufferinfo);
1107 }
1108 return allocatedSz;
1109 }
1110
getAvailableSize() const1111 OSCL_EXPORT_REF uint32 OsclMemPoolResizableAllocator::getAvailableSize() const
1112 {
1113 if (iMemPoolBufferNumLimit == 0)
1114 OSCL_LEAVE(OsclErrNotSupported);
1115
1116 uint32 availableSize = 0;
1117 for (uint32 i = 0; i < iMemPoolBufferList.size(); ++i)
1118 {
1119 MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
1120 uint32 memPoolBufferAvailableSz = 0;
1121 memPoolBufferAvailableSz = (getMemPoolBufferSize(bufferinfo) - getMemPoolBufferAllocatedSize(bufferinfo));
1122 availableSize += memPoolBufferAvailableSz;
1123 }
1124
1125 return availableSize;
1126 }
1127
getLargestContiguousFreeBlockSize() const1128 OSCL_EXPORT_REF uint32 OsclMemPoolResizableAllocator::getLargestContiguousFreeBlockSize() const
1129 {
1130 uint32 blockSz = 0;
1131
1132 if (iMemPoolBufferNumLimit > 0)
1133 {
1134 for (uint32 i = 0; i < iMemPoolBufferList.size(); ++i)
1135 {
1136 MemPoolBufferInfo* bufferinfo = iMemPoolBufferList[i];
1137 if (bufferinfo)
1138 {
1139 MemPoolBlockInfo* blockinfo = bufferinfo->iNextFreeBlock;
1140 while (blockinfo != NULL)
1141 {
1142 if (blockinfo->iBlockSize > blockSz) blockSz = blockinfo->iBlockSize;
1143 blockinfo = blockinfo->iNextFreeBlock;
1144 }
1145 }
1146 }
1147 }
1148 else
1149 OSCL_LEAVE(OsclErrNotSupported);
1150
1151 if (blockSz > iBlockInfoAlignedSize) blockSz -= iBlockInfoAlignedSize;
1152 else blockSz = 0;
1153
1154 return blockSz;
1155 }
1156
setMaxSzForNewMemPoolBuffer(uint32 aMaxNewMemPoolBufferSz)1157 OSCL_EXPORT_REF bool OsclMemPoolResizableAllocator::setMaxSzForNewMemPoolBuffer(uint32 aMaxNewMemPoolBufferSz)
1158 {
1159 bool retval = true;
1160 if (iMemPoolBufferNumLimit > 0)
1161 iMaxNewMemPoolBufferSz = aMaxNewMemPoolBufferSz;
1162 else
1163 retval = false;
1164 return retval;
1165 }
1166
getMemPoolBufferSize(MemPoolBufferInfo * aBufferInfo) const1167 uint32 OsclMemPoolResizableAllocator::getMemPoolBufferSize(MemPoolBufferInfo* aBufferInfo) const
1168 {
1169 uint32 memPoolBufferSz = 0;
1170
1171 if (aBufferInfo)
1172 memPoolBufferSz = aBufferInfo->iBufferSize;
1173
1174 return memPoolBufferSz;
1175 }
1176
getMemPoolBufferAllocatedSize(MemPoolBufferInfo * aBufferInfo) const1177 uint32 OsclMemPoolResizableAllocator::getMemPoolBufferAllocatedSize(MemPoolBufferInfo* aBufferInfo) const
1178 {
1179 return aBufferInfo->iAllocatedSz;
1180 /*
1181 uint32 allocatedSz = 0;
1182 const uint32 expectedNumBlocksPerBuffer = iExpectedNumBlocksPerBuffer > 0 ? iExpectedNumBlocksPerBuffer : OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER;
1183
1184 if (aBufferInfo)
1185 {
1186 if (aBufferInfo->iNumOutstanding > expectedNumBlocksPerBuffer)
1187 {
1188 allocatedSz = (aBufferInfo->iAllocatedSz - (expectedNumBlocksPerBuffer * iBlockInfoAlignedSize));
1189 }
1190 else
1191 {
1192 allocatedSz = (aBufferInfo->iAllocatedSz - (aBufferInfo->iNumOutstanding * iBlockInfoAlignedSize));
1193 }
1194 }
1195 return allocatedSz;
1196 */
1197 }
1198
memoryPoolBufferMgmtOverhead() const1199 uint32 OsclMemPoolResizableAllocator::memoryPoolBufferMgmtOverhead() const
1200 {
1201 uint32 overheadBytes = iBufferInfoAlignedSize;
1202 if (iExpectedNumBlocksPerBuffer > 0)
1203 {
1204 overheadBytes += (iExpectedNumBlocksPerBuffer * iBlockInfoAlignedSize);
1205 }
1206 else
1207 {
1208 overheadBytes += (OSCLMEMPOOLRESIZABLEALLOCATOR_DEFAULT_NUMBLOCKPERBUFFER * iBlockInfoAlignedSize);
1209 }
1210 return overheadBytes;
1211 }
1212