Skip to content

Commit a44d3f9

Browse files
committed
Merge remote-tracking branch 'origin/master' into stats-box
2 parents 8e8d848 + d473151 commit a44d3f9

19 files changed

Lines changed: 342 additions & 140 deletions

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ SYMBOLS=BTCUSDT,
1010
# CPU PINNING
1111
PX_SESSION_CPU=0
1212
TX_SESSION_CPU=1
13+
# CPU ISOLATION
14+
CPU_SET_NAME=tradercpp
15+
CPU_SET_RANGE="0-1"

.github/workflows/nightly_bench.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
build_and_test:
1212
runs-on: ubuntu-latest
1313
container:
14-
image: ghcr.io/milsanore/tradercppbuild:v1.7
14+
image: ghcr.io/milsanore/tradercppbuild:v1.8
1515
# set resource limits for some consistency
1616
options: --memory=7g --cpus=2
1717
steps:
@@ -57,3 +57,7 @@ jobs:
5757
GITHUB_REF_NAME: ${{ github.ref_name }}
5858
BENCH_SOURCE: github-actions
5959
run: python3 scripts/upload_to_influx.py
60+
61+
- name: Prune Conan cache
62+
run: |
63+
conan cache clean --build

.github/workflows/release.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
build_release:
1212
runs-on: ubuntu-latest
1313
container:
14-
image: ghcr.io/milsanore/tradercppbuild:v1.7
14+
image: ghcr.io/milsanore/tradercppbuild:v1.8
1515
steps:
1616
- name: Checkout repository
1717
uses: actions/checkout@v4
@@ -41,3 +41,7 @@ jobs:
4141
with:
4242
files: build/Release/tradercpp
4343
token: ${{ secrets.PAT_RELEASE_20261020 }}
44+
45+
- name: Prune Conan cache
46+
run: |
47+
conan cache clean --build

.github/workflows/reusable_build.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
build_and_test:
1717
runs-on: ubuntu-latest
1818
container:
19-
image: ghcr.io/milsanore/tradercppbuild:v1.7
19+
image: ghcr.io/milsanore/tradercppbuild:v1.8
2020
steps:
2121
- name: Checkout repository
2222
uses: actions/checkout@v4
@@ -26,6 +26,9 @@ jobs:
2626
- name: clang-format
2727
run: hooks/check_clang_format.sh
2828

29+
- name: shellcheck
30+
run: hooks/check_shell.sh
31+
2932
- name: Restore Conan cache
3033
uses: actions/cache@v4
3134
with:
@@ -48,7 +51,7 @@ jobs:
4851
- name: Test
4952
run: |
5053
set -e
51-
ctest -j$(nproc) --preset=debug
54+
ctest -j$(nproc) --preset=debug -LE BENCHMARK
5255
# `lcov` FOR CODECOV
5356
lcov --gcov-tool gcov \
5457
--capture \
@@ -81,3 +84,7 @@ jobs:
8184
-Dsonar.sources=src
8285
-Dsonar.tests=tests
8386
continue-on-error: true
87+
88+
- name: Prune Conan cache
89+
run: |
90+
conan cache clean --build

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cmake_minimum_required(VERSION 3.16)
1+
cmake_minimum_required(VERSION 4.0)
22
project(tradercpp)
33

44
set(CMAKE_CXX_STANDARD 23)

Dockerfile_build

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#############################################
2-
# milss/tradercppbuild:v1.7
2+
# milss/tradercppbuild:v1.8
33
# Build container for tradercpp
44
# Published to dockerhub in order to accelerate github actions
55
# Uses:
@@ -56,12 +56,6 @@ RUN apt update && apt install -y --no-install-recommends \
5656

5757

5858
# Install LLVM 18 (clang-format and clang-tidy)
59-
RUN apt update && apt install -y --no-install-recommends \
60-
gnupg \
61-
lsb-release \
62-
software-properties-common \
63-
wget \
64-
&& rm -rf /var/lib/apt/lists/*
6559

6660
RUN wget -qO - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
6761

@@ -115,5 +109,6 @@ RUN apt update && apt install -y --no-install-recommends \
115109
make \
116110
ninja-build \
117111
perl \
112+
shellcheck \
118113
unzip \
119114
&& rm -rf /var/lib/apt/lists/*

Makefile

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#!make
22
SHELL:=/bin/bash
33

4-
#################################################
5-
# A set of basic execution recipes (all PHONY).
6-
# Call `make` on the command line for documentation.
7-
#################################################
4+
# ###############################################
5+
# A set of execution recipes (all PHONY).
6+
# In essence, a programmatic entrypoint into the app.
7+
# Run `make` for help.
8+
# ###############################################
89

910
# pp - pretty print function
1011
yellow := $(shell tput setaf 3)
@@ -18,33 +19,39 @@ help: Makefile
1819
@echo " Choose a command to run:"
1920
@sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /'
2021

21-
## withenv: 😭 run `make` with envars from `.env`. like so `make withenv RECIPE=init`
22+
## withenv: 😭 execute `make` with environment variables defined in `.env`. like so > `make withenv RECIPE=init`
2223
.PHONY: withenv
2324
withenv:
2425
test -e .env || cp .env.example .env
2526
bash -c 'set -o allexport; source .env; set +o allexport; make "$$RECIPE"'
2627

27-
## init: 🏌️ initialize the project, fetch dependencies
28+
## init: 🏌️ initialize the project
2829
.PHONY: init
2930
init:
31+
$(call pp,initializing project)
32+
git config core.hooksPath hooks
3033
rm -rf build && mkdir build
3134
python3 -m venv .venv
3235
source .venv/bin/activate && \
3336
pip install gcovr conan && \
3437
conan install . --lockfile=conan.lock --build=missing -s build_type=Debug && \
3538
conan install . --lockfile=conan.lock --build=missing -s build_type=Release
39+
cmake --preset=release
3640
cmake --preset=debug
41+
$(MAKE) restore-cpus
3742

38-
## lock-conan: 📦 run after adding (but before installing) conan dependencies
39-
.PHONY: lock-conan
40-
lock-conan:
41-
conan lock create . --profile:host=default -s build_type=Debug --lockfile-out=conan.lock
42-
conan lock create . --profile:host=default -s build_type=Release --lockfile=conan.lock --lockfile-out=conan.lock
43+
## lock: 📦 update Conan dependency lock file. (NB run after adding conan dependencies to conanfile.txt, but before installing)
44+
.PHONY: lock
45+
lock:
46+
$(call pp,updating conan lock file to match contents of conanfile.txt)
47+
source .venv/bin/activate && \
48+
conan lock create . --profile:host=default -s build_type=Debug --lockfile-out=conan.lock && \
49+
conan lock create . --profile:host=default -s build_type=Release --lockfile=conan.lock --lockfile-out=conan.lock
4350

4451
## build-debug: 🔨 compile (debug)
4552
.PHONY: build-debug
4653
build-debug:
47-
$(call pp,assuming `make init` has been called)
54+
$(call pp,NB assuming `make init` has been called)
4855
cmake --preset=debug
4956
cmake --build --preset=debug
5057

@@ -68,7 +75,6 @@ test:
6875
## bench: ⏱️ build and run benchmarks
6976
.PHONY: bench
7077
bench:
71-
$(call pp,assuming `make build-release` has been called)
7278
cmake --build --preset release
7379
build/Release/benchmarks/benchmarks \
7480
--benchmark_out=bench_results.json \
@@ -79,19 +85,29 @@ bench:
7985
.PHONY: tidy
8086
tidy:
8187
find src/ tests/ benchmarks/ \( -name '*.cpp' -o -name '*.hpp' -o -name '*.c' -o -name '*.h' \) -exec clang-format -i {} +
88+
hooks/check_shell.sh
8289
hooks/check_clang_tidy.sh
8390

84-
## run-debug: 🏃‍♂️ run the app (debug) (don't forget `withenv`)
91+
## run-debug: 🏃‍♂️ run the app (debug) (don't forget `withenv`)
8592
.PHONY: run-debug
8693
run-debug:
8794
ASAN_OPTIONS=detect_leaks=1:leak_check_at_exit=1:fast_unwind_on_malloc=0 \
8895
build/Debug/tradercpp
8996

90-
## run-release: 🏎️ run the app (prod)
97+
## run-release: 🏎️ run the app (prod)
9198
.PHONY: run-release
9299
run-release:
93-
$(call pp,starting app. dont forget to run `scripts/cpu_shield_start.sh` and `scripts/irqs_move.sh`)
94-
build/Release/tradercpp
100+
$(call pp,moving IRQs)
101+
set -o allexport; source .env; set +o allexport; sudo -E scripts/pin_irqs.sh
102+
$(call pp,moving CPUs and starting app)
103+
set -o allexport; source .env; set +o allexport; sudo -E scripts/pin_cpus.sh build/Release/tradercpp
104+
105+
## restore-cpus: 🖥️ hand back pinned CPUs and IRQs to the operating system. (NB app must not be running)
106+
.PHONY: restore-cpus
107+
restore-cpus:
108+
$(call pp,handing CPU management back to the kernel (NB: app must not be running))
109+
$(call pp,NB: for re-assigning IRQs reboot the machine)
110+
set -o allexport; source .env; set +o allexport; sudo -E scripts/unpin_cpus.sh
95111

96112
# CONTAINERISATION RECIPES ----------------------------------------------------
97113

@@ -101,7 +117,7 @@ build-container:
101117
IMAGE_VERSION=
102118
@if [ -z "$(IMAGE_VERSION)" ]; then \
103119
echo "Error: IMAGE_VERSION is not set"; \
104-
echo "(you can set it on the command line like so: \`make build-container IMAGE_VERSION=1.7\`)"; \
120+
echo "(you can set it on the command line like so: \`make build-container IMAGE_VERSION=1.8\`)"; \
105121
exit 1; \
106122
fi
107123
docker build -f Dockerfile_build -t milss/tradercppbuild:latest -t milss/tradercppbuild:v$(IMAGE_VERSION) .

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ NB: this app uses `make` as a recipe book, but it's not essential:
152152
- ✅ cache line alignment
153153
- ✅ tcmalloc (Full) / gperftools
154154
- CPU
155-
-process priority
156-
-FIX-thread "realtime"
157-
-FIX-thread CPU affinity
155+
-isolated CPU cores
156+
- ✅ thread-CPU affinity
157+
- ✅ thread "realtime" priority
158158
- Disable hyperthreading
159159
- OS
160160
- ✅ vacate OS services
@@ -173,6 +173,7 @@ NB: this app uses `make` as a recipe book, but it's not essential:
173173
- ✅ debug quickfix to confirm if it's running in it's own thread
174174
- QuickFIX alternative (Fix8)
175175
- otherwise => QuickFIX + SSL
176+
- hugepages
176177
- kernel space vs user space
177178
- intrinsics
178179
- compiler auto-vectorization

hooks/check_shell.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
3+
################################################################
4+
# check_clang_tidy.sh
5+
# checks for any lint warnings and errors out.
6+
# does not modify files in-place.
7+
# uses run-clang-tidy for parallel execution.
8+
################################################################
9+
10+
set -euo pipefail
11+
12+
echo ">> Running shellcheck on all scripts"
13+
14+
while IFS= read -r file; do
15+
shellcheck "$file"
16+
# find files that start with a sh/bash shebang, exclude build/ and .git/hooks folders
17+
done < <(find . \( -type d -name build -o -path './.git/hooks' \) -prune -o -type f -exec grep -Iq '^#!.*sh' {} \; -print)

hooks/pre-commit

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
1313

1414
# Run subscripts
1515

16-
echo "Running strict pre-commit checks (clang-tidy, clang-format, build-debug)..."
16+
echo "Running strict pre-commit checks (clang-format, shellcheck, clang-tidy, build-debug)..."
17+
18+
bash "$DIR/check_clang_format.sh"
19+
20+
bash "$DIR/check_shell.sh"
1721

1822
# TODO(mils): does this also need to be converted to:
1923
# `git diff -U0 origin/master...HEAD -- '*.cpp'`
2024
git diff -U0 master...HEAD -- '*.cpp' | \
2125
clang-tidy-diff-18.py -p1 -path "$DIR/../build/Debug"
2226

23-
bash "$DIR/check_clang_format.sh"
24-
2527
make build-debug
2628

2729
echo "✅ Pre-commit checks passed on full codebase."

0 commit comments

Comments
 (0)