Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #ifndef WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_MEMORY_POOL_GENERIC_H_
     12 #define WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_MEMORY_POOL_GENERIC_H_
     13 
     14 #include <assert.h>
     15 #include <list>
     16 
     17 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
     18 #include "webrtc/typedefs.h"
     19 
     20 namespace webrtc {
     21 template<class MemoryType>
     22 class MemoryPoolImpl
     23 {
     24 public:
     25     // MemoryPool functions.
     26     int32_t PopMemory(MemoryType*&  memory);
     27     int32_t PushMemory(MemoryType*& memory);
     28 
     29     MemoryPoolImpl(int32_t initialPoolSize);
     30     ~MemoryPoolImpl();
     31 
     32     // Atomic functions
     33     int32_t Terminate();
     34     bool Initialize();
     35 private:
     36     // Non-atomic function.
     37     int32_t CreateMemory(uint32_t amountToCreate);
     38 
     39     CriticalSectionWrapper* _crit;
     40 
     41     bool _terminate;
     42 
     43     std::list<MemoryType*> _memoryPool;
     44 
     45     uint32_t _initialPoolSize;
     46     uint32_t _createdMemory;
     47     uint32_t _outstandingMemory;
     48 };
     49 
     50 template<class MemoryType>
     51 MemoryPoolImpl<MemoryType>::MemoryPoolImpl(int32_t initialPoolSize)
     52     : _crit(CriticalSectionWrapper::CreateCriticalSection()),
     53       _terminate(false),
     54       _initialPoolSize(initialPoolSize),
     55       _createdMemory(0),
     56       _outstandingMemory(0)
     57 {
     58 }
     59 
     60 template<class MemoryType>
     61 MemoryPoolImpl<MemoryType>::~MemoryPoolImpl()
     62 {
     63     // Trigger assert if there is outstanding memory.
     64     assert(_createdMemory == 0);
     65     assert(_outstandingMemory == 0);
     66     delete _crit;
     67 }
     68 
     69 template<class MemoryType>
     70 int32_t MemoryPoolImpl<MemoryType>::PopMemory(MemoryType*& memory)
     71 {
     72     CriticalSectionScoped cs(_crit);
     73     if(_terminate)
     74     {
     75         memory = NULL;
     76         return -1;
     77     }
     78     if (_memoryPool.empty()) {
     79         // _memoryPool empty create new memory.
     80         CreateMemory(_initialPoolSize);
     81         if(_memoryPool.empty())
     82         {
     83             memory = NULL;
     84             return -1;
     85         }
     86     }
     87     memory = _memoryPool.front();
     88     _memoryPool.pop_front();
     89     _outstandingMemory++;
     90     return 0;
     91 }
     92 
     93 template<class MemoryType>
     94 int32_t MemoryPoolImpl<MemoryType>::PushMemory(MemoryType*& memory)
     95 {
     96     if(memory == NULL)
     97     {
     98         return -1;
     99     }
    100     CriticalSectionScoped cs(_crit);
    101     _outstandingMemory--;
    102     if(_memoryPool.size() > (_initialPoolSize << 1))
    103     {
    104         // Reclaim memory if less than half of the pool is unused.
    105         _createdMemory--;
    106         delete memory;
    107         memory = NULL;
    108         return 0;
    109     }
    110     _memoryPool.push_back(memory);
    111     memory = NULL;
    112     return 0;
    113 }
    114 
    115 template<class MemoryType>
    116 bool MemoryPoolImpl<MemoryType>::Initialize()
    117 {
    118     CriticalSectionScoped cs(_crit);
    119     return CreateMemory(_initialPoolSize) == 0;
    120 }
    121 
    122 template<class MemoryType>
    123 int32_t MemoryPoolImpl<MemoryType>::Terminate()
    124 {
    125     CriticalSectionScoped cs(_crit);
    126     assert(_createdMemory == _outstandingMemory + _memoryPool.size());
    127 
    128     _terminate = true;
    129     // Reclaim all memory.
    130     while(_createdMemory > 0)
    131     {
    132         MemoryType* memory = _memoryPool.front();
    133         _memoryPool.pop_front();
    134         delete memory;
    135         _createdMemory--;
    136     }
    137     return 0;
    138 }
    139 
    140 template<class MemoryType>
    141 int32_t MemoryPoolImpl<MemoryType>::CreateMemory(
    142     uint32_t amountToCreate)
    143 {
    144     for(uint32_t i = 0; i < amountToCreate; i++)
    145     {
    146         MemoryType* memory = new MemoryType();
    147         if(memory == NULL)
    148         {
    149             return -1;
    150         }
    151         _memoryPool.push_back(memory);
    152         _createdMemory++;
    153     }
    154     return 0;
    155 }
    156 }  // namespace webrtc
    157 
    158 #endif // WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_MEMORY_POOL_GENERIC_H_
    159