• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
MemoryPoolImpl(int32_t initialPoolSize)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>
~MemoryPoolImpl()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>
PopMemory(MemoryType * & memory)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>
PushMemory(MemoryType * & memory)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>
Initialize()116 bool MemoryPoolImpl<MemoryType>::Initialize()
117 {
118     CriticalSectionScoped cs(_crit);
119     return CreateMemory(_initialPoolSize) == 0;
120 }
121 
122 template<class MemoryType>
Terminate()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>
CreateMemory(uint32_t amountToCreate)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