Commit 8c32441b authored by Dominik Charousset's avatar Dominik Charousset

less intrusive memory management

this patch adds the class `memory_cached_mixin` which adds all
member functions and member variables needed by the memory management
subsystem
parent eb2b833a
...@@ -35,8 +35,10 @@ ...@@ -35,8 +35,10 @@
#include <vector> #include <vector>
#include <utility> #include <utility>
#include <typeinfo> #include <typeinfo>
#include <iostream>
#include "cppa/detail/recursive_queue_node.hpp" #include "cppa/config.hpp"
#include "cppa/ref_counted.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
...@@ -79,6 +81,45 @@ class memory_cache { ...@@ -79,6 +81,45 @@ class memory_cache {
}; };
class memory;
memory_cache* get_cache_map_entry(const std::type_info* tinf);
template<typename T>
class basic_memory_cache;
template<typename Base>
class memory_cached_mixin : public Base {
friend class memory;
template<typename T>
friend class basic_memory_cache;
protected:
template<typename... Args>
memory_cached_mixin(Args&&... args)
: Base(std::forward<Args>(args)...), outer_memory(nullptr) { }
virtual void request_deletion() {
memory_cache* mc = get_cache_map_entry(&typeid(*this));
if (!mc) {
auto om = outer_memory;
if (om) {
om->destroy();
om->deallocate();
}
else delete this;
}
else mc->release_instance(mc->downcast(this));
}
private:
instance_wrapper* outer_memory;
};
template<typename T> template<typename T>
class basic_memory_cache : public memory_cache { class basic_memory_cache : public memory_cache {
...@@ -178,39 +219,8 @@ class memory { ...@@ -178,39 +219,8 @@ class memory {
return result; return result;
} }
/*
* @brief Calls the destructor of @p ptr and allows the memory manager
* to reuse this address.
*/
template<typename T>
static inline void dispose(T* ptr) {
auto mc = get_or_set_cache_map_entry<T>();
mc->release_instance(ptr);
}
/*
* @brief Calls the destructor of @p ptr and allows the memory manager
* to reuse this address. This function must be used when disposing
* through a base pointer.
*/
template<typename T>
static inline void dispose_base(T* ptr) {
auto mc = get_cache_map_entry(&typeid(*ptr));
if (mc) mc->release_instance(mc->downcast(ptr));
else {
auto wptr = ptr->outer_memory;
if (wptr) {
wptr->destroy();
wptr->deallocate();
}
else delete ptr;
}
}
private: private:
static memory_cache* get_cache_map_entry(const std::type_info* tinf);
static void add_cache_map_entry(const std::type_info* tinf, memory_cache* instance); static void add_cache_map_entry(const std::type_info* tinf, memory_cache* instance);
template<typename T> template<typename T>
...@@ -226,9 +236,8 @@ class memory { ...@@ -226,9 +236,8 @@ class memory {
}; };
struct disposer { struct disposer {
template<typename T> inline void operator()(memory_managed* ptr) const {
void operator()(T* ptr) { ptr->request_deletion();
memory::dispose(ptr);
} }
}; };
......
...@@ -37,19 +37,14 @@ ...@@ -37,19 +37,14 @@
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/message_id.hpp" #include "cppa/message_id.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/detail/memory.hpp"
// needs access to constructor + destructor to initialize m_dummy_node // needs access to constructor + destructor to initialize m_dummy_node
namespace cppa { class local_actor; } namespace cppa { class local_actor; }
namespace cppa { namespace detail { namespace cppa { namespace detail {
class memory; class recursive_queue_node : public memory_cached_mixin<memory_managed> {
class instance_wrapper;
class recursive_queue_node : public memory_managed {
template<typename>
friend class basic_memory_cache;
friend class memory; friend class memory;
friend class ::cppa::local_actor; friend class ::cppa::local_actor;
...@@ -75,11 +70,6 @@ class recursive_queue_node : public memory_managed { ...@@ -75,11 +70,6 @@ class recursive_queue_node : public memory_managed {
recursive_queue_node(actor_ptr sptr, any_tuple data, message_id_t id = message_id_t()); recursive_queue_node(actor_ptr sptr, any_tuple data, message_id_t id = message_id_t());
~recursive_queue_node();
// a pointer to the outer memory region this instance belongs to
instance_wrapper* outer_memory;
}; };
} } // namespace cppa::detail } } // namespace cppa::detail
......
...@@ -37,12 +37,13 @@ ...@@ -37,12 +37,13 @@
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/behavior.hpp" #include "cppa/behavior.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/message_id.hpp"
#include "cppa/match_expr.hpp" #include "cppa/match_expr.hpp"
#include "cppa/exit_reason.hpp" #include "cppa/exit_reason.hpp"
#include "cppa/response_handle.hpp" #include "cppa/response_handle.hpp"
#include "cppa/partial_function.hpp" #include "cppa/partial_function.hpp"
#include "cppa/message_id.hpp" #include "cppa/detail/memory.hpp"
#include "cppa/detail/recursive_queue_node.hpp" #include "cppa/detail/recursive_queue_node.hpp"
namespace cppa { namespace cppa {
...@@ -52,12 +53,6 @@ class scheduler; ...@@ -52,12 +53,6 @@ class scheduler;
class message_future; class message_future;
class local_scheduler; class local_scheduler;
namespace detail {
class memory;
class instance_wrapper;
template<typename> class basic_memory_cache;
} // namespace detail
template<bool DiscardOld> template<bool DiscardOld>
struct behavior_policy { static const bool discard_old = DiscardOld; }; struct behavior_policy { static const bool discard_old = DiscardOld; };
...@@ -115,7 +110,7 @@ class message_future; ...@@ -115,7 +110,7 @@ class message_future;
/** /**
* @brief Base class for local running Actors. * @brief Base class for local running Actors.
*/ */
class local_actor : public actor { class local_actor : public detail::memory_cached_mixin<actor> {
typedef actor super; typedef actor super;
...@@ -458,12 +453,6 @@ class local_actor : public actor { ...@@ -458,12 +453,6 @@ class local_actor : public actor {
do_become(std::move(copy), discard_old); do_become(std::move(copy), discard_old);
} }
void request_deletion();
private:
detail::instance_wrapper* outer_memory;
}; };
/** /**
......
...@@ -33,8 +33,17 @@ ...@@ -33,8 +33,17 @@
namespace cppa { namespace cppa {
namespace detail { struct disposer; }
/**
* @brief This base enables derived classes to enforce a different
* allocation strategy than new/delete by providing a virtual
* protected @p request_deletion() function and non-public destructor.
*/
class memory_managed { class memory_managed {
friend struct detail::disposer;
protected: protected:
virtual ~memory_managed(); virtual ~memory_managed();
......
...@@ -48,30 +48,22 @@ class basic_memory_cache; ...@@ -48,30 +48,22 @@ class basic_memory_cache;
namespace cppa { namespace network { namespace cppa { namespace network {
class sync_request_info : public memory_managed { class sync_request_info : public detail::memory_cached_mixin<memory_managed> {
public:
template<typename>
friend class detail::basic_memory_cache;
friend class detail::memory; friend class detail::memory;
public:
typedef sync_request_info* pointer; typedef sync_request_info* pointer;
pointer next; // intrusive next pointer pointer next; // intrusive next pointer
actor_ptr sender; // points to the sender of the message actor_ptr sender; // points to the sender of the message
message_id_t mid; message_id_t mid; // sync message ID
private: private:
sync_request_info(actor_ptr sptr, message_id_t id); sync_request_info(actor_ptr sptr, message_id_t id);
~sync_request_info();
// intrusive outer memory pointer
detail::instance_wrapper* outer_memory;
}; };
class default_actor_proxy : public detail::abstract_actor<actor_proxy> { class default_actor_proxy : public detail::abstract_actor<actor_proxy> {
......
...@@ -69,10 +69,6 @@ class ref_counted : public memory_managed { ...@@ -69,10 +69,6 @@ class ref_counted : public memory_managed {
inline size_t get_reference_count() const { return m_rc; } inline size_t get_reference_count() const { return m_rc; }
protected:
virtual ~ref_counted();
private: private:
std::atomic<size_t> m_rc; std::atomic<size_t> m_rc;
......
...@@ -48,8 +48,6 @@ inline sync_request_info* new_req_info(actor_ptr sptr, message_id_t id) { ...@@ -48,8 +48,6 @@ inline sync_request_info* new_req_info(actor_ptr sptr, message_id_t id) {
sync_request_info::sync_request_info(actor_ptr sptr, message_id_t id) sync_request_info::sync_request_info(actor_ptr sptr, message_id_t id)
: next(nullptr), sender(std::move(sptr)), mid(id) { } : next(nullptr), sender(std::move(sptr)), mid(id) { }
sync_request_info::~sync_request_info() { }
default_actor_proxy::default_actor_proxy(actor_id mid, default_actor_proxy::default_actor_proxy(actor_id mid,
const process_information_ptr& pinfo, const process_information_ptr& pinfo,
const default_protocol_ptr& parent) const default_protocol_ptr& parent)
......
...@@ -70,8 +70,7 @@ class down_observer : public attachable { ...@@ -70,8 +70,7 @@ class down_observer : public attachable {
local_actor::local_actor(bool sflag) local_actor::local_actor(bool sflag)
: m_chaining(sflag), m_trap_exit(false) : m_chaining(sflag), m_trap_exit(false)
, m_is_scheduled(sflag), m_dummy_node(), m_current_node(&m_dummy_node) , m_is_scheduled(sflag), m_dummy_node(), m_current_node(&m_dummy_node) { }
, outer_memory(nullptr) { }
void local_actor::monitor(actor_ptr whom) { void local_actor::monitor(actor_ptr whom) {
if (whom) whom->attach(new down_observer(this, whom)); if (whom) whom->attach(new down_observer(this, whom));
...@@ -158,9 +157,4 @@ response_handle local_actor::make_response_handle() { ...@@ -158,9 +157,4 @@ response_handle local_actor::make_response_handle() {
return std::move(result); return std::move(result);
} }
void local_actor::request_deletion() {
if (outer_memory) detail::memory::dispose_base(this);
else super::request_deletion();
}
} // namespace cppa } // namespace cppa
...@@ -70,7 +70,7 @@ cache_map& get_cache_map() { ...@@ -70,7 +70,7 @@ cache_map& get_cache_map() {
return *cache; return *cache;
} }
memory_cache* memory::get_cache_map_entry(const type_info* tinf) { memory_cache* get_cache_map_entry(const type_info* tinf) {
auto& cache = get_cache_map(); auto& cache = get_cache_map();
auto i = cache.find(tinf); auto i = cache.find(tinf);
if (i != cache.end()) return i->second.get(); if (i != cache.end()) return i->second.get();
......
...@@ -38,8 +38,6 @@ recursive_queue_node::recursive_queue_node(actor_ptr sptr, ...@@ -38,8 +38,6 @@ recursive_queue_node::recursive_queue_node(actor_ptr sptr,
any_tuple data, any_tuple data,
message_id_t id) message_id_t id)
: next(nullptr), marked(false), sender(move(sptr)) : next(nullptr), marked(false), sender(move(sptr))
, msg(move(data)), mid(id), outer_memory(nullptr) { } , msg(move(data)), mid(id) { }
recursive_queue_node::~recursive_queue_node() { }
} } // namespace cppa::detail } } // namespace cppa::detail
...@@ -35,6 +35,4 @@ namespace cppa { ...@@ -35,6 +35,4 @@ namespace cppa {
ref_counted::ref_counted() : m_rc(0) { } ref_counted::ref_counted() : m_rc(0) { }
ref_counted::~ref_counted() { }
} // namespace cppa } // namespace cppa
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