Commit 1e561870 authored by neverlord's avatar neverlord

maintenance

parent f812b653
...@@ -149,6 +149,9 @@ nobase_library_include_HEADERS = \ ...@@ -149,6 +149,9 @@ nobase_library_include_HEADERS = \
cppa/fsm_actor.hpp \ cppa/fsm_actor.hpp \
cppa/get.hpp \ cppa/get.hpp \
cppa/group.hpp \ cppa/group.hpp \
cppa/intrusive/iterator.hpp \
cppa/intrusive/single_reader_queue.hpp \
cppa/intrusive/singly_linked_list.hpp \
cppa/intrusive_ptr.hpp \ cppa/intrusive_ptr.hpp \
cppa/local_actor.hpp \ cppa/local_actor.hpp \
cppa/match.hpp \ cppa/match.hpp \
...@@ -182,7 +185,6 @@ nobase_library_include_HEADERS = \ ...@@ -182,7 +185,6 @@ nobase_library_include_HEADERS = \
cppa/util/comparable.hpp \ cppa/util/comparable.hpp \
cppa/util/compare_tuples.hpp \ cppa/util/compare_tuples.hpp \
cppa/util/conjunction.hpp \ cppa/util/conjunction.hpp \
cppa/util/default_deallocator.hpp \
cppa/util/disable_if.hpp \ cppa/util/disable_if.hpp \
cppa/util/disjunction.hpp \ cppa/util/disjunction.hpp \
cppa/util/duration.hpp \ cppa/util/duration.hpp \
...@@ -213,8 +215,6 @@ nobase_library_include_HEADERS = \ ...@@ -213,8 +215,6 @@ nobase_library_include_HEADERS = \
cppa/util/rm_ref.hpp \ cppa/util/rm_ref.hpp \
cppa/util/shared_lock_guard.hpp \ cppa/util/shared_lock_guard.hpp \
cppa/util/shared_spinlock.hpp \ cppa/util/shared_spinlock.hpp \
cppa/util/single_reader_queue.hpp \
cppa/util/singly_linked_list.hpp \
cppa/util/static_foreach.hpp \ cppa/util/static_foreach.hpp \
cppa/util/tbind.hpp \ cppa/util/tbind.hpp \
cppa/util/type_list.hpp \ cppa/util/type_list.hpp \
......
...@@ -48,8 +48,7 @@ cppa/util/replace_type.hpp ...@@ -48,8 +48,7 @@ cppa/util/replace_type.hpp
cppa/detail/serialize_tuple.hpp cppa/detail/serialize_tuple.hpp
unit_testing/test__atom.cpp unit_testing/test__atom.cpp
unit_testing/test__queue_performance.cpp unit_testing/test__queue_performance.cpp
cppa/util/single_reader_queue.hpp cppa/intrusive/single_reader_queue.hpp
cppa/util/singly_linked_list.hpp
unit_testing/test__local_group.cpp unit_testing/test__local_group.cpp
cppa/detail/channel.hpp cppa/detail/channel.hpp
cppa/local_actor.hpp cppa/local_actor.hpp
...@@ -232,7 +231,6 @@ benchmarks/mixed_case.erl ...@@ -232,7 +231,6 @@ benchmarks/mixed_case.erl
benchmarks/ActorCreation.scala benchmarks/ActorCreation.scala
benchmarks/MailboxPerformance.scala benchmarks/MailboxPerformance.scala
benchmarks/MixedCase.scala benchmarks/MixedCase.scala
cppa/util/default_deallocator.hpp
cppa/util/producer_consumer_list.hpp cppa/util/producer_consumer_list.hpp
cppa/util/arg_match_t.hpp cppa/util/arg_match_t.hpp
cppa/detail/types_array.hpp cppa/detail/types_array.hpp
...@@ -261,3 +259,6 @@ cppa/detail/tuple_cast_impl.hpp ...@@ -261,3 +259,6 @@ cppa/detail/tuple_cast_impl.hpp
cppa/match.hpp cppa/match.hpp
cppa/partial_function.hpp cppa/partial_function.hpp
src/partial_function.cpp src/partial_function.cpp
cppa/intrusive/singly_linked_list.hpp
cppa/intrusive/iterator.hpp
unit_testing/test__intrusive_containers.cpp
...@@ -169,7 +169,7 @@ class abstract_actor : public Base ...@@ -169,7 +169,7 @@ class abstract_actor : public Base
protected: protected:
util::single_reader_queue<queue_node> m_mailbox; intrusive::single_reader_queue<queue_node> m_mailbox;
template<typename T> template<typename T>
inline queue_node* fetch_node(actor* sender, T&& msg) inline queue_node* fetch_node(actor* sender, T&& msg)
......
...@@ -36,8 +36,9 @@ ...@@ -36,8 +36,9 @@
#include "cppa/abstract_actor.hpp" #include "cppa/abstract_actor.hpp"
#include "cppa/util/fiber.hpp" #include "cppa/util/fiber.hpp"
#include "cppa/util/singly_linked_list.hpp"
#include "cppa/util/single_reader_queue.hpp" #include "cppa/intrusive/singly_linked_list.hpp"
#include "cppa/intrusive/single_reader_queue.hpp"
#include "cppa/detail/delegate.hpp" #include "cppa/detail/delegate.hpp"
...@@ -50,9 +51,9 @@ class abstract_scheduled_actor : public abstract_actor<local_actor> ...@@ -50,9 +51,9 @@ class abstract_scheduled_actor : public abstract_actor<local_actor>
{ {
friend class task_scheduler; friend class task_scheduler;
friend class util::single_reader_queue<abstract_scheduled_actor>; friend class intrusive::single_reader_queue<abstract_scheduled_actor>;
abstract_scheduled_actor* next; // intrusive next pointer (single_reader_queue) abstract_scheduled_actor* next; // intrusive next pointer
void enqueue_node(queue_node* node); void enqueue_node(queue_node* node);
...@@ -63,8 +64,7 @@ class abstract_scheduled_actor : public abstract_actor<local_actor> ...@@ -63,8 +64,7 @@ class abstract_scheduled_actor : public abstract_actor<local_actor>
typedef abstract_actor super; typedef abstract_actor super;
typedef super::queue_node queue_node; typedef super::queue_node queue_node;
typedef util::singly_linked_list<queue_node> typedef intrusive::singly_linked_list<queue_node> queue_node_buffer;
queue_node_buffer;
enum dq_result enum dq_result
{ {
......
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
#include "cppa/local_actor.hpp" #include "cppa/local_actor.hpp"
#include "cppa/exit_reason.hpp" #include "cppa/exit_reason.hpp"
#include "cppa/abstract_actor.hpp" #include "cppa/abstract_actor.hpp"
#include "cppa/util/singly_linked_list.hpp" #include "cppa/intrusive/singly_linked_list.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
...@@ -86,8 +86,7 @@ class converted_thread_context : public abstract_actor<local_actor> ...@@ -86,8 +86,7 @@ class converted_thread_context : public abstract_actor<local_actor>
private: private:
typedef util::singly_linked_list<queue_node> typedef intrusive::singly_linked_list<queue_node> queue_node_buffer;
queue_node_buffer;
enum throw_on_exit_result enum throw_on_exit_result
{ {
......
...@@ -60,7 +60,9 @@ class invokable ...@@ -60,7 +60,9 @@ class invokable
public: public:
invokable() = default; invokable* next;
inline invokable() : next(nullptr) { }
virtual ~invokable(); virtual ~invokable();
virtual bool invoke(any_tuple const&) const = 0; virtual bool invoke(any_tuple const&) const = 0;
......
...@@ -35,8 +35,8 @@ ...@@ -35,8 +35,8 @@
#include "cppa/actor_proxy.hpp" #include "cppa/actor_proxy.hpp"
#include "cppa/process_information.hpp" #include "cppa/process_information.hpp"
#include "cppa/detail/native_socket.hpp" #include "cppa/detail/native_socket.hpp"
#include "cppa/util/single_reader_queue.hpp"
#include "cppa/detail/addressed_message.hpp" #include "cppa/detail/addressed_message.hpp"
#include "cppa/intrusive/single_reader_queue.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
...@@ -67,7 +67,7 @@ struct mailman_add_peer ...@@ -67,7 +67,7 @@ struct mailman_add_peer
class mailman_job class mailman_job
{ {
friend class util::single_reader_queue<mailman_job>; friend class intrusive::single_reader_queue<mailman_job>;
public: public:
...@@ -136,7 +136,7 @@ class mailman_job ...@@ -136,7 +136,7 @@ class mailman_job
void mailman_loop(); void mailman_loop();
util::single_reader_queue<mailman_job>& mailman_queue(); intrusive::single_reader_queue<mailman_job>& mailman_queue();
}} // namespace cppa::detail }} // namespace cppa::detail
......
...@@ -49,9 +49,9 @@ class network_manager ...@@ -49,9 +49,9 @@ class network_manager
virtual void stop() = 0; virtual void stop() = 0;
virtual util::single_reader_queue<mailman_job>& mailman_queue() = 0; virtual intrusive::single_reader_queue<mailman_job>& mailman_queue() = 0;
virtual util::single_reader_queue<post_office_msg>& post_office_queue() = 0; virtual intrusive::single_reader_queue<post_office_msg>& post_office_queue() = 0;
static network_manager* create_singleton(); static network_manager* create_singleton();
......
...@@ -36,14 +36,14 @@ ...@@ -36,14 +36,14 @@
#include "cppa/intrusive_ptr.hpp" #include "cppa/intrusive_ptr.hpp"
#include "cppa/process_information.hpp" #include "cppa/process_information.hpp"
#include "cppa/detail/native_socket.hpp" #include "cppa/detail/native_socket.hpp"
#include "cppa/util/single_reader_queue.hpp" #include "cppa/intrusive/single_reader_queue.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
class post_office_msg class post_office_msg
{ {
friend class util::single_reader_queue<post_office_msg>; friend class intrusive::single_reader_queue<post_office_msg>;
public: public:
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include "cppa/scheduler.hpp" #include "cppa/scheduler.hpp"
#include "cppa/detail/thread.hpp" #include "cppa/detail/thread.hpp"
#include "cppa/detail/abstract_scheduled_actor.hpp" #include "cppa/detail/abstract_scheduled_actor.hpp"
#include "cppa/util/single_reader_queue.hpp" #include "cppa/intrusive/single_reader_queue.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
...@@ -43,7 +43,7 @@ class task_scheduler : public scheduler ...@@ -43,7 +43,7 @@ class task_scheduler : public scheduler
typedef scheduler super; typedef scheduler super;
typedef util::single_reader_queue<abstract_scheduled_actor> job_queue; typedef intrusive::single_reader_queue<abstract_scheduled_actor> job_queue;
job_queue m_queue; job_queue m_queue;
scheduled_actor_dummy m_dummy; scheduled_actor_dummy m_dummy;
......
...@@ -44,8 +44,6 @@ ...@@ -44,8 +44,6 @@
#include "cppa/detail/yield_interface.hpp" #include "cppa/detail/yield_interface.hpp"
#include "cppa/detail/abstract_scheduled_actor.hpp" #include "cppa/detail/abstract_scheduled_actor.hpp"
#include "cppa/util/singly_linked_list.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
class yielding_actor : public abstract_scheduled_actor class yielding_actor : public abstract_scheduled_actor
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef ITERATOR_HPP
#define ITERATOR_HPP
#include <iterator>
namespace cppa { namespace intrusive {
template<class T>
class iterator // : std::iterator<forward_iterator_tag, T>
{
public:
typedef T value_type;
typedef value_type& reference;
typedef value_type const& const_reference;
typedef value_type* pointer;
typedef value_type const* const_pointer;
typedef ptrdiff_t difference_type;
typedef std::forward_iterator_tag iterator_category;
inline iterator(T* ptr) : m_ptr(ptr) { }
iterator(iterator const&) = default;
iterator& operator=(iterator const&) = default;
inline iterator& operator++()
{
m_ptr = m_ptr->next;
return *this;
}
inline iterator operator++(int)
{
iterator tmp{*this};
m_ptr = m_ptr->next;
return tmp;
}
inline reference operator*() { return *m_ptr; }
inline const_reference operator*() const { return *m_ptr; }
inline pointer operator->() { return m_ptr; }
inline const_pointer operator->() const { return m_ptr; }
inline pointer ptr() { return m_ptr; }
inline const_pointer ptr() const { return m_ptr; }
private:
pointer m_ptr;
};
template<class T>
inline bool operator==(iterator<T> const& lhs, iterator<T> const& rhs)
{
return lhs.ptr() == rhs.ptr();
}
template<class T>
inline bool operator==(iterator<T> const& lhs, T const* rhs)
{
return lhs.ptr() == rhs;
}
template<class T>
inline bool operator==(T const* lhs, iterator<T> const& rhs)
{
return lhs == rhs.ptr();
}
template<class T>
inline bool operator==(iterator<T> const& lhs, decltype(nullptr))
{
return lhs.ptr() == nullptr;
}
template<class T>
inline bool operator==(decltype(nullptr), iterator<T> const& rhs)
{
return rhs.ptr() == nullptr;
}
template<class T>
inline bool operator!=(iterator<T> const& lhs, iterator<T> const& rhs)
{
return !(lhs == rhs);
}
template<class T>
inline bool operator!=(iterator<T> const& lhs, T const* rhs)
{
return !(lhs == rhs);
}
template<class T>
inline bool operator!=(T const* lhs, iterator<T> const& rhs)
{
return !(lhs == rhs);
}
template<class T>
inline bool operator!=(iterator<T> const& lhs, decltype(nullptr))
{
return !(lhs == nullptr);
}
template<class T>
inline bool operator!=(decltype(nullptr), iterator<T> const& rhs)
{
return !(nullptr == rhs);
}
} } // namespace cppa::intrusive
#endif // ITERATOR_HPP
...@@ -34,19 +34,18 @@ ...@@ -34,19 +34,18 @@
#include <atomic> #include <atomic>
#include "cppa/detail/thread.hpp" #include "cppa/detail/thread.hpp"
#include "cppa/util/default_deallocator.hpp" #include "cppa/intrusive/singly_linked_list.hpp"
namespace cppa { namespace util { namespace cppa { namespace intrusive {
/** /**
* @brief An intrusive, thread safe queue implementation. * @brief An intrusive, thread safe queue implementation.
*/ */
template<typename T, class Deallocator = default_deallocator<T> > template<typename T>
class single_reader_queue class single_reader_queue
{ {
typedef detail::unique_lock<detail::mutex> lock_type; typedef detail::unique_lock<detail::mutex> lock_type;
Deallocator d;
public: public:
...@@ -97,8 +96,9 @@ class single_reader_queue ...@@ -97,8 +96,9 @@ class single_reader_queue
/** /**
* @warning call only from the reader (owner) * @warning call only from the reader (owner)
*/ */
template<typename List> //template<typename List>
void push_front(List&& list) //void push_front(List&& list)
void push_front(singly_linked_list<T>&& list)
{ {
if (!list.empty()) if (!list.empty())
{ {
...@@ -172,8 +172,7 @@ class single_reader_queue ...@@ -172,8 +172,7 @@ class single_reader_queue
{ {
element_type* tmp = e; element_type* tmp = e;
e = e->next; e = e->next;
d(tmp); delete tmp;
//delete tmp;
} }
} }
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef SINGLY_LINKED_LIST_HPP
#define SINGLY_LINKED_LIST_HPP
#include <cstddef>
#include <utility>
#include "cppa/config.hpp"
#include "cppa/intrusive/iterator.hpp"
namespace cppa { namespace intrusive {
template<class T>
class singly_linked_list
{
singly_linked_list(singly_linked_list const&) = delete;
singly_linked_list& operator=(singly_linked_list const&) = delete;
public:
typedef T value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef value_type& reference;
typedef value_type const& const_reference;
typedef value_type* pointer;
typedef value_type const* const_pointer;
typedef ::cppa::intrusive::iterator<value_type> iterator;
typedef ::cppa::intrusive::iterator<value_type const> const_iterator;
singly_linked_list() : m_head(nullptr), m_tail(nullptr) { }
singly_linked_list(singly_linked_list&& other)
: m_head(other.m_head), m_tail(other.m_tail)
{
other.m_head = other.m_tail = nullptr;
}
singly_linked_list& operator=(singly_linked_list&& other)
{
std::swap(m_head, other.m_head);
std::swap(m_tail, other.m_tail);
return *this;
}
static singly_linked_list from(std::pair<pointer, pointer> const& p)
{
singly_linked_list result;
result.m_head = p.first;
result.m_tail = p.second;
return result;
}
~singly_linked_list() { clear(); }
// element access
inline reference front() { return *m_head; }
inline const_reference front() const { return *m_head; }
inline reference back() { return *m_tail; }
inline const_reference back() const { return *m_tail; }
// iterators
inline iterator begin() { return m_head; }
inline const_iterator begin() const { return m_head; }
inline const_iterator cbegin() const { return m_head; }
inline iterator before_end() { return m_tail; }
inline const_iterator before_end() const { return m_tail; }
inline const_iterator cbefore_end() const { return m_tail; }
inline iterator end() { return nullptr; }
inline const_iterator end() const { return nullptr; }
inline const_iterator cend() const { return nullptr; }
// capacity
inline bool empty() const { return m_head == nullptr; }
// no size member function because it would have O(n) complexity
// modifiers
void clear()
{
while (m_head)
{
pointer next = m_head->next;
delete m_head;
m_head = next;
}
m_tail = nullptr;
}
iterator insert_after(iterator i, pointer what)
{
what->next = i->next;
i->next = what;
return what;
}
template<typename... Args>
void emplace_after(iterator i, Args&&... args)
{
insert_after(i, new value_type(std::forward<Args>(args)...));
}
iterator erase_after(iterator pos)
{
CPPA_REQUIRE(pos != nullptr);
auto next = pos->next;
if (next)
{
pos->next = next->next;
delete next;
}
return pos->next;
}
void push_back(pointer what)
{
what->next = nullptr;
if (empty())
{
m_tail = m_head = what;
}
else
{
m_tail->next = what;
m_tail = what;
}
}
template<typename... Args>
void emplace_back(Args&&... args)
{
push_back(new value_type(std::forward<Args>(args)...));
}
// pop_back would have complexity O(n)
void push_front(pointer what)
{
if (empty())
{
what->next = nullptr;
m_tail = m_head = what;
}
else
{
what->next = m_head;
m_head = what;
}
}
template<typename... Args>
void emplace_front(Args&&... args)
{
push_front(new value_type(std::forward<Args>(args)...));
}
void pop_front()
{
if (!empty())
{
auto next = m_head->next;
delete m_head;
m_head = next;
if (m_head == nullptr) m_tail = nullptr;
}
}
std::pair<pointer, pointer> take()
{
auto result = std::make_pair(m_head, m_tail);
m_head = m_tail = nullptr;
return result;
}
void splice_after(iterator pos, singly_linked_list&& other)
{
CPPA_REQUIRE(pos != nullptr);
CPPA_REQUIRE(this != &other);
if (other.empty() == false)
{
auto next = pos->next;
auto pair = other.take();
pos->next = pair.first;
pair.second->next = next;
if (pos == m_tail)
{
CPPA_REQUIRE(next == nullptr);
m_tail = pair.second;
}
}
}
template<typename UnaryPredicate>
void remove_if(UnaryPredicate p)
{
auto i = begin();
while (!empty() && p(*i))
{
pop_front();
i = begin();
}
if (empty()) return;
auto predecessor = i;
++i;
while (i != nullptr)
{
if (p(*i))
{
i = erase_after(predecessor);
}
else
{
predecessor = i;
++i;
}
}
}
void remove(value_type const& value)
{
remove_if([&](value_type const& other) { return value == other; });
}
private:
pointer m_head;
pointer m_tail;
};
} } // namespace cppa::intrusive
#endif // SINGLY_LINKED_LIST_HPP
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include "cppa/behavior.hpp" #include "cppa/behavior.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/partial_function.hpp" #include "cppa/partial_function.hpp"
#include "cppa/util/single_reader_queue.hpp" #include "cppa/intrusive/single_reader_queue.hpp"
namespace cppa { namespace cppa {
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <utility> #include <utility>
#include "cppa/detail/invokable.hpp" #include "cppa/detail/invokable.hpp"
#include "cppa/intrusive/singly_linked_list.hpp"
namespace cppa { namespace cppa {
...@@ -69,7 +70,8 @@ class partial_function ...@@ -69,7 +70,8 @@ class partial_function
template<class... Args> template<class... Args>
partial_function& splice(partial_function&& arg0, Args&&... args) partial_function& splice(partial_function&& arg0, Args&&... args)
{ {
m_funs.splice(m_funs.end(), std::move(arg0.m_funs)); if (m_funs.empty()) m_funs = std::move(arg0.m_funs);
else m_funs.splice_after(m_funs.before_end(), std::move(arg0.m_funs));
return splice(std::forward<Args>(args)...); return splice(std::forward<Args>(args)...);
} }
...@@ -85,7 +87,7 @@ class partial_function ...@@ -85,7 +87,7 @@ class partial_function
typedef std::vector<detail::invokable*> cache_entry; typedef std::vector<detail::invokable*> cache_entry;
typedef std::pair<void const*, cache_entry> cache_element; typedef std::pair<void const*, cache_entry> cache_element;
std::list<invokable_ptr> m_funs; intrusive::singly_linked_list<detail::invokable> m_funs;
std::vector<cache_element> m_cache; std::vector<cache_element> m_cache;
cache_element m_dummy; // binary search dummy cache_element m_dummy; // binary search dummy
......
#ifndef DEFAULT_DEALLOCATOR_HPP
#define DEFAULT_DEALLOCATOR_HPP
namespace cppa { namespace util {
template<typename T>
struct default_deallocator
{
inline void operator()(T* ptr) { delete ptr; }
};
} } // namespace cppa::detail
#endif // DEFAULT_DEALLOCATOR_HPP
...@@ -184,7 +184,6 @@ auto abstract_scheduled_actor::dq(queue_node_ptr& node, ...@@ -184,7 +184,6 @@ auto abstract_scheduled_actor::dq(queue_node_ptr& node,
if (!buffer.empty()) if (!buffer.empty())
{ {
m_mailbox.push_front(std::move(buffer)); m_mailbox.push_front(std::move(buffer));
buffer.clear();
} }
return dq_timeout_occured; return dq_timeout_occured;
} }
...@@ -199,7 +198,6 @@ auto abstract_scheduled_actor::dq(queue_node_ptr& node, ...@@ -199,7 +198,6 @@ auto abstract_scheduled_actor::dq(queue_node_ptr& node,
if (!buffer.empty()) if (!buffer.empty())
{ {
m_mailbox.push_front(std::move(buffer)); m_mailbox.push_front(std::move(buffer));
buffer.clear();
} }
// expire pending request // expire pending request
if (m_has_pending_timeout_request) if (m_has_pending_timeout_request)
......
...@@ -90,11 +90,6 @@ mailman_job::~mailman_job() ...@@ -90,11 +90,6 @@ mailman_job::~mailman_job()
} }
} }
/*
// implemented in post_office.cpp
util::single_reader_queue<mailman_job>& mailman_queue();
*/
// known issues: send() should be asynchronous and select() should be used // known issues: send() should be asynchronous and select() should be used
void mailman_loop() void mailman_loop()
{ {
......
...@@ -51,8 +51,8 @@ using namespace cppa::detail; ...@@ -51,8 +51,8 @@ using namespace cppa::detail;
struct network_manager_impl : network_manager struct network_manager_impl : network_manager
{ {
typedef util::single_reader_queue<post_office_msg> post_office_queue_t; typedef intrusive::single_reader_queue<post_office_msg> post_office_queue_t;
typedef util::single_reader_queue<mailman_job> mailman_queue_t; typedef intrusive::single_reader_queue<mailman_job> mailman_queue_t;
int m_pipe[2]; // m_pipe[0]: read; m_pipe[1]: write int m_pipe[2]; // m_pipe[0]: read; m_pipe[1]: write
...@@ -88,12 +88,12 @@ struct network_manager_impl : network_manager ...@@ -88,12 +88,12 @@ struct network_manager_impl : network_manager
return m_pipe[1]; return m_pipe[1];
} }
util::single_reader_queue<mailman_job>& mailman_queue() mailman_queue_t& mailman_queue()
{ {
return m_mailman_queue; return m_mailman_queue;
} }
util::single_reader_queue<post_office_msg>& post_office_queue() post_office_queue_t& post_office_queue()
{ {
return m_post_office_queue; return m_post_office_queue;
} }
......
...@@ -37,7 +37,7 @@ namespace cppa { ...@@ -37,7 +37,7 @@ namespace cppa {
partial_function::partial_function(invokable_ptr&& ptr) partial_function::partial_function(invokable_ptr&& ptr)
{ {
m_funs.push_back(std::move(ptr)); m_funs.push_back(ptr.release());
} }
partial_function::partial_function(partial_function&& other) partial_function::partial_function(partial_function&& other)
...@@ -68,12 +68,9 @@ auto partial_function::get_cache_entry(any_tuple const& value) -> cache_entry& ...@@ -68,12 +68,9 @@ auto partial_function::get_cache_entry(any_tuple const& value) -> cache_entry&
{ {
// ... create one (store all invokables with matching types) // ... create one (store all invokables with matching types)
cache_entry tmp; cache_entry tmp;
for (auto& fun : m_funs) for (auto f = m_funs.begin(); f != m_funs.end(); ++f)
{ {
if (fun->types_match(value)) if (f->types_match(value)) tmp.push_back(f.ptr());
{
tmp.push_back(fun.get());
}
} }
// m_cache is always sorted, // m_cache is always sorted,
// due to emplace(upper_bound, ...) insertions // due to emplace(upper_bound, ...) insertions
......
...@@ -52,8 +52,8 @@ ...@@ -52,8 +52,8 @@
#include "cppa/deserializer.hpp" #include "cppa/deserializer.hpp"
#include "cppa/binary_deserializer.hpp" #include "cppa/binary_deserializer.hpp"
// used cppa utility // used cppa intrusive containers
#include "cppa/util/single_reader_queue.hpp" #include "cppa/intrusive/single_reader_queue.hpp"
// used cppa details // used cppa details
#include "cppa/detail/thread.hpp" #include "cppa/detail/thread.hpp"
...@@ -103,7 +103,7 @@ constexpr int s_rdflag = MSG_DONTWAIT; ...@@ -103,7 +103,7 @@ constexpr int s_rdflag = MSG_DONTWAIT;
namespace cppa { namespace detail { namespace cppa { namespace detail {
util::single_reader_queue<mailman_job>& mailman_queue() intrusive::single_reader_queue<mailman_job>& mailman_queue()
{ {
return singleton_manager::get_network_manager()->mailman_queue(); return singleton_manager::get_network_manager()->mailman_queue();
} }
......
...@@ -53,7 +53,7 @@ void enqueue_fun(cppa::detail::thread_pool_scheduler* where, ...@@ -53,7 +53,7 @@ void enqueue_fun(cppa::detail::thread_pool_scheduler* where,
typedef unique_lock<mutex> guard_type; typedef unique_lock<mutex> guard_type;
typedef std::unique_ptr<thread_pool_scheduler::worker> worker_ptr; typedef std::unique_ptr<thread_pool_scheduler::worker> worker_ptr;
typedef util::single_reader_queue<thread_pool_scheduler::worker> worker_queue; typedef intrusive::single_reader_queue<thread_pool_scheduler::worker> worker_queue;
} // namespace <anonmyous> } // namespace <anonmyous>
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
#include "cppa/binary_serializer.hpp" #include "cppa/binary_serializer.hpp"
#include "cppa/binary_deserializer.hpp" #include "cppa/binary_deserializer.hpp"
#include "cppa/util/single_reader_queue.hpp" #include "cppa/intrusive/single_reader_queue.hpp"
#include "cppa/detail/mailman.hpp" #include "cppa/detail/mailman.hpp"
#include "cppa/detail/post_office.hpp" #include "cppa/detail/post_office.hpp"
......
...@@ -7,6 +7,7 @@ unit_tests_SOURCES = main.cpp \ ...@@ -7,6 +7,7 @@ unit_tests_SOURCES = main.cpp \
ping_pong.cpp \ ping_pong.cpp \
test__atom.cpp \ test__atom.cpp \
test__fixed_vector.cpp \ test__fixed_vector.cpp \
test__intrusive_containers.cpp \
test__intrusive_ptr.cpp \ test__intrusive_ptr.cpp \
test__local_group.cpp \ test__local_group.cpp \
test__pattern.cpp \ test__pattern.cpp \
......
...@@ -160,6 +160,7 @@ int main(int argc, char** argv) ...@@ -160,6 +160,7 @@ int main(int argc, char** argv)
size_t errors = 0; size_t errors = 0;
RUN_TEST(test__ripemd_160); RUN_TEST(test__ripemd_160);
RUN_TEST(test__primitive_variant); RUN_TEST(test__primitive_variant);
RUN_TEST(test__intrusive_containers);
RUN_TEST(test__uniform_type); RUN_TEST(test__uniform_type);
RUN_TEST(test__pattern); RUN_TEST(test__pattern);
RUN_TEST(test__intrusive_ptr); RUN_TEST(test__intrusive_ptr);
......
...@@ -64,6 +64,7 @@ size_t test__serialization(); ...@@ -64,6 +64,7 @@ size_t test__serialization();
size_t test__local_group(); size_t test__local_group();
size_t test__primitive_variant(); size_t test__primitive_variant();
size_t test__fixed_vector(); size_t test__fixed_vector();
size_t test__intrusive_containers();
void test__queue_performance(); void test__queue_performance();
......
...@@ -28,70 +28,89 @@ ...@@ -28,70 +28,89 @@
\******************************************************************************/ \******************************************************************************/
#ifndef SINGLY_LINKED_LIST_HPP #include <iterator>
#define SINGLY_LINKED_LIST_HPP
#include <utility> #include "test.hpp"
#include "cppa/util/default_deallocator.hpp" #include "cppa/intrusive/singly_linked_list.hpp"
namespace cppa { namespace util { using std::begin;
using std::end;
template<typename T, class Deallocator = default_deallocator<T> > namespace { size_t s_iint_instances = 0; }
class singly_linked_list
{
Deallocator d;
T* m_head;
T* m_tail;
public:
typedef T element_type; struct iint
{
singly_linked_list() : m_head(nullptr), m_tail(nullptr) { } iint* next;
int value;
inline iint(int val = 0) : next(nullptr), value(val) { ++s_iint_instances; }
~iint() { --s_iint_instances; }
};
~singly_linked_list() inline bool operator==(iint const& lhs, iint const& rhs)
{ {
clear(); return lhs.value == rhs.value;
} }
inline bool empty() const { return m_head == nullptr; } inline bool operator==(iint const& lhs, int rhs)
{
return lhs.value == rhs;
}
void push_back(element_type* what) inline bool operator==(int lhs, iint const& rhs)
{ {
what->next = nullptr; return lhs == rhs.value;
if (m_tail) }
{
m_tail->next = what;
m_tail = what;
}
else
{
m_head = m_tail = what;
}
}
std::pair<element_type*, element_type*> take() typedef cppa::intrusive::singly_linked_list<iint> iint_list;
{
element_type* first = m_head;
element_type* last = m_tail;
m_head = m_tail = nullptr;
return { first, last };
}
void clear() size_t test__intrusive_containers()
{
CPPA_TEST(test__intrusive_containers);
iint_list ilist1;
ilist1.push_back(new iint(1));
ilist1.emplace_back(2);
ilist1.push_back(new iint(3));
{ {
while (m_head) iint_list tmp;
{ tmp.push_back(new iint(4));
T* next = m_head->next; tmp.push_back(new iint(5));
d(m_head); ilist1.splice_after(ilist1.before_end(), std::move(tmp));
m_head = next; CPPA_CHECK(tmp.empty());
}
m_head = m_tail = nullptr;
} }
int iarr1[] = { 1, 2, 3, 4, 5 };
}; CPPA_CHECK((std::equal(begin(iarr1), end(iarr1), begin(ilist1))));
CPPA_CHECK((std::equal(begin(ilist1), end(ilist1), begin(iarr1))));
} } // namespace cppa::util
ilist1.push_front(new iint(0));
#endif // SINGLY_LINKED_LIST_HPP auto i = ilist1.erase_after(ilist1.begin());
// i points to second element
CPPA_CHECK_EQUAL(*i, 2);
i = ilist1.insert_after(i, new iint(20));
CPPA_CHECK_EQUAL(*i, 20);
int iarr2[] = { 0, 2, 20, 3, 4, 5 };
CPPA_CHECK((std::equal(begin(iarr2), end(iarr2), begin(ilist1))));
auto p = ilist1.take();
CPPA_CHECK(ilist1.empty());
auto ilist2 = iint_list::from(p);
ilist2.emplace_front(1); // 1 0 2 20 3 4 5
i = ilist2.erase_after(ilist2.begin()); // 1 2 20 3 4 5
CPPA_CHECK_EQUAL(*i, 2);
ilist2.erase_after(i); // 1 2 3 4 5
CPPA_CHECK((std::equal(begin(iarr1), end(iarr1), begin(ilist2))));
CPPA_CHECK_EQUAL(s_iint_instances, 5);
ilist2.remove_if([](iint const& val) { return (val.value % 2) != 0; });
CPPA_CHECK_EQUAL(s_iint_instances, 2);
int iarr3[] = { 2, 4 };
CPPA_CHECK((std::equal(begin(iarr3), end(iarr3), begin(ilist2))));
ilist2.clear();
CPPA_CHECK_EQUAL(s_iint_instances, 0);
CPPA_CHECK(ilist2.empty());
return CPPA_TEST_RESULT;
}
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <boost/progress.hpp> #include <boost/progress.hpp>
#include "cppa/util/single_reader_queue.hpp" #include "cppa/intrusive/single_reader_queue.hpp"
//#define DEBUG_RESULTS //#define DEBUG_RESULTS
...@@ -22,7 +22,7 @@ const size_t trials = 10; ...@@ -22,7 +22,7 @@ const size_t trials = 10;
using cppa::util::single_reader_queue; using cppa::intrusive::single_reader_queue;
using std::cout; using std::cout;
using std::cerr; using std::cerr;
......
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