diff --git a/LibSnugLog/CMakeLists.txt b/LibSnugLog/CMakeLists.txt index bbff36e..5a15a16 100644 --- a/LibSnugLog/CMakeLists.txt +++ b/LibSnugLog/CMakeLists.txt @@ -3,6 +3,6 @@ include_directories(./public_include) include_directories(./include) -add_library(LibSnugLog +add_library(SnugLog include/disruptor.h - source/disruptor.cpp include/sink.h include/registry.h include/source.h public_include/sl/strategies.h public_include/sl/register.h public_include/sl/transaction.h source/registry.cpp) \ No newline at end of file + source/disruptor.cpp include/sink.h include/registry.h include/source.h public_include/sl/strategies.h public_include/sl/register.h public_include/sl/transaction.h source/registry.cpp public_include/sl/logger.h source/logger.cpp) \ No newline at end of file diff --git a/LibSnugLog/include/disruptor.h b/LibSnugLog/include/disruptor.h index cdf8bb7..674dc71 100644 --- a/LibSnugLog/include/disruptor.h +++ b/LibSnugLog/include/disruptor.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "sl/strategies.h" @@ -19,13 +20,14 @@ static constexpr size_t line_length = 64; template struct alignas(max_interference_size) padded_atomic final { - std::atomic value; + std::atomic value; }; using offset_t = size_t; extern const size_t page_size; -struct force_contiguous_mode {}; +struct force_contiguous_mode_t {}; +constexpr force_contiguous_mode_t force_contiguous_mode; struct token_t {offset_t start; offset_t end;}; struct disruptor_exception : public std::runtime_error { @@ -41,37 +43,73 @@ class disruptor { char* buffer; size_t buffer_size; - std::atomic& read_trailer; - std::atomic& read_lead; + std::atomic* read_trailer; + std::atomic* read_lead; + std::atomic* write_trailer; + std::atomic* write_lead; - std::atomic& write_trailer; - std::atomic& write_lead; - - offset_t& max_offset; + offset_t* max_offset; char* data_buffer; + std::any buffer_life_extender; + std::any strategy_life_extender; public: + /** + * Constructs a disruptor from the provided strategy, initialization_and_checks() is responsible for the initialization + * @param strategy The provided strategy. The provided strategy is preserved, intact if properly movable and if moving is "pointer stable". The obtained buffer is also preserved under the same supposition. + * @param _buffer_size The total size of the buffer to allocate, keep in mind this includes not only the + */ + template + disruptor(buffer_strategy strategy, std::string_view _buffer_filename, const size_t _buffer_size) + : read_trailer{} + , read_lead{} + , write_trailer{} + , write_lead{} + { + auto tmp = strategy.build_buffer(_buffer_filename, _buffer_size); + buffer = tmp.data(); + buffer_size = tmp.size(); + read_trailer = reinterpret_cast*>(buffer+max_interference_size*0); + read_lead = reinterpret_cast*>(buffer+max_interference_size*1); + write_trailer = reinterpret_cast*>(buffer+max_interference_size*2); + write_lead = reinterpret_cast*>(buffer+max_interference_size*3); + max_offset = reinterpret_cast (buffer+max_interference_size*4); + buffer_life_extender = std::move(tmp); + strategy_life_extender = std::move(strategy); + initialization_and_checks(); + } + + /** + * Constructs a disruptor from the provided memory span, initialization_and_checks() is responsible for the initialization + * @ref initialization_and_checks() + * @param _buffer + * @param _buffer_size + */ disruptor(char* _buffer, const size_t _buffer_size) : buffer(_buffer) , buffer_size(_buffer_size) - , read_trailer (*reinterpret_cast*>(_buffer+max_interference_size*0)) - , read_lead (*reinterpret_cast*>(_buffer+max_interference_size*1)) - , write_trailer(*reinterpret_cast*>(_buffer+max_interference_size*2)) - , write_lead (*reinterpret_cast*>(_buffer+max_interference_size*3)) - , max_offset (*reinterpret_cast (_buffer+max_interference_size*4)) + , read_trailer (reinterpret_cast*>(_buffer+max_interference_size*0)) + , read_lead (reinterpret_cast*>(_buffer+max_interference_size*1)) + , write_trailer(reinterpret_cast*>(_buffer+max_interference_size*2)) + , write_lead (reinterpret_cast*>(_buffer+max_interference_size*3)) + , max_offset (reinterpret_cast (_buffer+max_interference_size*4)) { + initialization_and_checks(); + } + + void initialization_and_checks() { if(buffer_size <= page_size) throw disruptor_exception("buffer size too small to build a disruptor"); data_buffer = buffer+max_interference_size*5; if(data_buffer <= buffer+page_size) { data_buffer = buffer+page_size; - max_offset = buffer_size - page_size; + *max_offset = buffer_size - page_size; } else if(data_buffer > buffer+page_size) { size_t ctr = 0; do { ctr++; } while(data_buffer > buffer+page_size*ctr); data_buffer = buffer+page_size*ctr; - max_offset = buffer_size - page_size*ctr; + *max_offset = buffer_size - page_size*ctr; } } @@ -81,9 +119,9 @@ public: std::atomic& fence, offset_t amount ) { - offset_t old_offset = lead.load(std::memory_order_relaxed); + offset_t old_offset = lead.load(std::memory_order_seq_cst); offset_t new_offset = old_offset + amount; - offset_t fence_v = fence.load(std::memory_order_relaxed); + offset_t fence_v = fence.load(std::memory_order_seq_cst); // Check if we jumped the fence if(fence_v <= new_offset && fence_v > old_offset) { @@ -91,11 +129,11 @@ public: } // Check if we jumped the fence while overflowing - if(new_offset >= max_offset) { + if(new_offset >= *max_offset) { if constexpr(must_be_contiguous) { new_offset = amount; } else { - new_offset %= max_offset; + new_offset %= *max_offset; } if(fence_v <= new_offset) { goto handle_fence; @@ -107,14 +145,14 @@ public: if constexpr (OverflowStrategyType::on_overflow == overflow_response_t::must_wait) { return std::nullopt; } else if constexpr (OverflowStrategyType::on_overflow == overflow_response_t::must_overflow) { - if(!fence.compare_exchange_weak(fence_v, new_offset, std::memory_order_release, std::memory_order_relaxed)) { + if(!fence.compare_exchange_weak(fence_v, new_offset, std::memory_order_seq_cst)) { return std::nullopt; } else { offset_t v; do { - v = read_lead.load(std::memory_order_acquire); + v = read_lead->load(std::memory_order_seq_cst); if(v >= new_offset) break; - } while(read_lead.compare_exchange_weak(v, new_offset, std::memory_order_release, std::memory_order_relaxed)); + } while(read_lead->compare_exchange_weak(v, new_offset, std::memory_order_seq_cst)); } } else { static_assert( @@ -124,7 +162,7 @@ public: } handle_fence_end: - if(!lead.compare_exchange_weak(old_offset, new_offset, std::memory_order_acquire, std::memory_order_relaxed)) { + if(!lead.compare_exchange_weak(old_offset, new_offset, std::memory_order_seq_cst, std::memory_order_seq_cst)) { return std::nullopt; } @@ -135,18 +173,18 @@ public: std::optional tok; OverflowStrategyType waiter; while(true) { - tok = try_advance(write_lead, read_trailer, sz); + tok = try_advance(*write_lead, *read_trailer, sz); if(tok) break; waiter.wait(); } // std::cout << tok.value().start << " rw " << tok.value().end << std::endl; return tok.value(); } - token_t reserve_write(size_t sz, force_contiguous_mode) { + token_t reserve_write(size_t sz, force_contiguous_mode_t) { std::optional tok; OverflowStrategyType waiter; while(true) { - tok = try_advance(write_lead, read_trailer, sz); + tok = try_advance(*write_lead, *read_trailer, sz); if(tok) break; waiter.wait(); } @@ -158,18 +196,18 @@ public: void conclude_write(token_t tok) noexcept(std::is_nothrow_invocable_v) { OverflowStrategyType waiter; - while(!write_trailer.compare_exchange_weak(tok.start, tok.end, std::memory_order_release, std::memory_order_relaxed)) { + while(!write_trailer->compare_exchange_weak(tok.start, tok.end, std::memory_order_seq_cst, std::memory_order_seq_cst)) { waiter.wait(); } } token_t reserve_read() { - offset_t old_offset = read_lead.load(std::memory_order_relaxed); - offset_t new_offset = write_trailer.load(std::memory_order_relaxed); + offset_t old_offset = read_lead->load(std::memory_order_seq_cst); + offset_t new_offset = write_trailer->load(std::memory_order_seq_cst); if(old_offset > new_offset) new_offset = 0; OverflowStrategyType waiter; - while(!read_lead.compare_exchange_weak(old_offset, new_offset, std::memory_order_acquire, std::memory_order_relaxed)) { + while(!read_lead->compare_exchange_weak(old_offset, new_offset, std::memory_order_seq_cst, std::memory_order_seq_cst)) { waiter.wait(); } // std::cout << old_offset << " rr " << new_offset << std::endl; @@ -177,7 +215,7 @@ public: } void conclude_read(token_t tok) noexcept(std::is_nothrow_invocable_v) { OverflowStrategyType waiter; - while(!read_trailer.compare_exchange_weak(tok.start, tok.end, std::memory_order_release, std::memory_order_relaxed)) { + while(!read_trailer->compare_exchange_weak(tok.start, tok.end, std::memory_order_seq_cst, std::memory_order_seq_cst)) { waiter.wait(); } // std::cout << tok.start << " cr " << tok.end << std::endl; @@ -187,7 +225,52 @@ public: return data_buffer[offset]; } + char* data() { + return data_buffer; + } + [[nodiscard]] offset_t size() const { - return max_offset; + return *max_offset; } }; + + +class write_span { + offset_t start, end; + size_t target_sz; + char* target_buffer; +public: + template + write_span(token_t tok, disruptor& _target) + : start(tok.start) + , end(tok.end) + , target_sz(_target.size()) + , target_buffer(_target.data()) + {} +private: + write_span(const write_span& src, size_t ltrim) + : start((src.start + ltrim) % src.target_sz) + , end(src.end) + , target_sz(src.target_sz) + , target_buffer(src.target_buffer) + {} +public: + + char& front() { + return target_buffer[start]; + } + + [[nodiscard]] size_t size() const { + return start <= end ? end - start : end + target_sz - start; + } + + write_span subspan(size_t ltrim) { + if(ltrim > size()) throw disruptor_exception("write_span overflow, ltrim greater than available span"); + + return write_span(*this, ltrim); + } + + [[nodiscard]] bool empty() const { + return end==start; + } +}; \ No newline at end of file diff --git a/LibSnugLog/include/registry.h b/LibSnugLog/include/registry.h index 45dcbb0..500adcc 100644 --- a/LibSnugLog/include/registry.h +++ b/LibSnugLog/include/registry.h @@ -1,3 +1,23 @@ #pragma once +#include +#include +#include +#include +#include "disruptor.h" +struct registry_slab { + int id; + std::string name; + std::function reserve_write; + std::function reserve_write_c_align; + std::function conclude_write; + std::function get_buffer; + std::any disruptor; +}; + +/** + * @internal used because we need the pointer stability + * @see sl_transaction + */ +extern std::unordered_map registry_map; \ No newline at end of file diff --git a/LibSnugLog/public_include/sl/logger.h b/LibSnugLog/public_include/sl/logger.h new file mode 100644 index 0000000..1ea1bc6 --- /dev/null +++ b/LibSnugLog/public_include/sl/logger.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +namespace sl { + void log(int log_id, std::string line); +} \ No newline at end of file diff --git a/LibSnugLog/public_include/sl/register.h b/LibSnugLog/public_include/sl/register.h index 1ee0524..fcbbc1f 100644 --- a/LibSnugLog/public_include/sl/register.h +++ b/LibSnugLog/public_include/sl/register.h @@ -59,103 +59,103 @@ namespace sl { } template -void register_log(std::string_view buffer_filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory); +void register_log(int log_id, std::string_view log_name, std::string_view buffer_filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); -template<> void register_log(std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); +template<> void register_log(int log_id, std::string_view, std::string_view, uint64_t, uint64_t, std::string_view); #else typedef struct sl_buffer_strategy sl_buffer_strategy; typedef struct sl_sink_strategy sl_sink_strategy; diff --git a/LibSnugLog/public_include/sl/strategies.h b/LibSnugLog/public_include/sl/strategies.h index 43d9b63..e029cf7 100644 --- a/LibSnugLog/public_include/sl/strategies.h +++ b/LibSnugLog/public_include/sl/strategies.h @@ -86,8 +86,9 @@ concept BufferLike = requires (T buffer) { * @brief This concept maps a buffer strategy. */ template -concept BufferStrategy = requires (T strategy, size_t size) { - {strategy.build_buffer(size)} -> BufferLike; +concept BufferStrategy = requires (T strategy, std::string_view filename, size_t size) { + {strategy.build_buffer(filename, size)} -> BufferLike; + {strategy.build_buffer(filename, size)} -> std::same_as; }; /** @@ -141,7 +142,7 @@ struct mapped_buffer { struct BufferStrategyInternal { using buffer_type = std::vector; static_assert(BufferLike); - buffer_type build_buffer(size_t); + buffer_type build_buffer(std::string_view, size_t); }; /** @@ -150,7 +151,7 @@ struct BufferStrategyInternal { struct BufferStrategyShared { using buffer_type = mapped_buffer; static_assert(BufferLike); - buffer_type build_buffer(size_t); + buffer_type build_buffer(std::string_view, size_t); }; /** @@ -159,7 +160,7 @@ struct BufferStrategyShared { struct BufferStrategyExternal { using buffer_type = mapped_buffer; static_assert(BufferLike); - buffer_type build_buffer(size_t); + buffer_type build_buffer(std::string_view, size_t); }; /* * ... * */ diff --git a/LibSnugLog/public_include/sl/transaction.h b/LibSnugLog/public_include/sl/transaction.h index 1f2984f..9b2c5a8 100644 --- a/LibSnugLog/public_include/sl/transaction.h +++ b/LibSnugLog/public_include/sl/transaction.h @@ -239,8 +239,8 @@ inline void sl_clear_transaction(sl_log_transaction* to_clear) { to_clear->internals = nullptr; #else to_clear->begin = NULL; - to_clear->end = NULL; - to_clear->internals = NULL; + to_clear->end = NULL; + to_clear->internals = NULL; #endif #endif } diff --git a/LibSnugLog/source/logger.cpp b/LibSnugLog/source/logger.cpp new file mode 100644 index 0000000..a380bfa --- /dev/null +++ b/LibSnugLog/source/logger.cpp @@ -0,0 +1,16 @@ +#include +#include "sl/logger.h" +#include "registry.h" + +namespace sl { + void log(int log_id, std::string line) { + auto& slab = registry_map.at(log_id); + auto token = slab.reserve_write(line.size()); + auto span = slab.get_buffer(token); + for(auto elem : line) { + span.front() = elem; + span = span.subspan(1); + } + slab.conclude_write(token); + } +} \ No newline at end of file diff --git a/LibSnugLog/source/registry.cpp b/LibSnugLog/source/registry.cpp index a1b9758..89bfc9a 100644 --- a/LibSnugLog/source/registry.cpp +++ b/LibSnugLog/source/registry.cpp @@ -8,6 +8,12 @@ #include #include +#if defined(__linux__) || defined(__linux) +#include +#include +#include + +#endif /** * @brief A fast semaphore exclusion handler WITHOUT deadlock detection or yielding @@ -67,10 +73,11 @@ using rw_lock_type = fast_semaphore; class lock_handler_read { rw_lock_type& ref; + +public: explicit lock_handler_read(rw_lock_type& _ref) : ref(_ref) { while(ref.try_lock<1>()); } - ~lock_handler_read() { while(ref.try_unlock<1>() != rw_lock_type::tristate::success); } @@ -78,10 +85,11 @@ class lock_handler_read { class lock_handler_write { rw_lock_type& ref; + +public: explicit lock_handler_write(rw_lock_type& _ref) : ref(_ref) { while(ref.try_lock()); } - ~lock_handler_write() { while(ref.try_unlock() != rw_lock_type::tristate::success); } @@ -89,32 +97,285 @@ class lock_handler_write { static fast_semaphore registry_rw_lock; +std::unordered_map registry_map; -struct registry_slab { - int id; - std::string name; - std::function reserve_write; - std::function reserve_write_c_align; - std::function conclude_write; - std::any disruptor; -}; +template +void register_log_impl(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + if(buffer_size % page_size != 0) { + // TODO: more meaningful exception + throw disruptor_exception{"Size provided for the disruptor doesn't align with page size"}; + } + lock_handler_write lock_me{registry_rw_lock}; + + if(registry_map.contains(log_id)) { + // TODO: more meaningful exception + throw disruptor_exception{"Log ID already exists"}; + } + + registry_map.insert(std::pair{log_id, {}}); + auto& slab = registry_map[log_id]; + slab.id = log_id; + slab.name = log_name; + auto* transient_reference = new disruptor(buff_strat{}, filename, buffer_size); + slab.disruptor = transient_reference; + slab.reserve_write = [ptr = transient_reference] (size_t sz) -> token_t{ + return ptr->reserve_write(sz); + }; + slab.reserve_write_c_align = [ptr = transient_reference] (size_t sz) -> token_t{ + return ptr->reserve_write(sz, force_contiguous_mode); + }; + slab.conclude_write = [ptr = transient_reference] (token_t tok) -> void { + ptr->conclude_write(tok); + }; + slab.get_buffer = [self = slab, ptr = transient_reference] (token_t tok) -> write_span { + return write_span(tok, *ptr); + }; +} -/** - * @internal used because we need the pointer stability - * @see sl_transaction - */ -static std::unordered_map registry_map; +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} +template<> void register_log(int log_id, std::string_view log_name, std::string_view filename, uint64_t buffer_size, uint64_t out_strategy_parameter, std::string_view output_directory) { + register_log_impl(log_id, log_name, filename, buffer_size, out_strategy_parameter, output_directory); +} -BufferStrategyInternal::buffer_type BufferStrategyInternal::build_buffer(size_t) { - return {}; +BufferStrategyInternal::buffer_type BufferStrategyInternal::build_buffer(std::string_view, size_t sz) { + return std::vector(sz, 0); } -BufferStrategyShared::buffer_type BufferStrategyShared::build_buffer(size_t) { - return {}; +BufferStrategyShared::buffer_type BufferStrategyShared::build_buffer(std::string_view, size_t sz) { +#if defined(__linux__) || defined(__linux) + auto buff = mmap(nullptr, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0); + if(not buff) throw disruptor_exception{"Could not allocate memory for BufferStrategyShared"}; + return {(char*)buff, sz}; +#else + static_assert(false, "BufferStrategyShared strategy is unimplemented on your system"); +#endif } -BufferStrategyExternal::buffer_type BufferStrategyExternal::build_buffer(size_t) { - return {}; +BufferStrategyExternal::buffer_type BufferStrategyExternal::build_buffer(std::string_view filename, size_t sz) { +#if defined(__linux__) || defined(__linux) + auto fd = open(std::string{filename}.c_str(), O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + if(fd <= 0) throw disruptor_exception{"Could not open or create file for BufferStrategyExternal"}; + if(ftruncate(fd, sz) != 0) throw disruptor_exception{"Could not ensure size for the file for BufferStrategyExternal"}; + auto buff = mmap(nullptr, sz, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0); + if(not buff) { + throw disruptor_exception{"Could not allocate memory for BufferStrategyExternal, mapping failed"}; + } + return {(char*)buff, sz}; +#else + static_assert(false, "BufferStrategyExternal strategy is unimplemented on your system"); +#endif } void SinkStrategyDirect::write(int fd, std::string_view data) { diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index dce8f89..92139a6 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -11,7 +11,7 @@ FetchContent_Declare( FetchContent_MakeAvailable(Catch2) add_executable(tests disruptor.cpp) -target_link_libraries(tests PRIVATE LibSnugLog) +target_link_libraries(tests PRIVATE SnugLog) target_link_libraries(tests PRIVATE Catch2::Catch2WithMain) include_directories(../LibSnugLog/public_include) diff --git a/Tests/disruptor.cpp b/Tests/disruptor.cpp index b390760..b8d47a9 100644 --- a/Tests/disruptor.cpp +++ b/Tests/disruptor.cpp @@ -135,19 +135,19 @@ TEST_CASE("Disruptor works sequentially") { } } -TEST_CASE("Fails if buffer too small") { +TEST_CASE("Fails if buffer too small - 1") { REQUIRE_THROWS_AS(disruptor(nullptr, page_size), disruptor_exception); } -TEST_CASE("Fails if buffer size is 0") { +TEST_CASE("Fails if buffer size is 0 - 1") { REQUIRE_THROWS_AS(disruptor(nullptr, 0), disruptor_exception); } -TEST_CASE("Fails if buffer too small") { +TEST_CASE("Fails if buffer too small - 2") { REQUIRE_THROWS_AS(disruptor(nullptr, page_size), disruptor_exception); } -TEST_CASE("Fails if buffer size is 0") { +TEST_CASE("Fails if buffer size is 0 - 2") { REQUIRE_THROWS_AS(disruptor(nullptr, 0), disruptor_exception); }