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

Further work on implementing memory pools for dynamically allocated objects.

* Fixed includes in sigslot.cpp
* Implemented memory pools also for AbstractJob using the pool of OpenGLJobProcessor
parent 06c00865
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#include "job.h"
#include <memory>
#include <new>
#include "core/tools/opengljobprocessor.h"
namespace campvis {
// Implementation inspired by http://stackoverflow.com/questions/7194127/how-should-i-write-iso-c-standard-conformant-custom-new-and-delete-operators/7194149#7194149
void* AbstractJob::operator new(std::size_t size) throw(std::bad_alloc) {
if (size == 0)
size = 1;
while (true) {
void* toReturn = OpenGLJobProcessor::getRef()._signalPool.malloc(size);
if (toReturn != nullptr)
return toReturn;
//allocation was unsuccessful; find out what the current new-handling function is (see below)
std::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 AbstractJob::operator delete(void* rawMemory, std::size_t size) throw() {
if (rawMemory == nullptr)
return;
OpenGLJobProcessor::getRef()._signalPool.free(rawMemory);
}
}
......@@ -49,6 +49,20 @@ namespace campvis {
void operator()() {
this->execute();
}
/**
* Overloading the new operator to create signal handles in signal_manager's memory pool.
* \param size Number of bytes to allocate.
*/
static void* operator new(std::size_t size) throw(std::bad_alloc);
/**
* Overloading the delete operator to correctly remove signal handles from signal_manager's memory pool.
* \param rawMemory Pointer to object to delete
* \param size Number of bytes
*/
static void operator delete(void* rawMemory, std::size_t size) throw();
};
// = Specific Jobs ================================================================================
......
......@@ -31,10 +31,12 @@
#include <ext/threading.h>
#define TBB_PREVIEW_MEMORY_POOL 1
#include <tbb/atomic.h>
#include <tbb/concurrent_queue.h>
#include <tbb/concurrent_hash_map.h>
#include <tbb/concurrent_vector.h>
#include <tbb/memory_pool.h>
#include "tgt/glcontextmanager.h"
#include "tgt/singleton.h"
......@@ -70,7 +72,8 @@ namespace campvis {
* This class is to be considered as thread-safe.
*/
class CAMPVIS_CORE_API OpenGLJobProcessor : public tgt::Singleton<OpenGLJobProcessor>, public tgt::Runnable, public sigslot::has_slots {
friend class tgt::Singleton<OpenGLJobProcessor>;
friend class tgt::Singleton<OpenGLJobProcessor>; ///< CRTP
friend class AbstractJob; ///< so the custom new/delete operator can access the memory pool
public:
/**
......@@ -208,6 +211,9 @@ namespace campvis {
tbb::atomic<tgt::GLCanvas*> _currentContext; ///< current active OpenGL context
private:
typedef std::allocator<AbstractJob> pool_allocator_t;
tbb::memory_pool<pool_allocator_t> _signalPool; ///< Memory pool for the signals
static std::thread::id _this_thread_id;
};
......
......@@ -27,6 +27,8 @@
// ================================================================================================
#include <memory>
#include <new>
#include "sigslot.h"
namespace sigslot {
......@@ -117,7 +119,7 @@ namespace sigslot {
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::new_handler globalHandler = std::set_new_handler(0);
std::set_new_handler(globalHandler);
if (globalHandler) //If new_hander is registered call it
......
......@@ -255,7 +255,17 @@ namespace sigslot {
/// Emits the signal of this signal handle.
virtual void processSignal() const = 0;
/**
* Overloading the new operator to create signal handles in signal_manager's memory pool.
* \param size Number of bytes to allocate.
*/
static void* operator new(std::size_t size) throw(std::bad_alloc);
/**
* Overloading the delete operator to correctly remove signal handles from signal_manager's memory pool.
* \param rawMemory Pointer to object to delete
* \param size Number of bytes
*/
static void operator delete(void* rawMemory, std::size_t size) throw();
#ifdef CAMPVIS_DEBUG
......@@ -282,8 +292,8 @@ namespace sigslot {
* signal_manager can be considered as thread-safe.
*/
class SIGSLOT_API signal_manager : public tgt::Singleton<signal_manager>, public tgt::Runnable {
friend class tgt::Singleton<signal_manager>;
friend class _signal_handle_base;
friend class tgt::Singleton<signal_manager>; ///< CRTP
friend class _signal_handle_base; ///< so the custom new/delete operator can access the memory pool
public:
/// Enumeration of signal handling modes for the signal_manager
......
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