Commit 0adde1a1 authored by Dominik Charousset's avatar Dominik Charousset

Rename detail::{ringbuffer => sync_ring_buffer}

parent bb22e7fe
......@@ -135,6 +135,7 @@ caf_add_component(
caf/detail/stream_bridge.cpp
caf/detail/stringification_inspector.cpp
caf/detail/sync_request_bouncer.cpp
caf/detail/sync_ring_buffer.test.cpp
caf/detail/test_actor_clock.cpp
caf/detail/thread_safe_actor_clock.cpp
caf/detail/type_id_list_builder.cpp
......@@ -273,7 +274,6 @@ caf_add_component(
detail.parser.read_timespan
detail.parser.read_unsigned_integer
detail.private_thread_pool
detail.ringbuffer
detail.type_id_list_builder
detail.unique_function
dictionary
......
......@@ -13,14 +13,14 @@
namespace caf::detail {
// A ringbuffer designed for a single consumer and any number of producers that
// can hold a maximum of `Size - 1` elements.
// A ring buffer backed by an array for a single consumer and any number of
// producers that can hold a maximum of `Size - 1` elements.
template <class T, size_t Size>
class ringbuffer {
class sync_ring_buffer {
public:
using guard_type = std::unique_lock<std::mutex>;
ringbuffer() : wr_pos_(0), rd_pos_(0) {
sync_ring_buffer() : wr_pos_(0), rd_pos_(0) {
// nop
}
......
......@@ -2,23 +2,23 @@
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#define CAF_SUITE detail.ringbuffer
#include "caf/detail/sync_ring_buffer.hpp"
#include "caf/detail/ringbuffer.hpp"
#include "core-test.hpp"
#include "caf/test/caf_test_main.hpp"
#include "caf/test/test.hpp"
#include <algorithm>
#include <vector>
using namespace caf;
namespace {
static constexpr size_t buf_size = 64;
constexpr size_t int_buffer_size = 64;
using int_ringbuffer = detail::ringbuffer<int, buf_size>;
using int_buffer = detail::sync_ring_buffer<int, int_buffer_size>;
std::vector<int> consumer(int_ringbuffer& buf, size_t num) {
std::vector<int> consumer(int_buffer& buf, size_t num) {
std::vector<int> result;
for (size_t i = 0; i < num; ++i) {
buf.wait_nonempty();
......@@ -28,48 +28,45 @@ std::vector<int> consumer(int_ringbuffer& buf, size_t num) {
return result;
}
void producer(int_ringbuffer& buf, int first, int last) {
void producer(int_buffer& buf, int first, int last) {
for (auto i = first; i != last; ++i)
buf.push_back(std::move(i));
}
struct fixture {
int_ringbuffer buf;
};
} // namespace
BEGIN_FIXTURE_SCOPE(fixture)
CAF_TEST(construction) {
CHECK_EQ(buf.empty(), true);
CHECK_EQ(buf.full(), false);
CHECK_EQ(buf.size(), 0u);
TEST("a default-constructed ring buffer is empty") {
int_buffer buf;
check(buf.empty());
check(!buf.full());
check_eq(buf.size(), 0u);
}
CAF_TEST(push_back) {
MESSAGE("add one element");
TEST("push_back adds one element to the ring buffer") {
int_buffer buf;
info("add one element");
buf.push_back(42);
CHECK_EQ(buf.empty(), false);
CHECK_EQ(buf.full(), false);
CHECK_EQ(buf.size(), 1u);
CHECK_EQ(buf.front(), 42);
MESSAGE("remove element");
check(!buf.empty());
check(!buf.full());
check_eq(buf.size(), 1u);
check_eq(buf.front(), 42);
info("remove element");
buf.pop_front();
CHECK_EQ(buf.empty(), true);
CHECK_EQ(buf.full(), false);
CHECK_EQ(buf.size(), 0u);
MESSAGE("fill buffer");
for (int i = 0; i < static_cast<int>(buf_size - 1); ++i)
check(buf.empty());
check(!buf.full());
check_eq(buf.size(), 0u);
info("fill buffer");
for (int i = 0; i < static_cast<int>(int_buffer_size - 1); ++i)
buf.push_back(std::move(i));
CHECK_EQ(buf.empty(), false);
CHECK_EQ(buf.full(), true);
CHECK_EQ(buf.size(), buf_size - 1);
CHECK_EQ(buf.front(), 0);
check(!buf.empty());
check(buf.full());
check_eq(buf.size(), int_buffer_size - 1);
check_eq(buf.front(), 0);
}
CAF_TEST(get all) {
using array_type = std::array<int, buf_size>;
TEST("get_all returns all elements from the ring buffer") {
int_buffer buf;
using array_type = std::array<int, int_buffer_size>;
using vector_type = std::vector<int>;
array_type tmp;
auto fetch_all = [&] {
......@@ -77,44 +74,45 @@ CAF_TEST(get all) {
auto e = buf.get_all(i);
return vector_type(i, e);
};
MESSAGE("add five element");
info("add five element");
for (int i = 0; i < 5; ++i)
buf.push_back(std::move(i));
CHECK_EQ(buf.empty(), false);
CHECK_EQ(buf.full(), false);
CHECK_EQ(buf.size(), 5u);
CHECK_EQ(buf.front(), 0);
MESSAGE("drain elements");
CHECK_EQ(fetch_all(), vector_type({0, 1, 2, 3, 4}));
CHECK_EQ(buf.empty(), true);
CHECK_EQ(buf.full(), false);
CHECK_EQ(buf.size(), 0u);
MESSAGE("add 60 elements (wraps around)");
check(!buf.empty());
check(!buf.full());
check_eq(buf.size(), 5u);
check_eq(buf.front(), 0);
info("drain elements");
check_eq(fetch_all(), vector_type({0, 1, 2, 3, 4}));
check(buf.empty());
check(!buf.full());
check_eq(buf.size(), 0u);
info("add 60 elements (wraps around)");
vector_type expected;
for (int i = 0; i < 60; ++i) {
expected.push_back(i);
buf.push_back(std::move(i));
}
CHECK_EQ(buf.size(), 60u);
CHECK_EQ(fetch_all(), expected);
CHECK_EQ(buf.empty(), true);
CHECK_EQ(buf.full(), false);
CHECK_EQ(buf.size(), 0u);
check_eq(buf.size(), 60u);
check_eq(fetch_all(), expected);
check(buf.empty());
check(!buf.full());
check_eq(buf.size(), 0u);
}
CAF_TEST(concurrent access) {
TEST("sync_ring_buffer can be used with multiple producers") {
int_buffer buf;
std::vector<std::thread> producers;
producers.emplace_back(producer, std::ref(buf), 0, 100);
producers.emplace_back(producer, std::ref(buf), 100, 200);
producers.emplace_back(producer, std::ref(buf), 200, 300);
auto vec = consumer(buf, 300);
std::sort(vec.begin(), vec.end());
CHECK(std::is_sorted(vec.begin(), vec.end()));
CHECK_EQ(vec.size(), 300u);
CHECK_EQ(vec.front(), 0);
CHECK_EQ(vec.back(), 299);
check(std::is_sorted(vec.begin(), vec.end()));
check_eq(vec.size(), 300u);
check_eq(vec.front(), 0);
check_eq(vec.back(), 299);
for (auto& t : producers)
t.join();
}
END_FIXTURE_SCOPE()
CAF_TEST_MAIN()
......@@ -8,7 +8,7 @@
#include "caf/actor_clock.hpp"
#include "caf/actor_control_block.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/ringbuffer.hpp"
#include "caf/detail/sync_ring_buffer.hpp"
#include "caf/fwd.hpp"
#include <memory>
......@@ -58,7 +58,7 @@ private:
// -- member variables -------------------------------------------------------
/// Communication to the dispatcher thread.
detail::ringbuffer<schedule_entry_ptr, buffer_size> queue_;
detail::sync_ring_buffer<schedule_entry_ptr, buffer_size> queue_;
/// Handle to the dispatcher thread.
std::thread dispatcher_;
......
......@@ -12,8 +12,8 @@
#include "caf/detail/log_level.hpp"
#include "caf/detail/pp.hpp"
#include "caf/detail/pretty_type_name.hpp"
#include "caf/detail/ringbuffer.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/sync_ring_buffer.hpp"
#include "caf/fwd.hpp"
#include "caf/intrusive/drr_queue.hpp"
#include "caf/intrusive/fifo_inbox.hpp"
......@@ -339,7 +339,7 @@ private:
std::fstream file_;
// Filled with log events by other threads.
detail::ringbuffer<event, queue_size> queue_;
detail::sync_ring_buffer<event, queue_size> queue_;
// Stores the assembled name of the log file.
std::string file_name_;
......
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