Skip to content

Commit

Permalink
Replace MemoryManager implementation with rpmalloc (LMMS#3873)
Browse files Browse the repository at this point in the history
* Replace MemoryManager implementation with rpmalloc
    Fixes LMMS#3865
* Travis: Specify OSX image for Qt5 build
  • Loading branch information
lukas-w authored and PhysSong committed Oct 24, 2017
1 parent 4dc06f6 commit 158cf1a
Show file tree
Hide file tree
Showing 15 changed files with 97 additions and 276 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "src/3rdparty/qt5-x11embed"]
path = src/3rdparty/qt5-x11embed
url = https://github.com/Lukas-W/qt5-x11embed.git
[submodule "src/3rdparty/rpmalloc/rpmalloc"]
path = src/3rdparty/rpmalloc/rpmalloc
url = https://github.com/rampantpixels/rpmalloc.git
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ matrix:
osx_image: xcode8.2
- env: QT5=True
- os: osx
osx_image: xcode8.2
env: QT5=True
install: ${TRAVIS_BUILD_DIR}/.travis/install.sh
script: ${TRAVIS_BUILD_DIR}/.travis/script.sh
Expand Down
1 change: 1 addition & 0 deletions include/AutomatableModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#ifndef AUTOMATABLE_MODEL_H
#define AUTOMATABLE_MODEL_H

#include <QtCore/QMap>
#include <QtCore/QMutex>

#include "JournallingObject.h"
Expand Down
108 changes: 11 additions & 97 deletions include/MemoryManager.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* MemoryManager.h - A lightweight, generic memory manager for LMMS
* MemoryManager.h
*
* Copyright (c) 2017 Lukas W <lukaswhl/at/gmail.com>
* Copyright (c) 2014 Vesa Kivimäki
* Copyright (c) 2007-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
Expand All @@ -26,81 +27,22 @@
#ifndef MEMORY_MANAGER_H
#define MEMORY_MANAGER_H

#include <QtCore/QVector>
#include <QtCore/QMutex>
#include <QtCore/QHash>
#include "MemoryHelper.h"
#include "export.h"

class QReadWriteLock;

const int MM_CHUNK_SIZE = 64; // granularity of managed memory
const int MM_INITIAL_CHUNKS = 1024 * 1024; // how many chunks to allocate at startup - TODO: make configurable
const int MM_INCREMENT_CHUNKS = 16 * 1024; // min. amount of chunks to increment at a time

struct MemoryPool
{
void * m_pool;
char * m_free;
size_t m_chunks;
QMutex m_mutex;

MemoryPool() :
m_pool( NULL ),
m_free( NULL ),
m_chunks( 0 )
{}

MemoryPool( size_t chunks ) :
m_chunks( chunks )
{
m_free = reinterpret_cast<char*>( MemoryHelper::alignedMalloc( chunks ) );
memset( m_free, 1, chunks );
}

MemoryPool( const MemoryPool & mp ) :
m_pool( mp.m_pool ),
m_free( mp.m_free ),
m_chunks( mp.m_chunks ),
m_mutex()
{}

MemoryPool & operator = ( const MemoryPool & mp )
{
m_pool = mp.m_pool;
m_free = mp.m_free;
m_chunks = mp.m_chunks;
return *this;
}

void * getChunks( int chunksNeeded );
void releaseChunks( void * ptr, int chunks );
};
#include <cstddef>
#include <vector>

struct PtrInfo
{
int chunks;
MemoryPool * memPool;
};

typedef QVector<MemoryPool> MemoryPoolVector;
typedef QHash<void*, PtrInfo> PointerInfoMap;
#include "export.h"

class EXPORT MemoryManager
{
public:
static bool init();
struct ThreadGuard
{
ThreadGuard();
~ThreadGuard();
};

static void * alloc( size_t size );
static void free( void * ptr );
static int extend( int chunks ); // returns index of created pool (for use by alloc)
static void cleanup();

private:
static MemoryPoolVector s_memoryPools;
static QReadWriteLock s_poolMutex;

static PointerInfoMap s_pointerInfo;
static QMutex s_pointerMutex;
};

template<typename T>
Expand Down Expand Up @@ -147,32 +89,4 @@ static void operator delete[] ( void * ptr ) \
// and just for symmetry...
#define MM_FREE( ptr ) MemoryManager::free( ptr )



// for debugging purposes

#define MM_OPERATORS_DEBUG \
public: \
static void * operator new ( size_t size ) \
{ \
qDebug( "MM_OPERATORS_DEBUG: new called for %d bytes", size ); \
return MemoryManager::alloc( size ); \
} \
static void * operator new[] ( size_t size ) \
{ \
qDebug( "MM_OPERATORS_DEBUG: new[] called for %d bytes", size ); \
return MemoryManager::alloc( size ); \
} \
static void operator delete ( void * ptr ) \
{ \
qDebug( "MM_OPERATORS_DEBUG: delete called for %p", ptr ); \
MemoryManager::free( ptr ); \
} \
static void operator delete[] ( void * ptr ) \
{ \
qDebug( "MM_OPERATORS_DEBUG: delete[] called for %p", ptr ); \
MemoryManager::free( ptr ); \
}


#endif
1 change: 1 addition & 0 deletions include/PluginFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <memory>

#include <QtCore/QFileInfo>
#include <QtCore/QHash>
#include <QtCore/QList>

#include "export.h"
Expand Down
2 changes: 2 additions & 0 deletions plugins/carlabase/carla.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#ifndef CARLA_H
#define CARLA_H

#include <QtCore/QMutex>

#include "CarlaNative.h"

#include "Instrument.h"
Expand Down
4 changes: 4 additions & 0 deletions src/3rdparty/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ IF(QT5 AND LMMS_BUILD_LINUX)
ELSE()
add_library(qx11embedcontainer STATIC /dev/null)
ENDIF()
set(CMAKE_C_FLAGS "")
set(CMAKE_CXX_FLAGS "")

ADD_SUBDIRECTORY(rpmalloc)
30 changes: 30 additions & 0 deletions src/3rdparty/rpmalloc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
set(CMAKE_C_FLAGS "-std=c11")

add_library(rpmalloc STATIC
rpmalloc/rpmalloc/rpmalloc.c
rpmalloc/rpmalloc/rpmalloc.h
)

target_include_directories(rpmalloc PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/rpmalloc/rpmalloc
)

if (NOT LMMS_BUILD_WIN32)
target_compile_definitions(rpmalloc
PRIVATE -D_GNU_SOURCE
)
endif()

if (CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(rpmalloc
PRIVATE -DENABLE_ASSERTS=1 -DENABLE_VALIDATE_ARGS=1
)
endif()

option(LMMS_ENABLE_MALLOC_STATS "Enables statistics for rpmalloc" OFF)

if (LMMS_ENABLE_MALLOC_STATS)
target_compile_definitions(rpmalloc
PRIVATE -DENABLE_STATISTICS=1
)
endif()
1 change: 1 addition & 0 deletions src/3rdparty/rpmalloc/rpmalloc
Submodule rpmalloc added at 2e0479
10 changes: 10 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,24 @@ SET(LMMS_REQUIRED_LIBS ${LMMS_REQUIRED_LIBS}
${SAMPLERATE_LIBRARIES}
${SNDFILE_LIBRARIES}
${EXTRA_LIBRARIES}
rpmalloc
)

# Expose required libs for tests binary
SET(LMMS_REQUIRED_LIBS ${LMMS_REQUIRED_LIBS} PARENT_SCOPE)

TARGET_LINK_LIBRARIES(lmms
${LMMS_REQUIRED_LIBS}
)

FOREACH(LIB ${LMMS_REQUIRED_LIBS})
GET_TARGET_PROPERTY(INCLUDE_DIRS ${LIB} INTERFACE_INCLUDE_DIRECTORIES)
if (INCLUDE_DIRS)
TARGET_INCLUDE_DIRECTORIES(lmmsobjs PRIVATE ${INCLUDE_DIRS})
ENDIF()
ENDFOREACH()


# Required libs for debug msys builds
IF(LMMS_BUILD_MSYS AND CMAKE_BUILD_TYPE STREQUAL "Debug")
TARGET_LINK_LIBRARIES(lmms QtCore4 QtGui4 QtXml4)
Expand Down
Loading

0 comments on commit 158cf1a

Please sign in to comment.