### Find and Link Boost Libraries (CMake) Source: https://github.com/bytemaster/disruptor/blob/master/CMakeLists.txt This CMake snippet finds the Boost libraries (version 1.51 or later) and specifies the required components. It then includes the Boost include directory for the project. It assumes Boost is installed and discoverable by CMake. ```cmake SET( BUILD_SHARED_LIBS NO ) SET(Boost_USE_STATIC_LIBS ON) FIND_PACKAGE(Boost 1.51 components thread date_time system filesystem program_options signals serialization chrono unit_test_framework context ) include_directories( ${Boost_INCLUDE_DIR} ) ``` -------------------------------- ### C++ Disruptor Pipeline: Producer-Squarer-Cuber Source: https://context7.com/bytemaster/disruptor/llms.txt Implements a three-stage processing pipeline using the Disruptor pattern in C++. It chains a producer, a squaring stage, and a cubing stage, demonstrating how cursors can follow dependencies to create a processing chain. This example utilizes ring buffers and read/write cursors for efficient data flow between stages. ```cpp #include #include #include #define SIZE 1024 auto source = std::make_shared>(); auto squared = std::make_shared>(); auto cubed = std::make_shared>(); auto producer_cur = std::make_shared("producer", SIZE); auto square_cur = std::make_shared("squarer"); auto cube_cur = std::make_shared("cuber"); // Set up pipeline dependencies square_cur->follows(producer_cur); // Squarer reads from producer cube_cur->follows(square_cur); // Cuber reads from squarer producer_cur->follows(cube_cur); // Producer waits for end of pipeline // Producer: generates numbers std::thread producer([=]() { auto pos = producer_cur->begin(); auto end = producer_cur->end(); for (uint64_t i = 0; i < 100000; ++i) { if (pos >= end) { end = producer_cur->wait_for(end); } source->at(pos) = i; producer_cur->publish(pos); ++pos; } producer_cur->set_eof(); }); // Stage 1: squares numbers std::thread squarer([=]() { try { auto pos = square_cur->begin(); auto end = square_cur->end(); while (true) { if (pos == end) { square_cur->publish(pos - 1); end = square_cur->wait_for(end); } int64_t val = source->at(pos); squared->at(pos) = val * val; ++pos; } } catch (const disruptor::eof&) {} }); // Stage 2: cubes squared numbers std::thread cuber([=]() { try { auto pos = cube_cur->begin(); auto end = cube_cur->end(); while (true) { if (pos == end) { cube_cur->publish(pos - 1); end = cube_cur->wait_for(end); } int64_t sq = squared->at(pos); cubed->at(pos) = sq * source->at(pos); // sq * val = val^3 ++pos; } } catch (const disruptor::eof&) { std::cout << "Processed 100000 items" << std::endl; } }); producer.join(); squarer.join(); cuber.join(); ``` -------------------------------- ### Exception Propagation via Alert Mechanism (C++) Source: https://context7.com/bytemaster/disruptor/llms.txt Illustrates using the disruptor's alert mechanism for exception propagation. When a cursor encounters an error, it can set an alert that is thrown to waiting cursors, facilitating clean shutdown and error handling in complex pipelines. This example involves producer and consumer threads managing a ring buffer. ```cpp #include #include #include #define SIZE 1024 auto buffer = std::make_shared>(); auto write_cur = std::make_shared("producer", SIZE); auto read_cur = std::make_shared("consumer"); write_cur->follows(read_cur); read_cur->follows(write_cur); std::thread consumer([=]() { try { auto pos = read_cur->begin(); auto end = read_cur->end(); while (true) { if (pos == end) { read_cur->publish(pos - 1); end = read_cur->wait_for(end); // Will throw if producer sets alert } int64_t value = buffer->at(pos); // Simulate error condition if (value == 12345) { throw std::runtime_error("Invalid value encountered"); } ++pos; } } catch (const std::exception& e) { // Set alert to notify producer read_cur->set_alert(std::current_exception()); std::cerr << "Consumer error: " << e.what() << std::endl; } }); std::thread producer([=]() { try { auto pos = write_cur->begin(); auto end = write_cur->end(); for (uint64_t i = 0; i < 100000; ++i) { if (pos >= end) { end = write_cur->wait_for(end); // Will throw if consumer sets alert } buffer->at(pos) = i; write_cur->publish(pos); ++pos; } write_cur->set_eof(); } catch (const std::exception& e) { std::cerr << "Producer notified of error: " << e.what() << std::endl; } }); producer.join(); consumer.join(); ``` -------------------------------- ### CMake: Boost Library Integration Source: https://github.com/bytemaster/disruptor/blob/master/fc2/CMakeLists.txt Configures the build to use static Boost libraries, specifies the minimum required Boost version (1.53), and lists components to find. It then includes the Boost include directory. ```cmake set( BUILD_SHARED_LIBS NO ) set(Boost_USE_STATIC_LIBS ON) find_package(Boost 1.53 COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework context coroutine ) include_directories( ${Boost_INCLUDE_DIR} ) ``` -------------------------------- ### CMake: Library and Executable Definitions Source: https://github.com/bytemaster/disruptor/blob/master/fc2/CMakeLists.txt Defines a static library named 'fc' with source files from the 'src' directory. It also defines an executable 'fiber_test' and links it with the 'fc' library and specific Boost libraries. ```cmake include_directories( include ) add_library( fc STATIC src/future.cpp src/fiber.cpp # src/thread.cpp ) add_executable( fiber_test examples/fiber_test.cpp ) target_link_libraries( fiber_test fc ${Boost_THREAD_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_CONTEXT_LIBRARY} ) ``` -------------------------------- ### CMake: Project and C++ Standard Configuration Source: https://github.com/bytemaster/disruptor/blob/master/fc2/CMakeLists.txt Configures the CMake project name, minimum required version, and C++ standard (C++0x) with compiler flags for both Unix-like and Windows systems. Flags include Wall and Wno-unused-local-typedefs. ```cmake project( fc ) cmake_minimum_required(VERSION 2.8) if( NOT WIN32 ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall -Wno-unused-local-typedefs" ) else() endif( NOT WIN32 ) ``` -------------------------------- ### Define Library and Executable Targets (CMake) Source: https://github.com/bytemaster/disruptor/blob/master/CMakeLists.txt This CMake code defines a static library named 'disruptor' compiled from 'thread.cpp'. It also defines two executable targets, 'test' from 'test.cpp' and 'pingpong' from 'pingpong.cpp', and links the 'pingpong' executable with the 'disruptor' library and specific Boost libraries. ```cmake add_library( disruptor STATIC thread.cpp ) add_executable( test test.cpp ) add_executable( pingpong pingpong.cpp) target_link_libraries( pingpong disruptor ${Boost_THREAD_LIBRARY} ${Boost_SYSTEM_LIBRARY} ) ``` -------------------------------- ### write_cursor - Manage Single-Producer Write Position and Buffer Overwrites Source: https://context7.com/bytemaster/disruptor/llms.txt Illustrates how to use a write_cursor to track the write position in a ring buffer and coordinate with read cursors to prevent overwrites. It maintains a safe write range and automatically waits when the buffer is full, ensuring data is consumed before being overwritten. Publishes data to make it visible to readers and signals the end of the stream. ```cpp #include #include #define BUFFER_SIZE 1024 auto buffer = std::make_shared>(); auto write_cur = std::make_shared("producer", BUFFER_SIZE); auto read_cur = std::make_shared("consumer"); // Set up dependencies: write cursor follows read cursor to prevent overwrites write_cur->follows(read_cur); read_cur->follows(write_cur); // Producer thread std::thread producer([=]() { try { auto pos = write_cur->begin(); // Start at position 0 auto end = write_cur->end(); // Initially BUFFER_SIZE for (uint64_t i = 0; i < 1000000; ++i) { // Wait if buffer is full if (pos >= end) { end = write_cur->wait_for(end); // Blocks until space available } buffer->at(pos) = i; write_cur->publish(pos); // Make data visible to readers ++pos; } write_cur->set_eof(); // Signal end of stream } catch (const disruptor::eof& e) { std::cerr << "Producer stopped: " << e.what() << std::endl; } }); producer.join(); ``` -------------------------------- ### Read Cursor: Track Consumer Position and Wait for Data (C++) Source: https://context7.com/bytemaster/disruptor/llms.txt The read_cursor tracks the consumer's position in a ring buffer and blocks when waiting for new data. It follows write cursors or other read cursors to ensure data safety and uses progressive backoff when waiting. Requires the disruptor library and a ring buffer. ```cpp #include #include #define BUFFER_SIZE 1024 auto buffer = std::make_shared>(); auto write_cur = std::make_shared("producer", BUFFER_SIZE); auto read_cur = std::make_shared("consumer"); write_cur->follows(read_cur); read_cur->follows(write_cur); // Consumer thread std::thread consumer([=]() { try { auto pos = read_cur->begin(); // Start at position 0 auto end = read_cur->end(); // Initially 0 (nothing available) while (true) { // Wait for new data if caught up if (pos == end) { read_cur->publish(pos - 1); // Notify producers of progress end = read_cur->wait_for(end); // Blocks until data available } int64_t value = buffer->at(pos); // Process the value... ++pos; } } catch (const disruptor::eof& e) { std::cerr << "Consumer reached end: " << e.what() << std::endl; } }); consumer.join(); ``` -------------------------------- ### ring_buffer - Create and Access Lock-Free Circular Buffer Source: https://context7.com/bytemaster/disruptor/llms.txt Demonstrates the creation and usage of a fixed-size, lock-free circular buffer. The buffer size must be a power of 2 for efficient bitwise operations. Elements are accessed via 64-bit monotonically increasing positions, with automatic wrapping. Supports complex event types. ```cpp #include // Create a ring buffer with 1024 slots for int64_t values auto buffer = std::make_shared>(); // Write to the buffer using position-based indexing buffer->at(0) = 42; buffer->at(1) = 100; buffer->at(1024) = 999; // Automatically wraps to index 0 // Read from the buffer int64_t value = buffer->at(0); // Returns 999 (wrapped position) // Check buffer properties int64_t size = buffer->get_buffer_size(); // Returns 1024 int64_t index = buffer->get_buffer_index(1025); // Returns 1 (1025 & 1023) // Complex event types work too struct Event { uint64_t id; double value; char data[256]; }; auto event_buffer = std::make_shared>(); event_buffer->at(10).id = 42; event_buffer->at(10).value = 3.14; ``` -------------------------------- ### Shared Write Cursor: Multi-Producer Coordination and Ordered Publishing (C++) Source: https://context7.com/bytemaster/disruptor/llms.txt The shared_write_cursor allows multiple producer threads to safely write to a ring buffer using atomic claim operations. It ensures sequential consistency by using publish_after(), which waits for prior slots to be published. Requires the disruptor library and a ring buffer. ```cpp #include #include #include #define BUFFER_SIZE 1024 auto buffer = std::make_shared>(); auto write_cur = std::make_shared("multi-producer", BUFFER_SIZE); auto read_cur = std::make_shared("consumer"); write_cur->follows(read_cur); read_cur->follows(write_cur); // Multiple producer threads auto producer = [=](int thread_id, uint64_t count) { try { for (uint64_t i = 0; i < count; ++i) { // Atomically claim 1 slot in the buffer int64_t slot = write_cur->claim(1); // Write to the claimed slot buffer->at(slot) = (thread_id * 1000000) + i; // Publish after previous slot is published (maintains order) write_cur->publish_after(slot, slot - 1); } } catch (const std::exception& e) { std::cerr << "Producer " << thread_id << " error: " << e.what() << std::endl; } }; // Launch 4 producer threads std::vector producers; for (int i = 0; i < 4; ++i) { producers.emplace_back(producer, i, 250000); } for (auto& t : producers) { t.join(); } write_cur->set_eof(); ``` -------------------------------- ### Set C++ Flags Conditionally (CMake) Source: https://github.com/bytemaster/disruptor/blob/master/CMakeLists.txt This snippet sets C++ compiler flags based on the operating system. For non-Windows systems, it enables C++0x standard and specific warnings. It includes conditional logic for platform-specific configurations. ```cmake if( NOT WIN32 ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall -Wno-unused-local-typedefs" ) else() endif( NOT WIN32 ) ``` -------------------------------- ### C++ Disruptor Thread: High-Performance Functor Dispatch Source: https://context7.com/bytemaster/disruptor/llms.txt Demonstrates the use of the disruptor::thread class for ultra-fast inter-thread communication by posting functors to a background thread. It highlights single-producer and multi-producer posting methods, emphasizing in-place functor construction for performance. This class leverages an internal disruptor ring buffer for efficient dispatch. ```cpp #include #include // Create a background worker thread auto worker = new disruptor::thread(); worker->start(); // Single-producer posting (fastest) worker->post([=]() { std::cout << "Task executed on worker thread" << std::endl; }); // Multi-producer posting (thread-safe) auto producer1 = std::thread([=]() { for (int i = 0; i < 1000; ++i) { worker->atomic_post([=]() { std::cout << "Producer 1, task " << i << std::endl; }); } }); auto producer2 = std::thread([=]() { for (int i = 0; i < 1000; ++i) { worker->atomic_post([=]() { std::cout << "Producer 2, task " << i << std::endl; }); } }); producer1.join(); producer2.join(); // Shutdown worker->stop(); worker->join(); delete worker; ``` -------------------------------- ### Manage Multiple Read Cursors in a Single Thread (C++) Source: https://context7.com/bytemaster/disruptor/llms.txt Demonstrates how to use the disruptor::thread class to manage multiple read cursors, allowing sequential processing of events from different sources within a single thread. This pattern avoids locking for shared state access. Input is event data from ring buffers, output is processed event data and console output. ```cpp #include #include // Create data sources auto buffer1 = std::make_shared>(); auto buffer2 = std::make_shared>(); auto write_cur1 = std::make_shared("w1", 256); auto write_cur2 = std::make_shared("w2", 256); auto read_cur1 = std::make_shared("r1"); auto read_cur2 = std::make_shared("r2"); read_cur1->follows(write_cur1); read_cur2->follows(write_cur2); write_cur1->follows(read_cur1); write_cur2->follows(read_cur2); // Create worker thread auto worker = new disruptor::thread(); // Add custom cursor handlers worker->add_cursor(read_cur1, [=](int64_t begin, int64_t end) -> int64_t { // Process events from buffer1 for (int64_t pos = begin; pos < end; ++pos) { int64_t value = buffer1->at(pos); std::cout << "Buffer1[" << pos << "] = " << value << std::endl; } return end; // Processed all events }); worker->add_cursor(read_cur2, [=](int64_t begin, int64_t end) -> int64_t { // Process events from buffer2 (can access shared state safely) for (int64_t pos = begin; pos < end; ++pos) { double value = buffer2->at(pos); std::cout << "Buffer2[" << pos << "] = " << value << std::endl; } return end; }); worker->start(); // Producers write to buffers (in other threads) // ... worker->stop(); worker->join(); delete worker; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.