blob: 695878dbb22c2b11fe93c2fd5d1ea1e5e0a1abac [file] [log] [blame]
/*
* 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_