Commit fe323a83 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Introducing memory pools for sigslot::signal_handles to speedup signal handle allocation.

parent cd3297ef
...@@ -47,27 +47,34 @@ IF (WIN32) ...@@ -47,27 +47,34 @@ IF (WIN32)
# set debug and release library # set debug and release library
IF(CAMPVIS_WIN32) IF(CAMPVIS_WIN32)
SET(TBB_LIBRARY_DEBUG "${TbbDirectory}/lib/ia32/${TbbCompilerDirectory}/tbb_debug.lib") SET(TbbPlatformDirectory "ia32")
SET(TBB_DLL_DEBUG "${TbbDirectory}/bin/ia32/${TbbCompilerDirectory}/tbb_debug.dll")
SET(TBB_PDB_DEBUG "${TbbDirectory}/bin/ia32/${TbbCompilerDirectory}/tbb_debug.pdb")
SET(TBB_LIBRARY_RELEASE "${TbbDirectory}/lib/ia32/${TbbCompilerDirectory}/tbb.lib")
SET(TBB_DLL_RELEASE "${TbbDirectory}/bin/ia32/${TbbCompilerDirectory}/tbb.dll")
SET(TBB_PDB_RELEASE "${TbbDirectory}/bin/ia32/${TbbCompilerDirectory}/tbb.pdb")
ELSEIF(CAMPVIS_WIN64) ELSEIF(CAMPVIS_WIN64)
SET(TBB_LIBRARY_DEBUG "${TbbDirectory}/lib/intel64/${TbbCompilerDirectory}/tbb_debug.lib") SET(TbbPlatformDirectory "intel64")
SET(TBB_DLL_DEBUG "${TbbDirectory}/bin/intel64/${TbbCompilerDirectory}/tbb_debug.dll")
SET(TBB_PDB_DEBUG "${TbbDirectory}/bin/intel64/${TbbCompilerDirectory}/tbb_debug.pdb")
SET(TBB_LIBRARY_RELEASE "${TbbDirectory}/lib/intel64/${TbbCompilerDirectory}/tbb.lib")
SET(TBB_DLL_RELEASE "${TbbDirectory}/bin/intel64/${TbbCompilerDirectory}/tbb.dll")
SET(TBB_PDB_RELEASE "${TbbDirectory}/bin/intel64/${TbbCompilerDirectory}/tbb.pdb")
ELSE() ELSE()
MESSAGE(FATAL_ERROR "Neither CAMPVIS_WIN32 nor CAMPVIS_WIN64 defined!") MESSAGE(FATAL_ERROR "Neither CAMPVIS_WIN32 nor CAMPVIS_WIN64 defined!")
ENDIF(CAMPVIS_WIN32) ENDIF(CAMPVIS_WIN32)
IF (TBB_LIBRARY_DEBUG AND TBB_LIBRARY_RELEASE) SET(TBB_LIBRARY_DEBUG "${TbbDirectory}/lib/${TbbPlatformDirectory}/${TbbCompilerDirectory}/tbb_debug.lib")
SET(TBB_DLL_DEBUG "${TbbDirectory}/bin/${TbbPlatformDirectory}/${TbbCompilerDirectory}/tbb_debug.dll")
SET(TBB_PDB_DEBUG "${TbbDirectory}/bin/${TbbPlatformDirectory}/${TbbCompilerDirectory}/tbb_debug.pdb")
SET(TBB_LIBRARY_RELEASE "${TbbDirectory}/lib/${TbbPlatformDirectory}/${TbbCompilerDirectory}/tbb.lib")
SET(TBB_DLL_RELEASE "${TbbDirectory}/bin/${TbbPlatformDirectory}/${TbbCompilerDirectory}/tbb.dll")
SET(TBB_PDB_RELEASE "${TbbDirectory}/bin/${TbbPlatformDirectory}/${TbbCompilerDirectory}/tbb.pdb")
IF(TBB_LIBRARY_DEBUG AND TBB_LIBRARY_RELEASE)
SET(TBB_LIBRARY debug ${TBB_LIBRARY_DEBUG} optimized ${TBB_LIBRARY_RELEASE}) SET(TBB_LIBRARY debug ${TBB_LIBRARY_DEBUG} optimized ${TBB_LIBRARY_RELEASE})
ENDIF(TBB_LIBRARY_DEBUG AND TBB_LIBRARY_RELEASE) ENDIF(TBB_LIBRARY_DEBUG AND TBB_LIBRARY_RELEASE)
SET(TBB_MALLOC_LIBRARY_DEBUG "${TbbDirectory}/lib/${TbbPlatformDirectory}/${TbbCompilerDirectory}/tbbmalloc_debug.lib")
SET(TBB_MALLOC_DLL_DEBUG "${TbbDirectory}/bin/${TbbPlatformDirectory}/${TbbCompilerDirectory}/tbbmalloc_debug.dll")
SET(TBB_MALLOC_PDB_DEBUG "${TbbDirectory}/bin/${TbbPlatformDirectory}/${TbbCompilerDirectory}/tbbmalloc_debug.pdb")
SET(TBB_MALLOC_LIBRARY_RELEASE "${TbbDirectory}/lib/${TbbPlatformDirectory}/${TbbCompilerDirectory}/tbbmalloc.lib")
SET(TBB_MALLOC_DLL_RELEASE "${TbbDirectory}/bin/${TbbPlatformDirectory}/${TbbCompilerDirectory}/tbbmalloc.dll")
SET(TBB_MALLOC_PDB_RELEASE "${TbbDirectory}/bin/${TbbPlatformDirectory}/${TbbCompilerDirectory}/tbbmalloc.pdb")
IF(TBB_MALLOC_LIBRARY_DEBUG AND TBB_MALLOC_LIBRARY_RELEASE)
SET(TBB_MALLOC_LIBRARY debug ${TBB_MALLOC_LIBRARY_DEBUG} optimized ${TBB_MALLOC_LIBRARY_RELEASE})
ENDIF(TBB_MALLOC_LIBRARY_DEBUG AND TBB_MALLOC_LIBRARY_RELEASE)
SET(TBB_LICENSE_FILE "${TbbDirectory}/COPYING") SET(TBB_LICENSE_FILE "${TbbDirectory}/COPYING")
ELSE (WIN32) ELSE (WIN32)
......
...@@ -214,9 +214,9 @@ IF(TBB_FOUND) ...@@ -214,9 +214,9 @@ IF(TBB_FOUND)
MESSAGE(STATUS "* Found TBB") MESSAGE(STATUS "* Found TBB")
LIST(APPEND CampvisGlobalDefinitions ${TBB_DEFINITIONS}) LIST(APPEND CampvisGlobalDefinitions ${TBB_DEFINITIONS})
LIST(APPEND CampvisGlobalIncludeDirs ${TBB_INCLUDE_DIR}) LIST(APPEND CampvisGlobalIncludeDirs ${TBB_INCLUDE_DIR})
LIST(APPEND CampvisGlobalExternalLibs ${TBB_LIBRARY}) LIST(APPEND CampvisGlobalExternalLibs ${TBB_LIBRARY} ${TBB_MALLOC_LIBRARY})
LIST(APPEND CampvisExternalDllsDebug ${TBB_DLL_DEBUG}) LIST(APPEND CampvisExternalDllsDebug ${TBB_DLL_DEBUG} ${TBB_MALLOC_DLL_DEBUG})
LIST(APPEND CampvisExternalDllsRelease ${TBB_DLL_RELEASE}) LIST(APPEND CampvisExternalDllsRelease ${TBB_DLL_RELEASE} ${TBB_MALLOC_DLL_RELEASE})
LIST(APPEND CampvisExternalLicenseFiles ${TBB_LICENSE_FILE}) LIST(APPEND CampvisExternalLicenseFiles ${TBB_LICENSE_FILE})
ELSE(TBB_FOUND) ELSE(TBB_FOUND)
MESSAGE(FATAL_ERROR "TBB not found!") MESSAGE(FATAL_ERROR "TBB not found!")
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
// //
// ================================================================================================ // ================================================================================================
#include <memory>
#include "sigslot.h" #include "sigslot.h"
namespace sigslot { namespace sigslot {
...@@ -37,7 +38,7 @@ namespace sigslot { ...@@ -37,7 +38,7 @@ namespace sigslot {
} }
signal_manager::~signal_manager() { signal_manager::~signal_manager() {
_signalPool.recycle();
} }
void signal_manager::triggerSignalImpl(_signal_handle_base* signal) { void signal_manager::triggerSignalImpl(_signal_handle_base* signal) {
...@@ -103,4 +104,35 @@ namespace sigslot { ...@@ -103,4 +104,35 @@ namespace sigslot {
const std::string signal_manager::loggerCat_; const std::string signal_manager::loggerCat_;
// Implementation inspired by http://stackoverflow.com/questions/7194127/how-should-i-write-iso-c-standard-conformant-custom-new-and-delete-operators/7194149#7194149
void* _signal_handle_base::operator new(std::size_t size) throw(std::bad_alloc) {
if (size == 0)
size = 1;
while (true) {
void* toReturn = signal_manager::getRef()._signalPool.malloc(size);
if (toReturn != nullptr)
return toReturn;
//allocation was unsuccessful; find out what the current new-handling function is (see below)
new_handler globalHandler = std::set_new_handler(0);
std::set_new_handler(globalHandler);
if (globalHandler) //If new_hander is registered call it
(*globalHandler)();
else
throw std::bad_alloc(); //No handler is registered throw an exception
}
}
void _signal_handle_base::operator delete(void* rawMemory, std::size_t size) throw() {
if (rawMemory == nullptr)
return;
signal_manager::getRef()._signalPool.free(rawMemory);
return;
}
} }
...@@ -58,8 +58,10 @@ ...@@ -58,8 +58,10 @@
#include "tgt/assert.h" #include "tgt/assert.h"
#include <ext/threading.h> #include <ext/threading.h>
#define TBB_PREVIEW_MEMORY_POOL 1
#include <tbb/concurrent_queue.h> #include <tbb/concurrent_queue.h>
#include <tbb/concurrent_vector.h> #include <tbb/concurrent_vector.h>
#include <tbb/memory_pool.h>
#include <tbb/spin_mutex.h> #include <tbb/spin_mutex.h>
#include "ext/tgt/runnable.h" #include "ext/tgt/runnable.h"
...@@ -246,13 +248,16 @@ namespace sigslot { ...@@ -246,13 +248,16 @@ namespace sigslot {
// ================================================================================================ // ================================================================================================
/// Base class for signal handles that provides an interface to emit the signal. /// Base class for signal handles that provides an interface to emit the signal.
class _signal_handle_base { class SIGSLOT_API _signal_handle_base {
public: public:
/// Virtual destructor /// Virtual destructor
virtual ~_signal_handle_base() {}; virtual ~_signal_handle_base() {};
/// Emits the signal of this signal handle. /// Emits the signal of this signal handle.
virtual void processSignal() const = 0; virtual void processSignal() const = 0;
static void* operator new(std::size_t size) throw(std::bad_alloc);
static void operator delete(void* rawMemory, std::size_t size) throw();
#ifdef CAMPVIS_DEBUG #ifdef CAMPVIS_DEBUG
// This is debug information only, automatically removed from release builds // This is debug information only, automatically removed from release builds
...@@ -278,6 +283,7 @@ namespace sigslot { ...@@ -278,6 +283,7 @@ namespace sigslot {
*/ */
class SIGSLOT_API signal_manager : public tgt::Singleton<signal_manager>, public tgt::Runnable { class SIGSLOT_API signal_manager : public tgt::Singleton<signal_manager>, public tgt::Runnable {
friend class tgt::Singleton<signal_manager>; friend class tgt::Singleton<signal_manager>;
friend class _signal_handle_base;
public: public:
/// Enumeration of signal handling modes for the signal_manager /// Enumeration of signal handling modes for the signal_manager
...@@ -342,6 +348,9 @@ namespace sigslot { ...@@ -342,6 +348,9 @@ namespace sigslot {
std::thread::id _this_thread_id; std::thread::id _this_thread_id;
typedef std::allocator<_signal_handle_base> pool_allocator_t;
tbb::memory_pool<pool_allocator_t> _signalPool; ///< Memory pool for the signals
static const std::string loggerCat_; static const std::string loggerCat_;
}; };
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment