| /* |
| * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #ifndef WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_MEMORY_POOL_GENERIC_H_ |
| #define WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_MEMORY_POOL_GENERIC_H_ |
| |
| #include <assert.h> |
| #include <list> |
| |
| #include "webrtc/rtc_base/criticalsection.h" |
| #include "webrtc/typedefs.h" |
| |
| namespace webrtc { |
| template<class MemoryType> |
| class MemoryPoolImpl |
| { |
| public: |
| // MemoryPool functions. |
| int32_t PopMemory(MemoryType*& memory); |
| int32_t PushMemory(MemoryType*& memory); |
| |
| MemoryPoolImpl(int32_t initialPoolSize); |
| ~MemoryPoolImpl(); |
| |
| // Atomic functions |
| int32_t Terminate(); |
| bool Initialize(); |
| private: |
| // Non-atomic function. |
| int32_t CreateMemory(uint32_t amountToCreate); |
| |
| rtc::CriticalSection _crit; |
| |
| bool _terminate; |
| |
| std::list<MemoryType*> _memoryPool; |
| |
| uint32_t _initialPoolSize; |
| uint32_t _createdMemory; |
| uint32_t _outstandingMemory; |
| }; |
| |
| template<class MemoryType> |
| MemoryPoolImpl<MemoryType>::MemoryPoolImpl(int32_t initialPoolSize) |
| : _terminate(false), |
| _initialPoolSize(initialPoolSize), |
| _createdMemory(0), |
| _outstandingMemory(0) |
| { |
| } |
| |
| template<class MemoryType> |
| MemoryPoolImpl<MemoryType>::~MemoryPoolImpl() |
| { |
| // Trigger assert if there is outstanding memory. |
| assert(_createdMemory == 0); |
| assert(_outstandingMemory == 0); |
| } |
| |
| template<class MemoryType> |
| int32_t MemoryPoolImpl<MemoryType>::PopMemory(MemoryType*& memory) |
| { |
| rtc::CritScope cs(&_crit); |
| if(_terminate) |
| { |
| memory = NULL; |
| return -1; |
| } |
| if (_memoryPool.empty()) { |
| // _memoryPool empty create new memory. |
| CreateMemory(_initialPoolSize); |
| if(_memoryPool.empty()) |
| { |
| memory = NULL; |
| return -1; |
| } |
| } |
| memory = _memoryPool.front(); |
| _memoryPool.pop_front(); |
| _outstandingMemory++; |
| return 0; |
| } |
| |
| template<class MemoryType> |
| int32_t MemoryPoolImpl<MemoryType>::PushMemory(MemoryType*& memory) |
| { |
| if(memory == NULL) |
| { |
| return -1; |
| } |
| rtc::CritScope cs(&_crit); |
| _outstandingMemory--; |
| if(_memoryPool.size() > (_initialPoolSize << 1)) |
| { |
| // Reclaim memory if less than half of the pool is unused. |
| _createdMemory--; |
| delete memory; |
| memory = NULL; |
| return 0; |
| } |
| _memoryPool.push_back(memory); |
| memory = NULL; |
| return 0; |
| } |
| |
| template<class MemoryType> |
| bool MemoryPoolImpl<MemoryType>::Initialize() |
| { |
| rtc::CritScope cs(&_crit); |
| return CreateMemory(_initialPoolSize) == 0; |
| } |
| |
| template<class MemoryType> |
| int32_t MemoryPoolImpl<MemoryType>::Terminate() |
| { |
| rtc::CritScope cs(&_crit); |
| assert(_createdMemory == _outstandingMemory + _memoryPool.size()); |
| |
| _terminate = true; |
| // Reclaim all memory. |
| while(_createdMemory > 0) |
| { |
| MemoryType* memory = _memoryPool.front(); |
| _memoryPool.pop_front(); |
| delete memory; |
| _createdMemory--; |
| } |
| return 0; |
| } |
| |
| template<class MemoryType> |
| int32_t MemoryPoolImpl<MemoryType>::CreateMemory( |
| uint32_t amountToCreate) |
| { |
| for(uint32_t i = 0; i < amountToCreate; i++) |
| { |
| MemoryType* memory = new MemoryType(); |
| if(memory == NULL) |
| { |
| return -1; |
| } |
| _memoryPool.push_back(memory); |
| _createdMemory++; |
| } |
| return 0; |
| } |
| } // namespace webrtc |
| |
| #endif // WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_MEMORY_POOL_GENERIC_H_ |