Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 49 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,57 @@ on:
pull_request:
branches: [ "HP" ]

permissions:
contents: read

jobs:
build:
linux:
name: Linux (${{ matrix.cc }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
cc: [gcc, clang]
env:
CC: ${{ matrix.cc }}
steps:
- uses: actions/checkout@v6
- name: Build and test
run: make clean test

sanitizers:
name: Sanitizers
runs-on: ubuntu-latest
permissions:
contents: read
env:
CC: clang
steps:
- uses: actions/checkout@v6
- name: Address + UndefinedBehavior Sanitizer
run: make clean test-sanitize
- name: ThreadSanitizer
run: make clean test-tsan

windows:
name: Windows MSVC
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: make
run: make
- name: make test
run: make test
- uses: actions/checkout@v6
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Build
shell: cmd
run: |
if not exist bin mkdir bin
cl /nologo /W4 /WX /O2 /TC lfq.c test_edge_cases.c /Fe:bin\test_edge_cases.exe
cl /nologo /W4 /WX /O2 /TC lfq.c test_multithread.c /DMAX_PRODUCER=4 /DMAX_CONSUMER=4 /DITEMS_PER_PRODUCER=5000 /Fe:bin\test_multithread.exe
cl /nologo /W4 /WX /O2 /TC lfq.c test_aba.c /DABA_THREADS=8 /DABA_ITERATIONS=5000 /Fe:bin\test_aba.exe
- name: Test
shell: cmd
run: |
bin\test_edge_cases.exe
bin\test_multithread.exe
bin\test_aba.exe
- name: Build Visual Studio solution
shell: cmd
run: msbuild "Visual Stdio\lfqueue.sln" /m /p:Configuration=Release /p:Platform=x64 /p:PlatformToolset=v145
140 changes: 100 additions & 40 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,40 +1,100 @@
CC=gcc
CFLAGS=-std=gnu99 -O3 -Wall -Wextra -g
LDFLAGS=-g
LOADLIBS=-lpthread

all : bin/test_p1c1 bin/test_p4c4 bin/test_p100c10 bin/test_p10c100 bin/test_aba bin/example

bin/example: example.c liblfq.so.1.0.0
gcc $(CFLAGS) $(LDFLAGS) example.c lfq.c -o bin/example -lpthread

bin/test_p1c1: liblfq.so.1.0.0 test_multithread.c
gcc $(CFLAGS) $(LDFLAGS) test_multithread.c -o bin/test_p1c1 -L. -Wl,-Bstatic -llfq -Wl,-Bdynamic -lpthread -D MAX_PRODUCER=1 -D MAX_CONSUMER=1

bin/test_p4c4: liblfq.so.1.0.0 test_multithread.c
gcc $(CFLAGS) $(LDFLAGS) test_multithread.c -o bin/test_p4c4 -L. -Wl,-Bstatic -llfq -Wl,-Bdynamic -lpthread -D MAX_PRODUCER=4 -D MAX_CONSUMER=4

bin/test_p100c10: liblfq.so.1.0.0 test_multithread.c
gcc $(CFLAGS) $(LDFLAGS) test_multithread.c -o bin/test_p100c10 -L. -Wl,-Bstatic -llfq -Wl,-Bdynamic -lpthread -D MAX_PRODUCER=100 -D MAX_CONSUMER=10

bin/test_p10c100: liblfq.so.1.0.0 test_multithread.c
gcc $(CFLAGS) $(LDFLAGS) test_multithread.c -o bin/test_p10c100 -L. -Wl,-Bstatic -llfq -Wl,-Bdynamic -lpthread -D MAX_PRODUCER=10 -D MAX_CONSUMER=100

bin/test_aba: liblfq.so.1.0.0 test_aba.c
gcc $(CFLAGS) $(LDFLAGS) test_aba.c -o bin/test_aba -L. -Wl,-Bstatic -llfq -Wl,-Bdynamic -lpthread

liblfq.so.1.0.0: lfq.c lfq.h cross-platform.h
gcc $(CFLAGS) $(CPPFLAGS) -c lfq.c # -fno-pie for static linking?
ar rcs liblfq.a lfq.o
gcc $(CFLAGS) $(CPPFLAGS) -fPIC -c lfq.c
gcc $(LDFLAGS) -shared -o liblfq.so.1.0.0 lfq.o

test: bin/test_p1c1 bin/test_p4c4 bin/test_p100c10 bin/test_p10c100 bin/test_aba
$(TESTWRAPPER) bin/test_p1c1
$(TESTWRAPPER) bin/test_p4c4
$(TESTWRAPPER) bin/test_p100c10
$(TESTWRAPPER) bin/test_p10c100
$(TESTWRAPPER) bin/test_aba

clean:
rm -rf *.o bin/* liblfq.so.1.0.0 liblfq.a
CC ?= gcc
CFLAGS ?= -std=gnu99 -O3 -Wall -Wextra -Wpedantic -g
CPPFLAGS ?=
LDFLAGS ?=
LDLIBS ?= -lpthread

TEST_BINS = bin/test_edge_cases bin/test_p1c1 bin/test_p4c4 bin/test_p100c10 bin/test_p10c100 bin/test_aba bin/test_scheduler bin/test_affinity_single bin/test_affinity_split

.PHONY: all test clean test-sanitize test-tsan

all: liblfq.a liblfq.so.1.0.0 $(TEST_BINS) bin/example

bin:
mkdir -p bin

lfq.o: lfq.c lfq.h cross-platform.h
$(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -c lfq.c -o $@

liblfq.a: lfq.o
ar rcs $@ $<

liblfq.so.1.0.0: lfq.o
$(CC) $(LDFLAGS) -shared -o $@ $<

bin/example: example.c lfq.c lfq.h cross-platform.h | bin
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) example.c lfq.c -o $@ $(LDLIBS)

bin/test_edge_cases: test_edge_cases.c lfq.c lfq.h cross-platform.h | bin
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) test_edge_cases.c lfq.c -o $@ $(LDLIBS)

bin/test_p1c1: test_multithread.c lfq.c lfq.h cross-platform.h | bin
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) test_multithread.c lfq.c -o $@ $(LDLIBS) -D MAX_PRODUCER=1 -D MAX_CONSUMER=1

bin/test_p4c4: test_multithread.c lfq.c lfq.h cross-platform.h | bin
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) test_multithread.c lfq.c -o $@ $(LDLIBS) -D MAX_PRODUCER=4 -D MAX_CONSUMER=4

bin/test_p100c10: test_multithread.c lfq.c lfq.h cross-platform.h | bin
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) test_multithread.c lfq.c -o $@ $(LDLIBS) -D MAX_PRODUCER=100 -D MAX_CONSUMER=10 -D ITEMS_PER_PRODUCER=20000

bin/test_p10c100: test_multithread.c lfq.c lfq.h cross-platform.h | bin
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) test_multithread.c lfq.c -o $@ $(LDLIBS) -D MAX_PRODUCER=10 -D MAX_CONSUMER=100 -D ITEMS_PER_PRODUCER=20000

bin/test_aba: test_aba.c lfq.c lfq.h cross-platform.h | bin
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) test_aba.c lfq.c -o $@ $(LDLIBS)

bin/test_scheduler: test_scheduler.c lfq.c lfq.h cross-platform.h | bin
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -DLFQ_TEST_HOOKS test_scheduler.c lfq.c -o $@ $(LDLIBS)

bin/test_affinity_single: test_multithread.c lfq.c lfq.h cross-platform.h | bin
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) test_multithread.c lfq.c -o $@ $(LDLIBS) -D LFQ_AFFINITY_MODE=1 -D MAX_PRODUCER=16 -D MAX_CONSUMER=16 -D ITEMS_PER_PRODUCER=20000

bin/test_affinity_split: test_multithread.c lfq.c lfq.h cross-platform.h | bin
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) test_multithread.c lfq.c -o $@ $(LDLIBS) -D LFQ_AFFINITY_MODE=2 -D MAX_PRODUCER=16 -D MAX_CONSUMER=16 -D ITEMS_PER_PRODUCER=20000

test: $(TEST_BINS)
./bin/test_edge_cases
./bin/test_p1c1
./bin/test_p4c4
./bin/test_p100c10
./bin/test_p10c100
./bin/test_aba
./bin/test_scheduler
./bin/test_affinity_single
./bin/test_affinity_split

bin/test_edge_asan: test_edge_cases.c lfq.c lfq.h cross-platform.h | bin
$(CC) -std=gnu99 -O1 -g -Wall -Wextra -fno-omit-frame-pointer -fsanitize=address,undefined test_edge_cases.c lfq.c -o $@ $(LDLIBS)

bin/test_mt_asan: test_multithread.c lfq.c lfq.h cross-platform.h | bin
$(CC) -std=gnu99 -O1 -g -Wall -Wextra -fno-omit-frame-pointer -fsanitize=address,undefined test_multithread.c lfq.c -o $@ $(LDLIBS) -D MAX_PRODUCER=8 -D MAX_CONSUMER=8 -D ITEMS_PER_PRODUCER=5000

bin/test_aba_asan: test_aba.c lfq.c lfq.h cross-platform.h | bin
$(CC) -std=gnu99 -O1 -g -Wall -Wextra -fno-omit-frame-pointer -fsanitize=address,undefined test_aba.c lfq.c -o $@ $(LDLIBS) -D ABA_THREADS=8 -D ABA_ITERATIONS=5000

bin/test_scheduler_asan: test_scheduler.c lfq.c lfq.h cross-platform.h | bin
$(CC) -std=gnu99 -O1 -g -Wall -Wextra -fno-omit-frame-pointer -fsanitize=address,undefined -DLFQ_TEST_HOOKS test_scheduler.c lfq.c -o $@ $(LDLIBS)

test-sanitize: bin/test_edge_asan bin/test_mt_asan bin/test_aba_asan bin/test_scheduler_asan
ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 ./bin/test_edge_asan
ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 ./bin/test_mt_asan
ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 ./bin/test_aba_asan
ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 ./bin/test_scheduler_asan

bin/test_mt_tsan: test_multithread.c lfq.c lfq.h cross-platform.h | bin
$(CC) -std=gnu99 -O1 -g -Wall -Wextra -fno-omit-frame-pointer -fsanitize=thread test_multithread.c lfq.c -o $@ $(LDLIBS) -D MAX_PRODUCER=8 -D MAX_CONSUMER=8 -D ITEMS_PER_PRODUCER=5000

bin/test_aba_tsan: test_aba.c lfq.c lfq.h cross-platform.h | bin
$(CC) -std=gnu99 -O1 -g -Wall -Wextra -fno-omit-frame-pointer -fsanitize=thread test_aba.c lfq.c -o $@ $(LDLIBS) -D ABA_THREADS=8 -D ABA_ITERATIONS=5000

bin/test_scheduler_tsan: test_scheduler.c lfq.c lfq.h cross-platform.h | bin
$(CC) -std=gnu99 -O1 -g -Wall -Wextra -fno-omit-frame-pointer -fsanitize=thread -DLFQ_TEST_HOOKS test_scheduler.c lfq.c -o $@ $(LDLIBS)

test-tsan: bin/test_mt_tsan bin/test_aba_tsan bin/test_scheduler_tsan
TSAN_OPTIONS=halt_on_error=1 ./bin/test_mt_tsan
TSAN_OPTIONS=halt_on_error=1 ./bin/test_aba_tsan
TSAN_OPTIONS=halt_on_error=1 ./bin/test_scheduler_tsan

clean:
rm -f *.o liblfq.a liblfq.so.1.0.0
rm -f bin/test_* bin/example
Loading
Loading