/*
* Copyright (C) 2014, The University of Texas at Austin
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of The University of Texas at Austin nor the names
* of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Copyright (C) 2014-2015, Michael Lehn
*
* ulmBLAS adopted general ideas from BLIS. Using micro kernels from BLIS
* only requires minor modifications,
*
*/
#ifndef ULMBLAS_IMPL_AUXILIARY_MEMORYPOOL_TCC
#define ULMBLAS_IMPL_AUXILIARY_MEMORYPOOL_TCC 1
#include <cassert>
#include <list>
#include <unordered_map>
#include <type_traits>
#include <ulmblas/impl/auxiliary/isfundamental.h>
#include <ulmblas/impl/auxiliary/memorypool.h>
#include <ulmblas/impl/config/simd.h>
#if defined(USE_SSE)
# include <xmmintrin.h>
#endif
namespace ulmBLAS {
template <typename T>
typename std::enable_if<IsFundamental<T>::value,
T *>::type
malloc(size_t n)
{
#if defined(USE_SSE)
return reinterpret_cast<T *>(_mm_malloc(n*sizeof(T), 16));
# else
return new T[n];
# endif
}
template <typename T>
typename std::enable_if<! IsFundamental<T>::value,
T *>::type
malloc(size_t n)
{
return new T[n];
}
template <typename T>
typename std::enable_if<IsFundamental<T>::value,
void>::type
free(T *block)
{
#if defined(USE_SSE)
_mm_free(reinterpret_cast<void *>(block));
# else
delete [] block;
# endif
}
template <typename T>
typename std::enable_if<! IsFundamental<T>::value,
void>::type
free(T *block)
{
delete [] block;
}
template <typename T>
T *
MemoryPool<T>::allocate(size_t n)
{
mutex_.lock();
BlockList &free = free_[n];
T *block;
if (free.empty()) {
block = malloc<T>(n);
allocated_.push_back(block);
} else {
block = free.back();
free.pop_back();
}
used_[block] = n;
mutex_.unlock();
return block;
}
template <typename T>
void
MemoryPool<T>::release(T *block)
{
mutex_.lock();
if (block) {
assert(used_.count(block)==1);
size_t n = used_[block];
free_[n].push_back(block);
}
mutex_.unlock();
}
template <typename T>
MemoryPool<T>::~MemoryPool()
{
while (!allocated_.empty()) {
free(allocated_.back());
allocated_.pop_back();
}
}
} // namespace ulmBLAS
#endif // ULMBLAS_IMPL_AUXILIARY_MEMORYPOOL_TCC
|