Skip to content

Commit

Permalink
logging: implement debug
Browse files Browse the repository at this point in the history
And begin on assert framework.
  • Loading branch information
rHermes committed Apr 20, 2024
1 parent f7143d1 commit 13d70ff
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 14 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,31 @@ It is not stable in **ANY WAY SHAPE OR FORM** and any usage is at your own risk.

## Components

### Core library

This is a core library that is included by most of the other libraries. It includes:

#### Concepts

Some concepts that is useful across applications.

#### Lifetime tester

A very simple lifetime tester, that can be used for quickly testing out move semantics or other.

#### Assert

This is a simple assert library. It's made so that I could learn about the preprocessor. The main
need here is to be able to turn it off during release.



#### TODO

- Implement better documentation. For this libraries to be useful, I will need to have good documentation.
- Think a bit about what kind of dependencies we will require.
- Figure out how to do cmake install.

### Utility library

This is not implemented yet, but here are some components I want:
Expand Down
6 changes: 6 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@

find_package(Threads REQUIRED)

add_executable(compiler_bug_1 compiler_bug_1.cpp)
add_executable(compiler_bug_2 compiler_bug_2.cpp)
add_executable(play play.cpp)

target_link_libraries(compiler_bug_1 PRIVATE Threads::Threads)

# target_compile_options(compiler_bug_1 PRIVATE -pthread)

foreach (target_var IN ITEMS compiler_bug_1 compiler_bug_2 play)
target_compile_features(${target_var} PUBLIC cxx_std_20)
set_target_properties(${target_var} PROPERTIES CXX_EXTENSIONS OFF)
Expand Down
25 changes: 25 additions & 0 deletions include/hage/core/assert.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include "misc.hpp"

#include <utility>
#include <string_view>

namespace hage::detail {
template<typename F> requires std::predicate<F>
void assert(F&& f, std::string_view cond, std::string_view msg) {
if (!std::forward<F>(f)()) {
std::string lel(msg);
std::string cl(cond);
throw std::runtime_error("We got an error during assertion: " +lel + " " + cl);
}
}
}

#ifdef HAGE_DEBUG
#define HAGE_ASSERT(cond,...) HAGE_ASSERT_##__VA_OPT__(1)(cond __VA_OPT__(,)__VA_ARGS__)
#define HAGE_ASSERT_(cond) HAGE_ASSERT_1(cond, "")
#define HAGE_ASSERT_1(cond, msg) hage::detail::assert([&]{ return cond; }, #cond, msg)
#else
#define HAGE_ASSERT(cond,...) void()
#endif
23 changes: 17 additions & 6 deletions include/hage/core/misc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
#include <array>

namespace hage {
namespace details {
namespace detail {
#ifdef __cpp_lib_hardware_interference_size
#include <new>
static constexpr auto constructive_interference_size = std::hardware_constructive_interference_size;
static constexpr auto destructive_interference_size = std::hardware_destructive_interference_size;
inline constexpr auto constructive_interference_size = std::hardware_constructive_interference_size;
inline constexpr auto destructive_interference_size = std::hardware_destructive_interference_size;
#else
// 64 bytes on x86-64 │ L1_CACHE_BYTES │ L1_CACHE_SHIFT │ __cacheline_aligned │ ...
static constexpr std::size_t constructive_interference_size = 64;
static constexpr std::size_t destructive_interference_size = 64;
inline constexpr std::size_t constructive_interference_size = 64;
inline constexpr std::size_t destructive_interference_size = 64;
#endif

}
Expand All @@ -22,5 +22,16 @@ byte_array(T... a)
{
return { static_cast<std::byte>(a)... };
}
// Explanation of the purpose of this template.
// https://artificial-mind.net/blog/2020/10/03/always-false
template <typename...>
constexpr bool dependent_false = false;

};
#if !defined(NDEBUG)
#define HAGE_DEBUG true
inline constexpr bool debug_mode = true;
#else
inline constexpr bool debug_mode = false;
#endif

}
28 changes: 21 additions & 7 deletions include/hage/logging/ring_buffer.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <hage/core/assert.hpp>
#include <hage/core/misc.hpp>

#include "byte_buffer.hpp"
Expand All @@ -18,31 +19,40 @@ namespace hage {
template<std::ptrdiff_t N>
class RingBuffer final : public ByteBuffer
{
static_assert(0 < N, "We don't allow RingBuffers with non positive sizes");

alignas(details::destructive_interference_size) std::atomic<std::ptrdiff_t> m_head{ 0 };
alignas(details::destructive_interference_size) std::ptrdiff_t m_cachedHead{ 0 };
alignas(detail::destructive_interference_size) std::atomic<std::ptrdiff_t> m_head{ 0 };
alignas(detail::destructive_interference_size) std::ptrdiff_t m_cachedHead{ 0 };

alignas(details::destructive_interference_size) std::atomic<std::ptrdiff_t> m_tail{ 0 };
alignas(details::destructive_interference_size) std::ptrdiff_t m_cachedTail{ 0 };
alignas(detail::destructive_interference_size) std::atomic<std::ptrdiff_t> m_tail{ 0 };
alignas(detail::destructive_interference_size) std::ptrdiff_t m_cachedTail{ 0 };

alignas(details::destructive_interference_size) std::array<std::byte, N + 1> m_buff{};
alignas(detail::destructive_interference_size) std::array<std::byte, N + 1> m_buff{};

alignas(details::destructive_interference_size) std::atomic_flag m_hasReader;
alignas(details::destructive_interference_size) std::atomic_flag m_hasWriter;

#ifdef HAGE_DEBUG
alignas(detail::destructive_interference_size) std::atomic_flag m_hasReader;
alignas(detail::destructive_interference_size) std::atomic_flag m_hasWriter;
#endif

class Reader final : public ByteBuffer::Reader
{
public:
explicit Reader(RingBuffer& parent)
: m_parent{ parent }
{

#ifdef HAGE_DEBUG
if (m_parent.m_hasReader.test_and_set(std::memory_order::acq_rel))
throw std::runtime_error("We can only have one concurrent reader for RingBuffer");
#endif

m_shadowHead = m_parent.m_head.load(std::memory_order::relaxed);
}

#ifdef HAGE_DEBUG
~Reader() override { m_parent.m_hasReader.clear(std::memory_order::release); }
#endif

bool read(std::span<std::byte> dst) override
{
Expand Down Expand Up @@ -111,13 +121,17 @@ class RingBuffer final : public ByteBuffer
explicit Writer(RingBuffer& parent)
: m_parent{ parent }
{
#ifdef HAGE_DEBUG
if (m_parent.m_hasWriter.test_and_set(std::memory_order::acq_rel))
throw std::runtime_error("We can only have one concurrent writer for RingBuffer");
#endif

m_shadowTail = m_parent.m_tail.load(std::memory_order::relaxed);
}

#ifdef HAGE_DEBUG
~Writer() override { m_parent.m_hasWriter.clear(std::memory_order::release); }
#endif

bool commit() override
{
Expand Down
13 changes: 13 additions & 0 deletions include/hage/logging/vector_buffer.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <hage/core/misc.hpp>
#include "byte_buffer.hpp"

#include <algorithm>
Expand All @@ -20,8 +21,11 @@ class VectorBuffer final : public ByteBuffer

using index_type = std::ptrdiff_t;


#ifdef HAGE_DEBUG
bool m_hasReader{ false };
bool m_hasWriter{ false };
#endif

index_type m_writeLevel{ 0 };

Expand All @@ -31,18 +35,23 @@ class VectorBuffer final : public ByteBuffer
explicit Reader(VectorBuffer& parent)
: m_parent(parent)
{
#ifdef HAGE_DEBUG
std::scoped_lock lk(m_parent.m_mtx);

if (m_parent.m_hasReader)
throw std::runtime_error("Two readers created, only 1 is supported at a time");

m_parent.m_hasReader = true;
#endif
}

#ifdef HAGE_DEBUG
~Reader() override
{
std::scoped_lock lk(m_parent.m_mtx);
m_parent.m_hasReader = false;
}
#endif

bool read(std::span<std::byte> dst) override
{
Expand Down Expand Up @@ -85,17 +94,21 @@ class VectorBuffer final : public ByteBuffer
explicit Writer(VectorBuffer& parent)
: m_parent(parent)
{
#ifdef HAGE_DEBUG
std::scoped_lock lk(m_parent.m_mtx);
if (m_parent.m_hasWriter)
throw std::runtime_error("Two writers created, only 1 is supported at a time");

m_parent.m_hasWriter = true;
#endif
}

~Writer() override
{
std::scoped_lock lk(m_parent.m_mtx);
#ifdef HAGE_DEBUG
m_parent.m_hasWriter = false;
#endif

m_parent.m_q.erase(std::next(m_parent.m_q.end(), m_parent.m_writeLevel), m_parent.m_q.end());
m_parent.m_writeLevel = 0;
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ set(CORE_HEADER_LIST
"${hage_SOURCE_DIR}/include/hage/core/misc.hpp"
"${hage_SOURCE_DIR}/include/hage/core/lifetime_tester.hpp"
"${hage_SOURCE_DIR}/include/hage/core/concepts.hpp"
"${hage_SOURCE_DIR}/include/hage/core/assert.hpp"
)


Expand Down
5 changes: 4 additions & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ add_executable(hage_test doctest.cpp
ring_buffer_tests.cpp
atomics_tests.cpp)

find_package(Threads REQUIRED)

#target_compile_features(hage_test PUBLIC cxx_std_20)
# set_target_properties(hage_test PROPERTIES CXX_EXTENSIONS OFF)

Expand Down Expand Up @@ -48,7 +50,8 @@ endif ()

# target_compile_definitions(hage_test PRIVATE DOCTEST_CONFIG_SUPER_FAST_ASSERTS)

target_link_libraries(hage_test PRIVATE hage_logging hage_atomic doctest::doctest)
target_link_libraries(hage_test PRIVATE hage_logging hage_atomic doctest::doctest
Threads::Threads)
# add_test(NAME hage_test_test COMMAND hage_test)

include(doctest)
Expand Down
4 changes: 4 additions & 0 deletions tests/logging_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <latch>
#include <thread>

#include <hage/core/misc.hpp>

#include <hage/logging.hpp>
#include <hage/logging/file_sink.hpp>
#include <hage/logging/ring_buffer.hpp>
Expand Down Expand Up @@ -245,6 +247,7 @@ TEST_CASE_TEMPLATE("Single produser, single consumer buffers", BufferType, hage:
BufferType buff;
hage::ByteBuffer& buffer = buff;

#ifdef HAGE_DEBUG
SUBCASE("Creating two readers should throw")
{
auto reader1 = buffer.get_reader();
Expand All @@ -256,6 +259,7 @@ TEST_CASE_TEMPLATE("Single produser, single consumer buffers", BufferType, hage:
auto writer = buffer.get_writer();
REQUIRE_THROWS(std::ignore = buffer.get_writer());
}
#endif
}

TEST_CASE("RingBuffer")
Expand Down

0 comments on commit 13d70ff

Please sign in to comment.