Memory.h fixes
* Use a Nifty Counter for rpmalloc initialization. This fixes init order with other static objects using MmAllocator or MemoryManagger * Fix exception throwing in AlignedAllocator * Add missing constructor to MmAllocator for compatibility with std containers
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* MemoryManager.h
|
||||
* Memory.h
|
||||
*
|
||||
* Copyright (c) 2017 Lukas W <lukaswhl/at/gmail.com>
|
||||
* Copyright (c) 2014 Simon Symeonidis <lethaljellybean/at/gmail/com>
|
||||
@@ -32,25 +32,35 @@
|
||||
#include <vector>
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "NiftyCounter.h"
|
||||
|
||||
class LMMS_EXPORT MemoryManager
|
||||
{
|
||||
public:
|
||||
struct ThreadGuard
|
||||
{
|
||||
ThreadGuard();
|
||||
~ThreadGuard();
|
||||
};
|
||||
|
||||
static void * alloc( size_t size );
|
||||
static void free( void * ptr );
|
||||
|
||||
private:
|
||||
static void initialize();
|
||||
static void deinitialize();
|
||||
static void thread_initialize();
|
||||
static void thread_deinitialize();
|
||||
public:
|
||||
typedef NiftyCounter<MemoryManager::initialize, MemoryManager::deinitialize> MmCounter;
|
||||
typedef NiftyCounterTL<MemoryManager::thread_initialize, MemoryManager::thread_deinitialize> ThreadGuard;
|
||||
};
|
||||
|
||||
static MemoryManager::MmCounter _mm_counter;
|
||||
|
||||
template<typename T>
|
||||
struct MmAllocator
|
||||
class MmAllocator
|
||||
{
|
||||
public:
|
||||
MmAllocator() = default;
|
||||
template< class U > MmAllocator( const MmAllocator<U>& other ) {}
|
||||
typedef T value_type;
|
||||
template<class U> struct rebind { typedef MmAllocator<U> other; };
|
||||
template<class U> struct rebind { typedef MmAllocator<U> other; };
|
||||
|
||||
|
||||
T* allocate( std::size_t n )
|
||||
{
|
||||
|
||||
60
include/NiftyCounter.h
Normal file
60
include/NiftyCounter.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* NiftyCounter.h
|
||||
*
|
||||
* Copyright (c) 2018 Lukas W <lukaswhl/at/gmail.com>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This file is licensed under the MIT license. See LICENSE.MIT.txt file in the
|
||||
* project root for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/// Nifty counter, also known as "Schwarz Counter". Used for ensuring global
|
||||
/// static object initialization and destruction order.
|
||||
|
||||
template <typename T> class _NiftyCounter_Base
|
||||
{
|
||||
public:
|
||||
_NiftyCounter_Base()
|
||||
{
|
||||
if (! T::inc()) T::init();
|
||||
}
|
||||
_NiftyCounter_Base(const _NiftyCounter_Base& other) : _NiftyCounter_Base() {}
|
||||
|
||||
~_NiftyCounter_Base()
|
||||
{
|
||||
if (! T::dec()) T::deinit();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, void C(), void D()> class _NiftyCounterCD_Base : public _NiftyCounter_Base<T>
|
||||
{
|
||||
friend class _NiftyCounter_Base<T>;
|
||||
private:
|
||||
static void init() { C(); }
|
||||
static void deinit() { D(); }
|
||||
static int inc() { return T::s_count++; }
|
||||
static int dec() { return T::s_count--; }
|
||||
};
|
||||
|
||||
|
||||
/// Pass construction and destruction functions as template arguments C and D.
|
||||
template <void C(), void D()> class NiftyCounter : public _NiftyCounterCD_Base<NiftyCounter<C,D>, C,D>
|
||||
{
|
||||
friend class _NiftyCounterCD_Base<NiftyCounter<C,D>, C,D>;
|
||||
private:
|
||||
static int s_count;
|
||||
};
|
||||
template <void C(), void D()> int NiftyCounter<C, D>::s_count = 0;
|
||||
|
||||
/// Thread-local version of NiftyCounter
|
||||
template <void C(), void D()> class NiftyCounterTL : public _NiftyCounterCD_Base<NiftyCounterTL<C,D>, C,D>
|
||||
{
|
||||
friend class _NiftyCounterCD_Base<NiftyCounterTL<C,D>, C,D>;
|
||||
private:
|
||||
thread_local static int s_count;
|
||||
};
|
||||
template <void C(), void D()> thread_local int NiftyCounterTL<C, D>::s_count = 0;
|
||||
Reference in New Issue
Block a user