Line data Source code
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 0 : MemoryPoolImpl<MemoryType>::MemoryPoolImpl(int32_t initialPoolSize)
52 0 : : _crit(CriticalSectionWrapper::CreateCriticalSection()),
53 : _terminate(false),
54 : _initialPoolSize(initialPoolSize),
55 : _createdMemory(0),
56 0 : _outstandingMemory(0)
57 : {
58 0 : }
59 :
60 : template<class MemoryType>
61 0 : MemoryPoolImpl<MemoryType>::~MemoryPoolImpl()
62 : {
63 : // Trigger assert if there is outstanding memory.
64 0 : assert(_createdMemory == 0);
65 0 : assert(_outstandingMemory == 0);
66 0 : delete _crit;
67 0 : }
68 :
69 : template<class MemoryType>
70 0 : int32_t MemoryPoolImpl<MemoryType>::PopMemory(MemoryType*& memory)
71 : {
72 0 : CriticalSectionScoped cs(_crit);
73 0 : if(_terminate)
74 : {
75 0 : memory = NULL;
76 0 : return -1;
77 : }
78 0 : if (_memoryPool.empty()) {
79 : // _memoryPool empty create new memory.
80 0 : CreateMemory(_initialPoolSize);
81 0 : if(_memoryPool.empty())
82 : {
83 0 : memory = NULL;
84 0 : return -1;
85 : }
86 : }
87 0 : memory = _memoryPool.front();
88 0 : _memoryPool.pop_front();
89 0 : _outstandingMemory++;
90 0 : return 0;
91 : }
92 :
93 : template<class MemoryType>
94 0 : int32_t MemoryPoolImpl<MemoryType>::PushMemory(MemoryType*& memory)
95 : {
96 0 : if(memory == NULL)
97 : {
98 0 : return -1;
99 : }
100 0 : CriticalSectionScoped cs(_crit);
101 0 : _outstandingMemory--;
102 0 : if(_memoryPool.size() > (_initialPoolSize << 1))
103 : {
104 : // Reclaim memory if less than half of the pool is unused.
105 0 : _createdMemory--;
106 0 : delete memory;
107 0 : memory = NULL;
108 0 : return 0;
109 : }
110 0 : _memoryPool.push_back(memory);
111 0 : memory = NULL;
112 0 : return 0;
113 : }
114 :
115 : template<class MemoryType>
116 0 : bool MemoryPoolImpl<MemoryType>::Initialize()
117 : {
118 0 : CriticalSectionScoped cs(_crit);
119 0 : return CreateMemory(_initialPoolSize) == 0;
120 : }
121 :
122 : template<class MemoryType>
123 0 : int32_t MemoryPoolImpl<MemoryType>::Terminate()
124 : {
125 0 : CriticalSectionScoped cs(_crit);
126 0 : assert(_createdMemory == _outstandingMemory + _memoryPool.size());
127 :
128 0 : _terminate = true;
129 : // Reclaim all memory.
130 0 : while(_createdMemory > 0)
131 : {
132 0 : MemoryType* memory = _memoryPool.front();
133 0 : _memoryPool.pop_front();
134 0 : delete memory;
135 0 : _createdMemory--;
136 : }
137 0 : return 0;
138 : }
139 :
140 : template<class MemoryType>
141 0 : int32_t MemoryPoolImpl<MemoryType>::CreateMemory(
142 : uint32_t amountToCreate)
143 : {
144 0 : for(uint32_t i = 0; i < amountToCreate; i++)
145 : {
146 0 : MemoryType* memory = new MemoryType();
147 0 : if(memory == NULL)
148 : {
149 0 : return -1;
150 : }
151 0 : _memoryPool.push_back(memory);
152 0 : _createdMemory++;
153 : }
154 0 : return 0;
155 : }
156 : } // namespace webrtc
157 :
158 : #endif // WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_MEMORY_POOL_GENERIC_H_
|