From 7396de1f0d990bc618efbf67fcf8fab7aa8a2cab Mon Sep 17 00:00:00 2001 From: E Sequeira <5458743+geseq@users.noreply.github.com> Date: Mon, 25 Dec 2023 14:33:32 +0000 Subject: [PATCH 1/2] add github workflow --- .github/workflows/cmake.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/cmake.yml diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 0000000..c0b91f2 --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,36 @@ +name: CMake + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Debug + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. + # You can convert this to a matrix build if you need cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Configure CMake + # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. + # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DENABLE_TESTING=ON + + - name: Build + # Build your program with the given configuration + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + + - name: Test + # Build your program with the given configuration + run: | + cd build + ctest -C ${{env.BUILD_TYPE}} -L test --force-new-test-process -V --timeout 1800 From 962b5cd017f39804ae4c180b939f29afa2041469 Mon Sep 17 00:00:00 2001 From: E Sequeira <5458743+geseq@users.noreply.github.com> Date: Mon, 25 Dec 2023 15:39:14 +0000 Subject: [PATCH 2/2] cleanup --- CMakeLists.txt | 4 ---- include/orderbook.hpp | 9 +++++---- include/orderqueue.hpp | 11 ++++++----- test/orderbook_test.cpp | 8 ++++---- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d02744..3cc3870 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,10 +4,6 @@ set(CPP_ORDERBOOK orderbook) project(${CPP_ORDERBOOK} LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_COMPILER "/usr/bin/clang++") -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -std=c++20 -stdlib=libc++ -lc++abi") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -stdlib=libc++") - set(CMAKE_THREAD_LIBS_INIT "-lpthread") set(CMAKE_HAVE_THREADS_LIBRARY ON) diff --git a/include/orderbook.hpp b/include/orderbook.hpp index 60c6723..3a28a14 100644 --- a/include/orderbook.hpp +++ b/include/orderbook.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -48,9 +49,9 @@ class OrderBook { Notification& notification_; - std::atomic_uint64_t last_token_ = 0; + std::atomic last_token_ = 0; - std::atomic_uint64_t matching_ = 1; + std::atomic matching_ = 1; Decimal cancelOrder(OrderID id); void addTrigOrder(OrderID id, Type type, Side side, Decimal qty, Decimal price, Decimal trigPrice, Flag flag); @@ -63,7 +64,7 @@ class OrderBook { template void OrderBook::addOrder(uint64_t tok, OrderID id, Type type, Side side, Decimal qty, Decimal price, Decimal trigPrice, Flag flag) { uint64_t exp = tok - 1; // technically this should always be single threaded, but just in case. - if (!last_token_.compare_exchange_strong(exp, tok)) { + if (!last_token_.compare_exchange_strong(exp, tok, std::memory_order_acq_rel, std::memory_order_acquire)) { throw std::invalid_argument("invalid token received: cannot maintain determinism"); } @@ -72,7 +73,7 @@ void OrderBook::addOrder(uint64_t tok, OrderID id, Type type, Side return; } - if (!matching_) { + if (!matching_.load(std::memory_order_acquire)) { if (type == Type::Market) { notification_.putOrder(MsgType::CreateOrder, OrderStatus::Rejected, id, qty, Error::NoMatching); } diff --git a/include/orderqueue.hpp b/include/orderqueue.hpp index 20765c1..80efbee 100644 --- a/include/orderqueue.hpp +++ b/include/orderqueue.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "boost/intrusive/set_hook.hpp" #include "order.hpp" @@ -19,12 +20,12 @@ class OrderQueue : public boost::intrusive::set_base_hook> ob; - std::atomic_uint64_t tok = 0; + std::atomic tok = 0; void SetUp() override { tok = 0; @@ -19,7 +19,7 @@ class LimitOrderTest : public ::testing::Test { void TearDown() override {} - void processLine(std::shared_ptr> ob, const std::string& line) { + void processLine(std::shared_ptr>& ob, const std::string& line) { std::vector parts; boost::split(parts, line, boost::is_any_of("\t")); if (parts.empty()) { @@ -44,7 +44,7 @@ class LimitOrderTest : public ::testing::Test { ob->addOrder(++tok, oid, type, side, qty, price, trigPrice, flag); } - void processOrders(std::shared_ptr> ob, const std::string& input, int prefix) { + void processOrders(std::shared_ptr>& ob, const std::string& input, int prefix) { std::stringstream ss(input); std::string line; @@ -60,7 +60,7 @@ class LimitOrderTest : public ::testing::Test { } } - void addDepth(std::shared_ptr> ob, int prefix = 0) { + void addDepth(std::shared_ptr>& ob, int prefix = 0) { const static std::string depth = R"( # add depth to the orderbook 1 L B 2 50 0 N