-
Notifications
You must be signed in to change notification settings - Fork 173
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1400 from ccotter/relacy
Proof of concept: Relacy tests
- Loading branch information
Showing
8 changed files
with
203 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# User-customizable variables: | ||
CXX ?= c++ | ||
CXX_STD ?= c++20 | ||
CXXFLAGS ?= -I relacy -I relacy/relacy/fakestd -O1 -std=$(CXX_STD) -I ../../include -I ../../test -g | ||
DEPFLAGS ?= -MD -MF $(@).d -MP -MT $(@) | ||
build_dir = build | ||
|
||
.SECONDARY: | ||
|
||
test_programs = split async_scope | ||
|
||
test_exe_files = $(foreach name,$(test_programs),$(build_dir)/$(name)) | ||
|
||
exe_files = $(test_exe_files) | ||
o_files = $(exe_files:=.cpp.o) | ||
|
||
ansi_term_csi = [ | ||
ansi_term_bold = $(ansi_term_csi)1m | ||
ansi_term_green = $(ansi_term_csi)32m | ||
ansi_term_red = $(ansi_term_csi)31m | ||
ansi_term_reset = $(ansi_term_csi)m | ||
|
||
COMPILE.cpp = $(CXX) $(DEPFLAGS) $(CXXFLAGS) -c | ||
LINK.cpp = $(CXX) $(CXXFLAGS) | ||
|
||
.PHONY: all | ||
all: tests | ||
|
||
.PHONY: tests | ||
tests: $(test_exe_files) | ||
|
||
$(build_dir)/%.check-result: $(build_dir)/% always-run | ||
@ \ | ||
printf '%s%s ...%s\n' $(ansi_term_bold) $(*) $(ansi_term_reset) >&2; \ | ||
$(<); \ | ||
status="$${?}"; \ | ||
printf %d "$${status}" >$(@); \ | ||
if [ "$${status}" -eq 0 ]; then \ | ||
printf '%s%s %s%s\n' $(ansi_term_green) $(*) OK $(ansi_term_reset); \ | ||
else \ | ||
printf '%s%s %s%s\n' $(ansi_term_red) $(*) FAIL $(ansi_term_reset); \ | ||
fi >&2; \ | ||
exit "$${status}" | ||
|
||
$(build_dir)/%: $(build_dir)/%.cpp.o | ||
$(LINK.cpp) $(^) -o $(@) | ||
|
||
$(build_dir)/%.cpp.o: %.cpp | ||
@mkdir -p $(dir $(@)) | ||
$(COMPILE.cpp) -o $(@) $(<) | ||
|
||
.PHONY: clean | ||
clean: | ||
rm -fr -- $(build_dir)/ | ||
|
||
.PHONY: always-run | ||
always-run: | ||
|
||
-include $(o_files:=.d) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
## Relacy tests | ||
|
||
[Relacy (RRD)](https://www.1024cores.net/home/relacy-race-detector/rrd-introduction) | ||
is a data race detector. It replaces the OS scheduler with an scheduler that | ||
explores many different thread interleavings, and logs detected races or assertion | ||
failures. Relacy can also simulate relaxed hardware by simulating old values of a | ||
variable as allowed by the C++11 memory model. | ||
|
||
Relacy requires a specialized build. In particular, it is a header only library that | ||
replaces the standard library and pthread APIs at compile time. Since it places some | ||
standard library includes, writing new tests may require working around certain | ||
limitations in terms of what the replacement headers and accompanying runtime can | ||
support. For example, Relacy's atomic replacements cannot support `++x`, so the | ||
stdexec library could needs to use `x.fetch_add(1)` to be compatible with Relacy. | ||
|
||
## Instructions | ||
|
||
Run the following commands from within this directory (`./tests/rrd`). | ||
|
||
``` | ||
# TODO: Merge patches into upstream Relacy @ dvyukov's version | ||
git clone -b stdexec https://github.com/ccotter/relacy | ||
CXX=g++-11 make -j 4 | ||
./build/split | ||
``` | ||
|
||
## Recommended use | ||
|
||
The Relacy tests can be manually built and executed. New tests can be written for | ||
new algorithms, or new use cases in the stdexec library. | ||
|
||
At this time, integrating the tests into CI is not yet recommended. If we can figure | ||
out a more stable build on all environments/compilers, we should revisit this. | ||
|
||
## Supported platforms | ||
|
||
The stdexec Relacy tests have been verified to build and run on | ||
* Linux based GCC+11 with libstdc++ (`x86_64`) | ||
* Mac with Apple Clang 15 with libc++ (`x86_64`) | ||
|
||
G++12 and newer are known to have issues that could be addressed with patches | ||
to Relacy. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#include "../../relacy/relacy_std.hpp" | ||
#include "../../relacy/relacy_cli.hpp" | ||
|
||
#include <stdexec/execution.hpp> | ||
#include <exec/async_scope.hpp> | ||
#include <exec/static_thread_pool.hpp> | ||
#include <test_common/schedulers.hpp> | ||
#include <test_common/type_helpers.hpp> | ||
|
||
#include <chrono> | ||
#include <random> | ||
#include <iostream> | ||
|
||
using rl::nvar; | ||
using rl::nvolatile; | ||
using rl::mutex; | ||
|
||
namespace ex = stdexec; | ||
using exec::async_scope; | ||
|
||
struct async_scope_bug : rl::test_suite<async_scope_bug, 1> | ||
{ | ||
static size_t const dynamic_thread_count = 2; | ||
|
||
void thread(unsigned) | ||
{ | ||
exec::static_thread_pool ctx{1}; | ||
|
||
ex::scheduler auto sch = ctx.get_scheduler(); | ||
|
||
exec::async_scope scope; | ||
std::atomic_bool produced{false}; | ||
ex::sender auto begin = ex::schedule(sch); | ||
{ | ||
ex::sender auto ftr = scope.spawn_future(begin | stdexec::then([&]() { produced.store(true); })); | ||
(void) ftr; | ||
} | ||
stdexec::sync_wait(scope.on_empty() | stdexec::then([&]() { | ||
RL_ASSERT(produced.load()); | ||
})); | ||
} | ||
}; | ||
|
||
int main() | ||
{ | ||
rl::test_params p; | ||
p.iteration_count = 50000; | ||
p.execution_depth_limit = 10000; | ||
rl::simulate<async_scope_bug>(p); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#include "../../relacy/relacy_std.hpp" | ||
#include "../../relacy/relacy_cli.hpp" | ||
|
||
#include <stdexec/execution.hpp> | ||
#include <exec/async_scope.hpp> | ||
#include <exec/static_thread_pool.hpp> | ||
#include <test_common/schedulers.hpp> | ||
|
||
#include <chrono> | ||
#include <random> | ||
#include <iostream> | ||
|
||
using rl::nvar; | ||
using rl::nvolatile; | ||
using rl::mutex; | ||
|
||
namespace ex = stdexec; | ||
using exec::async_scope; | ||
|
||
struct split_bug : rl::test_suite<split_bug, 1> | ||
{ | ||
static size_t const dynamic_thread_count = 2; | ||
|
||
void thread(unsigned) | ||
{ | ||
exec::static_thread_pool pool{1}; | ||
auto split = ex::schedule(pool.get_scheduler()) // | ||
| ex::then([] { | ||
return 42; | ||
}) | ||
| ex::split(); | ||
|
||
auto [val] = ex::sync_wait(split).value(); | ||
RL_ASSERT(val == 42); | ||
} | ||
}; | ||
|
||
int main() | ||
{ | ||
rl::test_params p; | ||
p.iteration_count = 50000; | ||
p.execution_depth_limit = 10000; | ||
rl::simulate<split_bug>(p); | ||
return 0; | ||
} |