Add ReaderWriterQueue and update ConcurrentQueue

This commit is contained in:
Paul Hollinsky
2020-03-09 13:38:14 -04:00
parent 9ac3fd56bd
commit 42780dc610
1629 changed files with 306008 additions and 868 deletions
@@ -0,0 +1,61 @@
#pragma once
#include "../relacy/relacy_std.hpp"
struct test_addr_hash : rl::test_suite<test_addr_hash, 2>
{
void* p1;
void* p2;
size_t h1, h2;
static size_t const table_size = 1000;
void before()
{
p1 = malloc(0);
h1 = rl::hash_ptr(p1, table_size);
p2 = malloc(0);
h2 = rl::hash_ptr(p2, table_size);
}
void after()
{
free(p1);
free(p2);
}
void thread(unsigned index)
{
assert(h1 == rl::hash_ptr(p1, table_size));
assert(h2 == rl::hash_ptr(p2, table_size));
assert(rl::hash_ptr(&index, table_size) == rl::hash_ptr(&index,table_size));
assert(rl::hash_ptr(0, table_size) == rl::hash_ptr(0, table_size));
}
};
struct test_addr_hash2 : rl::test_suite<test_addr_hash2, 2, rl::test_result_until_condition_hit>
{
static size_t const table_size = 4;
std::atomic<int> table [table_size];
void before()
{
for (size_t i = 0; i != table_size; i += 1)
table[i].store(0, std::memory_order_relaxed);
}
void thread(unsigned)
{
for (size_t i = 0; i != table_size + 1; i += 1)
{
void* p = malloc(0);
size_t idx = rl::hash_ptr(p, table_size);
free(p);
int v = table[idx].exchange(1, std::memory_order_relaxed);
RL_UNTIL(v);
}
}
};
@@ -0,0 +1,51 @@
Test parameters. You can specify various parameters for test.
rl::test_params p;
p.search_type = rl::fair_context_bound_scheduler_type;
p.context_bound = 1;
p.execution_depth_limit = 1000;
rl::simulate<test_t>(p);
The main parameter is scheduler type used for simulation. There is 3 types of scheduler:
random_scheduler_type - random exploration of state space
fair_full_search_scheduler_type - exhaustive systematic exploration of state space
fair_context_bound_scheduler_type - systematic exploration of state space with limit on context switches.
For random_scheduler_type you can specify 'iteration_count' parameter - number of explored executions.
For fair_context_bound_scheduler_type you can specify 'context_bound' parameter - limit on context switches.
Also you can specify 'execution_depth_limit' parameter - used for livelock detection. All executions with trace longer than execution_depth_limit will be treated as livelocked (or non-terminating).
Also from test_params structure you can receive output parameters from simulation. Main output parameter is 'test_result' which describes cause of test failure.
If you use fair_full_search_scheduler_type or fair_context_bound_scheduler_type, in order to ensure fairness of scheduler, you must use 'yield' calls in all 'spin-loops', otherwise simulation will report non-terminating execution. Example:
struct race_seq_ld_ld_test : rl::test_suite<race_seq_ld_ld_test, 2>
{
std::atomic<int> a;
rl::var<int> x;
void before()
{
a($) = 0;
x($) = 0;
}
void thread(unsigned index)
{
if (index)
{
x($).load();
a($).store(1, std::memory_order_relaxed);
}
else
{
rl::backoff b;
while (0 == a($).load(rl::memory_order_relaxed))
b.yield($);
x($).load();
}
}
};
@@ -0,0 +1,47 @@
#pragma once
#include "../relacy/relacy_std.hpp"
template<int T>
struct cas_spurious_fail_test : rl::test_suite<cas_spurious_fail_test<T>, 1, rl::test_result_until_condition_hit>
{
std::atomic<int> x;
std::atomic<int> y;
void before()
{
x.store(0, std::memory_order_relaxed);
y.store(0, std::memory_order_relaxed);
}
void thread(unsigned /*index*/)
{
int cmp = 0;
if (x.compare_exchange_weak(cmp, 1, std::memory_order_seq_cst, std::memory_order_seq_cst))
{
cmp = 1;
if (x.compare_exchange_weak(cmp, 2, std::memory_order_seq_cst))
{
cmp = 0;
if (y.compare_exchange_weak(cmp, 1, std::memory_order_seq_cst))
{
}
else
{
if (T == 2) RL_UNTIL(true);
}
}
else
{
if (T == 1) RL_UNTIL(true);
}
}
else
{
if (T == 0) RL_UNTIL(true);
}
}
};
@@ -0,0 +1,82 @@
#pragma once
#include "../relacy/relacy_std.hpp"
struct test_condvar : rl::test_suite<test_condvar, 2>
{
std::mutex mtx;
std::condition_variable cv;
rl::var<int> data;
void before()
{
data($) = 0;
}
void thread(unsigned index)
{
if (0 == index)
{
mtx.lock($);
data($) += 1;
mtx.unlock($);
cv.notify_one($);
}
else
{
mtx.lock($);
while (0 == data($))
{
cv.wait(mtx, $);
}
mtx.unlock($);
}
}
};
struct test_condvar2 : rl::test_suite<test_condvar2, 3>
{
rl::var<int> stage;
std::mutex mtx;
std::condition_variable cv;
void before()
{
stage($) = 0;
}
void thread(unsigned index)
{
if (0 == index)
{
mtx.lock($);
stage($) += 1;
cv.notify_all($);
while (stage($) != 2)
cv.wait(mtx, $);
mtx.unlock($);
}
else if (1 == index)
{
mtx.lock($);
while (stage($) != 1)
cv.wait(mtx, $);
stage($) += 1;
cv.notify_all($);
mtx.unlock($);
}
else if (2 == index)
{
mtx.lock($);
while (stage($) != 2)
cv.wait(mtx, $);
mtx.unlock($);
}
}
};
@@ -0,0 +1,247 @@
#pragma once
#include "../relacy/relacy_std.hpp"
struct race_ld_ld_test : rl::test_suite<race_ld_ld_test, 2>
{
rl::var<int> x;
void before()
{
x($) = 0;
}
void thread(unsigned index)
{
if (index)
x($).load();
else
x($).load();
}
};
struct race_ld_st_test : rl::test_suite<race_ld_st_test, 2, rl::test_result_data_race>
{
rl::var<int> x;
void before()
{
x($) = 0;
}
void thread(unsigned index)
{
if (index)
x($).load();
else
x($).store(1);
}
};
struct race_st_st_test : rl::test_suite<race_st_st_test, 2, rl::test_result_data_race>
{
rl::var<int> x;
void thread(unsigned index)
{
if (index)
x($).store(1);
else
x($).store(1);
}
};
struct race_seq_ld_ld_test : rl::test_suite<race_seq_ld_ld_test, 2>
{
std::atomic<int> a;
rl::var<int> x;
void before()
{
a($) = 0;
x($) = 0;
}
void thread(unsigned index)
{
if (index)
{
x($).load();
a.store(1, std::memory_order_relaxed);
}
else
{
rl::backoff b;
while (0 == a.load(std::memory_order_relaxed))
b.yield($);
x($).load();
}
}
};
struct race_seq_ld_st_test : rl::test_suite<race_seq_ld_st_test, 2, rl::test_result_data_race>
{
std::atomic<int> a;
rl::var<int> x;
void before()
{
a($) = 0;
x($) = 0;
}
void thread(unsigned index)
{
if (index)
{
x($).load();
a.store(1, std::memory_order_relaxed);
}
else
{
rl::backoff b;
while (0 == a.load(std::memory_order_relaxed))
b.yield($);
x($).store(1);
}
}
};
struct race_seq_st_ld_test : rl::test_suite<race_seq_st_ld_test, 2, rl::test_result_data_race>
{
std::atomic<int> a;
rl::var<int> x;
void before()
{
a($) = 0;
}
void thread(unsigned index)
{
if (0 == index)
{
x($).store(1);
a.store(1, std::memory_order_relaxed);
}
else
{
rl::backoff b;
while (0 == a.load(std::memory_order_relaxed))
b.yield($);
x($).load();
}
}
};
struct race_seq_st_st_test : rl::test_suite<race_seq_st_st_test, 2, rl::test_result_data_race>
{
std::atomic<int> a;
rl::var<int> x;
void before()
{
a($) = 0;
}
void thread(unsigned index)
{
if (index)
{
x($).store(1);
a.store(1, std::memory_order_relaxed);
}
else
{
rl::backoff b;
while (0 == a.load(std::memory_order_relaxed))
b.yield($);
VAR(x) = 1;
}
}
};
struct race_uninit_test : rl::test_suite<race_uninit_test, 2, rl::test_result_unitialized_access>
{
std::atomic<int> a;
std::atomic<int> x;
void before()
{
a($) = 0;
}
void thread(unsigned index)
{
if (index)
{
x.store(1, std::memory_order_relaxed);
a.store(1, std::memory_order_relaxed);
}
else
{
rl::backoff b;
while (0 == a.load(std::memory_order_relaxed))
b.yield($);
x.load(std::memory_order_seq_cst);
}
}
};
struct race_indirect_test : rl::test_suite<race_indirect_test, 2, rl::test_result_data_race>
{
std::atomic<int> a;
rl::var<int> x;
void before()
{
a($) = 0;
x($) = 0;
}
void thread(unsigned index)
{
if (0 == index)
{
x($) = 1;
a.store(1, std::memory_order_release);
(void)(int)x($);
}
else
{
rl::backoff b;
while (0 == a.load(std::memory_order_acquire))
b.yield($);
(void)(int)x($);
x($) = 2;
}
}
};
@@ -0,0 +1,10 @@
- Race condition (accoring to ISO C++0x)
- Access to uninitialized variable
- Access to freed memory
- Double free
- Memory leak
- Deadlock
- Livelock
- User assert failed
- User invariant failed
@@ -0,0 +1,155 @@
#pragma once
#include "../relacy/relacy.hpp"
#include "../relacy/dyn_thread.hpp"
struct dyn_thread_basic_test : rl::test_suite<dyn_thread_basic_test, 2>
{
static unsigned const dynamic_thread_count = 4;
rl::var<int> data1;
rl::var<int> data2;
rl::atomic<int> data3;
void before()
{
data3($) = 0;
}
static void* thread1(void* p)
{
dyn_thread_basic_test& self = *(dyn_thread_basic_test*)p;
self.data1($) = 1;
return 0;
}
static void* thread2(void* p)
{
dyn_thread_basic_test& self = *(dyn_thread_basic_test*)p;
self.data2($) = 2;
return 0;
}
static void* thread3(void* p)
{
dyn_thread_basic_test& self = *(dyn_thread_basic_test*)p;
self.data3.store(3, rl::memory_order_relaxed);
return 0;
}
void thread(unsigned index)
{
if (index == 0)
{
rl::dyn_thread t1;
t1.start(&dyn_thread_basic_test::thread1, this);
rl::dyn_thread t2;
t2.start(&dyn_thread_basic_test::thread2, this);
t1.join();
t2.join();
RL_ASSERT(data1($) == 1);
RL_ASSERT(data2($) == 2);
}
else if (index == 1)
{
rl::dyn_thread t1;
t1.start(&dyn_thread_basic_test::thread3, this);
while (data3.load(rl::memory_order_relaxed) != 3)
rl::yield(1, $);
t1.join();
}
else
{
RL_ASSERT(false);
}
}
};
struct dyn_thread_win32_test : rl::test_suite<dyn_thread_win32_test, 2>
{
static unsigned const dynamic_thread_count = 4;
rl::var<int> data1;
rl::var<int> data2;
rl::atomic<int> data3;
void before()
{
data3($) = 0;
}
static unsigned long RL_STDCALL thread1(void* p)
{
dyn_thread_win32_test& self = *(dyn_thread_win32_test*)p;
self.data1($) = 1;
return 0;
}
static unsigned long RL_STDCALL thread2(void* p)
{
dyn_thread_win32_test& self = *(dyn_thread_win32_test*)p;
self.data2($) = 2;
return 0;
}
static unsigned long RL_STDCALL thread3(void* p)
{
dyn_thread_win32_test& self = *(dyn_thread_win32_test*)p;
self.data3.store(3, rl::memory_order_relaxed);
return 0;
}
void thread(unsigned index)
{
if (index == 0)
{
HANDLE threads [2];
threads[0] = CreateThread(0, 0, &dyn_thread_win32_test::thread1, this, 0, 0);
threads[1] = CreateThread(0, 0, &dyn_thread_win32_test::thread2, this, 0, 0);
WaitForMultipleObjects(2, threads, 1, INFINITE);
RL_ASSERT(VAR(data1) == 1);
RL_ASSERT(VAR(data2) == 2);
}
else if (index == 1)
{
HANDLE th = CreateThread(0, 0, &dyn_thread_win32_test::thread3, this, 0, 0);
while (data3.load(rl::memory_order_relaxed) != 3)
rl::yield(1, $);
WaitForSingleObject(th, INFINITE);
}
else
{
RL_ASSERT(false);
}
}
};
struct dyn_thread_visibility_test : rl::test_suite<dyn_thread_visibility_test, 1>
{
static unsigned const dynamic_thread_count = 1;
rl::var<int> data;
static unsigned long RL_STDCALL thread(void* p)
{
dyn_thread_visibility_test& self = *(dyn_thread_visibility_test*)p;
RL_ASSERT(self.data($) == 1);
self.data($) = 2;
return 0;
}
void thread(unsigned /*index*/)
{
data($) = 1;
HANDLE th = CreateThread(0, 0, &dyn_thread_visibility_test::thread, this, 0, 0);
WaitForSingleObject(th, INFINITE);
RL_ASSERT(data($) == 2);
}
};
@@ -0,0 +1,118 @@
#pragma once
#include "../relacy/relacy_std.hpp"
struct test_event_auto : rl::test_suite<test_event_auto, 2>
{
HANDLE ev;
VAR_T(int) data;
void before()
{
VAR(data) = 0;
ev = CreateEvent(0, 0, 0, 0);
}
void after()
{
CloseHandle(ev);
}
void thread(unsigned index)
{
if (0 == index)
{
VAR(data) = 1;
SetEvent(ev);
}
else
{
unsigned rv = WaitForSingleObject(ev, INFINITE);
assert(rv == WAIT_OBJECT_0);
assert(VAR(data) == 1);
rv = WaitForSingleObject(ev, 0);
assert(rv == WAIT_TIMEOUT);
}
}
};
struct test_event_atomic : rl::test_suite<test_event_atomic, 2>
{
HANDLE ev1;
HANDLE ev2;
void before()
{
ev1 = CreateEvent(0, 0, 0, 0);
ev2 = CreateEvent(0, 0, 0, 0);
}
void after()
{
CloseHandle(ev1);
CloseHandle(ev2);
}
void thread(unsigned index)
{
if (0 == index)
{
unsigned rv = WaitForSingleObject(ev1, INFINITE);
assert(rv == WAIT_OBJECT_0);
SetEvent(ev2);
rv = WaitForSingleObject(ev2, 0);
assert(rv == WAIT_TIMEOUT);
}
else
{
unsigned rv = SignalObjectAndWait(ev1, ev2, INFINITE, 0);
assert(rv == WAIT_OBJECT_0);
rv = WaitForSingleObject(ev2, 0);
assert(rv == WAIT_TIMEOUT);
}
}
};
struct test_event_manual : rl::test_suite<test_event_manual, 2>
{
HANDLE ev;
VAR_T(int) data;
void before()
{
VAR(data) = 0;
ev = CreateEvent(0, 1, 0, 0);
}
void after()
{
CloseHandle(ev);
}
void thread(unsigned index)
{
if (0 == index)
{
VAR(data) = 1;
SetEvent(ev);
}
else
{
unsigned rv = WaitForSingleObject(ev, INFINITE);
assert(rv == WAIT_OBJECT_0);
assert(VAR(data) == 1);
rv = WaitForSingleObject(ev, 0);
assert(rv == WAIT_OBJECT_0);
}
}
};
@@ -0,0 +1,9 @@
- Relaxed ISO C++0x Memory Model. Relaxed/acquire/release/acq_rel/seq_cst memory operations. The only non-supported feature is memory_order_consume, it's simulated with memory_order_acquire.
- Exhaustive automatic error checking (including ABA detection).
- Full-fledged atomics library (with spurious failures in compare_exchange()).
- Memory fences.
- Arbitrary number of threads.
- Detailed execution history for failed tests.
- No false positives.
- Before/after/invariant functions for test suites.
@@ -0,0 +1,164 @@
#pragma once
#include "../relacy/relacy_std.hpp"
template<int index, int mo_index>
struct fence_synch_test : rl::test_suite<fence_synch_test<index, mo_index>, 2>
{
std::atomic<int> x;
rl::var<int> data;
void before()
{
x($) = 0;
}
void thread(unsigned th)
{
if (0 == th)
{
data($) = 1;
if (0 == index || 1 == index)
{
std::atomic_thread_fence(order().first, $);
x.store(1, std::memory_order_relaxed);
}
else
{
x.store(1, order().first, $);
}
}
else
{
if (0 == index || 2 == index)
{
if (x.load(std::memory_order_relaxed))
{
std::atomic_thread_fence(order().second, $);
data($).load();
}
}
else
{
if (x.load(order().second, $))
{
data($).load();
}
}
}
}
std::pair<std::memory_order, std::memory_order> order()
{
switch (mo_index)
{
default: RL_VERIFY(false);
case 0: return std::make_pair(std::mo_release, std::mo_acquire);
case 1: return std::make_pair(std::mo_seq_cst, std::mo_seq_cst);
}
}
};
struct two_fence_synch_test : rl::test_suite<two_fence_synch_test, 3>
{
std::atomic<int> x0;
std::atomic<int> x1;
rl::var<int> data0;
rl::var<int> data1;
void before()
{
x0($) = 0;
x1($) = 0;
}
void thread(unsigned index)
{
if (0 == index)
{
data0($) = 1;
std::atomic_thread_fence(std::memory_order_release);
x0.store(1, std::memory_order_relaxed);
}
else if (1 == index)
{
data1($) = 1;
std::atomic_thread_fence(std::memory_order_release);
x1.store(1, std::memory_order_relaxed);
}
else
{
int y0 = x0.load(std::memory_order_relaxed);
int y1 = x1.load(std::memory_order_relaxed);
if (y0 || y1)
{
std::atomic_thread_fence(std::memory_order_acquire);
if (y0)
data0($).load();
if (y1)
data1($).load();
}
}
}
};
template<int index>
struct seq_cst_fence_test : rl::test_suite<seq_cst_fence_test<index>, 2,
(rl::test_result_e)((0 == index) * rl::test_result_success
+ (1 == index) * rl::test_result_until_condition_hit)>
{
std::atomic<int> x0;
std::atomic<int> x1;
rl::var<int> r0;
rl::var<int> r1;
void before()
{
x0($) = 0;
x1($) = 0;
}
void thread(unsigned th)
{
if (0 == th)
{
x0.store(1, std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
r0($) = x1.load(std::memory_order_relaxed);
}
else
{
x1.store(1, std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
r1($) = x0.load(std::memory_order_relaxed);
}
}
void after()
{
if (0 == index)
RL_ASSERT(r0($) || r1($));
else if (1 == index)
RL_UNTIL(r0($) && r1($));
}
};
@@ -0,0 +1,6 @@
#include "stdafx.h"
#include "../relacy/relacy_std.hpp"
#include "../relacy/windows.h"
#include "../relacy/pthread.h"
@@ -0,0 +1,162 @@
#pragma once
#include "../relacy/pthread.h"
struct test_futex : rl::test_suite<test_futex, 2>
{
rl::atomic<int> state;
int wakeres;
int waitres;
void before()
{
state.store(0, rl::memory_order_relaxed);
wakeres = 0;
waitres = 0;
}
void after()
{
assert((waitres == 0 && wakeres == 1)
|| (waitres == EWOULDBLOCK && wakeres == 0)
|| (waitres == EINTR && wakeres == 0));
}
void thread(unsigned index)
{
if (index == 0)
{
state.store(1, std::memory_order_relaxed);
wakeres = futex(&state, FUTEX_WAKE, 1, 0, 0, 0);
}
else
{
waitres = EINTR;
while (state.load(rl::memory_order_relaxed) == 0)
{
waitres = futex(&state, FUTEX_WAIT, 0, 0, 0, 0);
}
}
}
};
struct test_futex_deadlock : rl::test_suite<test_futex_deadlock, 1, rl::test_result_deadlock>
{
rl::atomic<int> state;
void thread(unsigned index)
{
state.store(0, rl::memory_order_relaxed);
int rv = futex(&state, FUTEX_WAIT, 0, 0, 0, 0);
assert(rv == EINTR);
}
};
struct test_futex_sync1 : rl::test_suite<test_futex_sync1, 2, rl::test_result_until_condition_hit>
{
rl::atomic<int> state;
VAR_T(int) data;
void before()
{
state.store(0, rl::memory_order_relaxed);
VAR(data) = 0;
}
void thread(unsigned index)
{
if (index == 0)
{
VAR(data) = 1;
state.store(1, std::memory_order_release);
futex(&state, FUTEX_WAKE, 1, 0, 0, 0);
}
else
{
int rv = futex(&state, FUTEX_WAIT, 0, 0, 0, 0);
assert(rv == 0 || rv == EWOULDBLOCK || rv == EINTR);
if (rv == 0)
{
assert(VAR(data) == 1);
assert(state.load(rl::memory_order_relaxed) == 1);
RL_UNTIL(true);
}
}
}
};
struct test_futex_sync2 : rl::test_suite<test_futex_sync2, 2, rl::test_result_until_condition_hit>
{
rl::atomic<int> state;
VAR_T(int) data;
void before()
{
state.store(0, rl::memory_order_relaxed);
VAR(data) = 0;
}
void thread(unsigned index)
{
if (index == 0)
{
VAR(data) = 1;
state.store(1, std::memory_order_release);
futex(&state, FUTEX_WAKE, 1, 0, 0, 0);
}
else
{
int rv = futex(&state, FUTEX_WAIT, 0, 0, 0, 0);
assert(rv == 0 || rv == EWOULDBLOCK || rv == EINTR);
if (rv == EWOULDBLOCK)
{
assert(VAR(data) == 1);
assert(state.load(rl::memory_order_relaxed) == 1);
RL_UNTIL(true);
}
}
}
};
struct test_futex_intr : rl::test_suite<test_futex_intr, 2, rl::test_result_until_condition_hit>
{
rl::atomic<int> state;
VAR_T(int) data;
void before()
{
state.store(0, rl::memory_order_relaxed);
VAR(data) = 0;
}
void thread(unsigned index)
{
if (index == 0)
{
VAR(data) = 1;
state.store(1, std::memory_order_release);
futex(&state, FUTEX_WAKE, 1, 0, 0, 0);
}
else
{
int rv = futex(&state, FUTEX_WAIT, 0, 0, 0, 0);
assert(rv == 0 || rv == EWOULDBLOCK || rv == EINTR);
RL_UNTIL(rv == EINTR);
}
}
};
@@ -0,0 +1,19 @@
g++ ../../jtest/jtest.cpp -c -o jtest_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../../ntest/ntest.cpp -c -o ntest_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../../example/peterson/peterson.cpp -c -o peterson_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../../example/proxy_collector/proxy_collector.cpp -c -o proxy_collector_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../../example/ref_counting/ref_counting.cpp -c -o ref_counting_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../../example/smr/smr.cpp -c -o smr_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../../example/spsc_queue/spsc_queue.cpp -c -o spsc_queue_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../../example/stack/stack.cpp -c -o stack_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../../example/condvar/condvar.cpp -c -o condvar_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../../example/mutex_business_logic/mutex_business_logic.cpp -c -o mutex_business_logic_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../../example/ws_deque/ws_deque.cpp -c -o ws_deque_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../../example/cli_ws_deque/cli_ws_deque.cpp -c -o cli_ws_deque_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../../example/java_ws_deque/java_ws_deque.cpp -c -o java_ws_deque_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
g++ ../main.cpp -c -o test_debug.exe -D_DEBUG -Wall -DRL_CYGWIN_STUB -march=i686
@@ -0,0 +1,19 @@
g++ ../../jtest/jtest.cpp -o jtest_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../../ntest/ntest.cpp -o ntest_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../../example/peterson/peterson.cpp -o peterson_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../../example/proxy_collector/proxy_collector.cpp -o proxy_collector_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../../example/ref_counting/ref_counting.cpp -o ref_counting_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../../example/smr/smr.cpp -o smr_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../../example/spsc_queue/spsc_queue.cpp -o spsc_queue_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../../example/stack/stack.cpp -o stack_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../../example/condvar/condvar.cpp -o condvar_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../../example/mutex_business_logic/mutex_business_logic.cpp -o mutex_business_logic_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../../example/ws_deque/ws_deque.cpp -o ws_deque_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../../example/cli_ws_deque/cli_ws_deque.cpp -o cli_ws_deque_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../../example/java_ws_deque/java_ws_deque.cpp -o java_ws_deque_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
g++ ../main.cpp -o test_debug.exe -D_DEBUG -Wall -Wno-deprecated -g
@@ -0,0 +1,17 @@
#!/bin/bash
set -eux
#g++ ../jtest/jtest.cpp -o jtest_release.exe -Wall -D_DEBUG -O2
#g++ ../ntest/ntest.cpp -o ntest_release.exe -Wall -D_DEBUG -O2
#g++ ../../example/peterson/peterson.cpp -o peterson_release.exe -Wall -D_DEBUG -O2
g++ ../../example/proxy_collector/proxy_collector.cpp -o proxy_collector_release.exe -Wall -D_DEBUG -O2
g++ ../../example/ref_counting/ref_counting.cpp -o ref_counting_release.exe -Wall -D_DEBUG -O2
g++ ../../example/smr/smr.cpp -o smr_release.exe -Wall -D_DEBUG -O2
g++ ../../example/spsc_queue/spsc_queue.cpp -o spsc_queue_release.exe -Wall -D_DEBUG -O2
g++ ../../example/stack/stack.cpp -o stack_release.exe -Wall -D_DEBUG -O2
g++ ../../example/condvar/condvar.cpp -o condvar_release.exe -Wall -D_DEBUG -O2
g++ ../../example/mutex_business_logic/mutex_business_logic.cpp -o mutex_business_logic_release.exe -Wall -D_DEBUG -O2
g++ ../../example/ws_deque/ws_deque.cpp -o ws_deque_release.exe -Wall -D_DEBUG -O2
g++ ../../example/cli_ws_deque/cli_ws_deque.cpp -o cli_ws_deque_release.exe -Wall -D_DEBUG -O2
g++ ../../example/java_ws_deque/java_ws_deque.cpp -o java_ws_deque_release.exe -Wall -D_DEBUG -O2
g++ ../main.cpp -o test_release.exe -Wall -D_DEBUG -O2
@@ -0,0 +1,4 @@
#!/bin/bash
g++ ../main.cpp -o test_release.exe -DNDEBUG -DRL_CYGWIN_STUB -Wall -O3
@@ -0,0 +1,2 @@
#!/bin/bash
g++ ../main.cpp -o test_debug.exe -D_DEBUG -D_XOPEN_SOURCE -Wall -Wno-deprecated -g -O0 -fno-inline
@@ -0,0 +1,4 @@
#!/bin/bash
g++ ../main.cpp -o test_release.exe -DNDEBUG -Wall -O3 -D_XOPEN_SOURCE -Wno-deprecated
@@ -0,0 +1,124 @@
//#ifdef _FORTIFY_SOURCE
//#undef _FORTIFY_SOURCE
//#endif
//#define _FORTIFY_SOURCE 0
#include "../../relacy/pthread.h"
class queue_t
{
public:
queue_t()
{
VAR(head) = 0;
VAR(tail) = 0;
pthread_mutex_init(&mtx, 0);
pthread_cond_init(&cv, 0);
}
~queue_t()
{
pthread_mutex_destroy(&mtx);
pthread_cond_destroy(&cv);
}
void enqueue(void* data)
{
node_t* n = new node_t;
n->VAR(next) = 0;
n->VAR(data) = data;
bool was_empty = false;
pthread_mutex_lock(&mtx);
if (VAR(head) == 0)
{
was_empty = true;
VAR(head) = n;
VAR(tail) = n;
}
else
{
VAR(tail)->VAR(next) = n;
VAR(tail) = n;
}
pthread_mutex_unlock(&mtx);
if (was_empty)
pthread_cond_broadcast(&cv);
}
void* dequeue()
{
node_t* n = 0;
pthread_mutex_lock(&mtx);
while (VAR(head) == 0)
pthread_cond_wait(&cv, &mtx);
n = VAR(head);
if (n->VAR(next) == 0)
VAR(tail) = 0;
VAR(head) = n->VAR(next);
pthread_mutex_unlock(&mtx);
void* data = n->VAR(data);
delete n;
return data;
}
private:
struct node_t
{
VAR_T(node_t*) next;
VAR_T(void*) data;
};
VAR_T(node_t*) head;
VAR_T(node_t*) tail;
pthread_mutex_t mtx;
pthread_cond_t cv;
};
void* enqueue_thread(void* ctx)
{
queue_t* q = static_cast<queue_t*>(ctx);
for (size_t i = 0; i != 4; i += 1)
q->enqueue((void*)(i + 1));
return 0;
}
void* dequeue_thread(void* ctx)
{
queue_t* q = static_cast<queue_t*>(ctx);
for (size_t i = 0; i != 4; i += 1)
{
void* data = q->dequeue();
assert((int)(uintptr_t)data >= 1 && (int)(uintptr_t)data <= 4);
}
return 0;
}
void queue_test()
{
queue_t q;
pthread_t th [4];
for (size_t i = 0; i != 2; i += 1)
pthread_create(&th[i], 0, enqueue_thread, &q);
for (size_t i = 2; i != 4; i += 1)
pthread_create(&th[i], 0, dequeue_thread, &q);
void* res = 0;
for (size_t i = 0; i != 4; i += 1)
pthread_join(th[i], &res);
}
int main()
{
rl::test_params p;
p.iteration_count = 100000;
//p.search_type = rl::sched_full;
//p.context_bound = 5;
//p.execution_depth_limit = 200;
rl::execute<queue_test, 4>(p);
}
@@ -0,0 +1,46 @@
#include "../relacy/relacy_std.hpp"
struct test : rl::test_suite<test, 4> {
std::atomic<int> x_;
std::atomic<int> y_;
int r2x, r2y, r3x, r3y;
void before() {
x_.store(0, std::memory_order_relaxed);
y_.store(0, std::memory_order_relaxed);
r2x = r2y = r3x = r3y = 0;
}
void thread(unsigned thread_index) {
switch (thread_index) {
case 0:;
x_.store(1, std::memory_order_relaxed);
break;
case 1:
y_.store(1, std::memory_order_relaxed);
break;
case 2:
r2x = x_.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
r2y = y_.load(std::memory_order_relaxed);
break;
case 3:
r3y = y_.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
r3x = x_.load(std::memory_order_relaxed);
break;
}
}
void after() {
// This assert should fire according to C++ memory model,
// however it does not in the current relacy implementation.
RL_ASSERT(!(r2x == 1 && r3y == 1 && r2y == 0 && r3x == 0));
}
};
int main() {
rl::test_params p;
p.iteration_count = 1000000;
rl::simulate<test>(p);
}
@@ -0,0 +1,258 @@
#include "stdafx.h"
#include "../../relacy/relacy_java.hpp"
class stack
{
public:
stack()
: head_(0)
{
}
void push(int data)
{
rl::var<node*> n = new node ();
VAR(n)->VAR(data_) = data;
node* next = head_.load(rl::memory_order_relaxed);
for (;;)
{
VAR(n)->next_.store(next, rl::memory_order_relaxed);
if (head_.compare_exchange_weak(next, VAR(n), rl::memory_order_release))
break;
}
}
int pop()
{
node* n = head_.load(rl::memory_order_acquire);
for (;;)
{
if (0 == n)
break;
node* next = n->next_.load(rl::memory_order_relaxed);
if (head_.compare_exchange_weak(n, next, rl::memory_order_acquire))
break;
}
if (n)
{
int data = n->VAR(data_);
return data;
}
else
{
return 0;
}
}
private:
struct node
{
rl::atomic<node*> next_;
rl::var<int> data_;
};
rl::atomic<node*> head_;
stack(stack const&);
stack& operator = (stack const&);
};
struct stack_test : rl::test_suite<stack_test, 4>
{
stack s_;
int produced_count_;
int consumed_count_;
void before()
{
produced_count_ = 0;
consumed_count_ = 0;
}
void after()
{
typedef rl::test_suite<stack_test, 4> base_t;
RL_ASSERT(base_t::params::thread_count == produced_count_);
RL_ASSERT(base_t::params::thread_count == consumed_count_);
}
void thread(unsigned /*index*/)
{
s_.push(rand() + 1);
produced_count_ += 1;
int data = s_.pop();
RL_ASSERT(data);
consumed_count_ += 1;
}
};
struct test_api : rl::test_suite<test_api, 1>
{
void thread(unsigned)
{
rl::jvolatile<int> jv1;
rl::jvolatile<int> jv2 (2);
rl::jvolatile<int> jv3 (jv2($));
rl::jvolatile<int> jv4 (jv1);
jv1($) = jv3($);
jv1($) = 2;
(int)jv1($);
jv1($) += 1;
jv1($) -= 1;
int x = jv1($)++;
x = jv1($)--;
x = --jv1($);
x = ++jv1($);
rl::AtomicInteger ai, ai2(1), ai3(x), ai4(ai($)), ai5(ai);
x = ai($).get();
ai($).set(1);
x = ai($).addAndGet(2);
bool b = ai($).compareAndSet(1, 2);
(void)b;
x = ai($).addAndGet(2);
x = ai($).getAndSet(2);
}
};
struct test_seq_cst_volatiles : rl::test_suite<test_seq_cst_volatiles, 2>
{
rl::jvolatile<int> flag0;
rl::jvolatile<int> flag1;
rl::jvolatile<int> turn;
rl::var<int> data;
void thread(unsigned index)
{
if (0 == index)
{
flag0($) = 1;
turn($) = 1;
while (flag1($) && 1 == turn($))
rl::yield(1, $);
data($) = 1;
flag0($) = 0;
}
else
{
flag1($) = 1;
turn($) = 0;
while (flag0($) && 0 == turn($))
rl::yield(1, $);
data($) = 2;
flag1($) = 0;
}
}
};
struct test_seq_cst_volatiles2 : rl::test_suite<test_seq_cst_volatiles2, 4>
{
rl::jvolatile<int> x;
rl::jvolatile<int> y;
int r1, r2, r3, r4;
void before()
{
r1 = r2 = r3 = r4 = 0;
}
void thread(unsigned index)
{
if (0 == index)
{
x($) = 0;
}
else if (1 == index)
{
y($) = 0;
}
else if (2 == index)
{
r1 = x($);
r2 = y($);
}
else if (3 == index)
{
r3 = y($);
r4 = x($);
}
}
void after()
{
RL_ASSERT(false == (r1 && !r2 && r3 && !r4));
}
};
template<int expected>
struct test_unitialized_var : rl::test_suite<test_unitialized_var<expected>, 2, rl::test_result_until_condition_hit>
{
rl::jvar<rl::jvar<int>*> www;
void thread(unsigned index)
{
if (0 == index)
{
www($) = new rl::jvar<int> (1);
}
else
{
while (0 == www($))
rl::yield(1, $);
int x = (*www($))($);
RL_UNTIL(x == expected);
}
}
};
int main()
{
rl::simulate_f tests[] =
{
//!!! broken &rl::simulate<test_unitialized_var<0> >,
&rl::simulate<test_unitialized_var<1> >,
&rl::simulate<test_seq_cst_volatiles>,
&rl::simulate<test_seq_cst_volatiles2>,
&rl::simulate<test_api>,
&rl::simulate<stack_test>,
};
for (size_t i = 0; i != sizeof(tests)/sizeof(*tests); ++i)
{
rl::ostringstream stream;
rl::test_params params;
params.iteration_count = 10000;
params.output_stream = &stream;
params.progress_stream = &stream;
params.context_bound = 2;
params.execution_depth_limit = 500;
if (false == tests[i](params))
{
std::cout << std::endl;
std::cout << "FAILED" << std::endl;
std::cout << stream.str();
return 1;
}
else
{
std::cout << params.test_name << "...OK" << std::endl;
}
}
std::cout << std::endl << "SUCCESS" << std::endl;
}
@@ -0,0 +1,43 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jtest", "jtest.vcproj", "{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "..\..\test\msvc8\rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Debug64|Win32 = Debug64|Win32
Debug64|x64 = Debug64|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.ActiveCfg = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.Build.0 = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|x64.ActiveCfg = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug64|Win32.ActiveCfg = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug64|Win32.Build.0 = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug64|x64.ActiveCfg = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.ActiveCfg = Release|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.Build.0 = Release|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|x64.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.ActiveCfg = Debug|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.Build.0 = Debug|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|Win32.ActiveCfg = Debug64|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|Win32.Build.0 = Debug64|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|x64.ActiveCfg = Debug64|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|x64.Build.0 = Debug64|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.ActiveCfg = Release|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,205 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="jtest"
ProjectGUID="{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}"
RootNamespace="jtest"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="4"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="2"
WarningLevel="4"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\jtest.cpp"
>
</File>
<File
RelativePath="..\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\stdafx.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,43 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jtest", "jtest.vcproj", "{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "..\..\test\msvc9\rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Debug64|Win32 = Debug64|Win32
Debug64|x64 = Debug64|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.ActiveCfg = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.Build.0 = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|x64.ActiveCfg = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug64|Win32.ActiveCfg = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug64|Win32.Build.0 = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug64|x64.ActiveCfg = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.ActiveCfg = Release|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.Build.0 = Release|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|x64.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.ActiveCfg = Debug|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.Build.0 = Debug|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|Win32.ActiveCfg = Debug64|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|Win32.Build.0 = Debug64|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|x64.ActiveCfg = Debug64|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|x64.Build.0 = Debug64|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.ActiveCfg = Release|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,200 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="jtest"
ProjectGUID="{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}"
RootNamespace="jtest"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="4"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="2"
WarningLevel="4"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\jtest.cpp"
>
</File>
<File
RelativePath="..\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\stdafx.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,2 @@
#include "stdafx.h"
@@ -0,0 +1,6 @@
#pragma once
#define RL_JAVA_MODE
#include "../../relacy/pch.hpp"
@@ -0,0 +1,581 @@
#include "stdafx.h"
//#define RL_MSVC_OUTPUT
#include "../relacy/relacy_std.hpp"
#include "memory_order.hpp"
#include "fence.hpp"
#include "data_race.hpp"
#include "mutex.hpp"
#include "condvar.hpp"
#include "semaphore.hpp"
#include "event.hpp"
#include "scheduler.hpp"
#include "compare_swap.hpp"
#include "wfmo.hpp"
#include "thread_local.hpp"
#include "dyn_thread.hpp"
#include "memory.hpp"
#include "pthread.hpp"
#include "windows.hpp"
#include "addr_hash.hpp"
#include "futex.hpp"
#include "../relacy/windows.h"
#include "../relacy/pthread.h"
#include <cstdio>
#include <climits>
class queue_t
{
public:
queue_t()
{
VAR(head) = 0;
VAR(tail) = 0;
pthread_mutex_init(&mtx, 0);
pthread_cond_init(&cv, 0);
}
~queue_t()
{
pthread_mutex_destroy(&mtx);
pthread_cond_destroy(&cv);
}
void enqueue(void* data)
{
node_t* n = new node_t;
n->VAR(next) = 0;
n->VAR(data) = data;
bool was_empty = false;
pthread_mutex_lock(&mtx);
if (VAR(head) == 0)
{
was_empty = true;
VAR(head) = n;
VAR(tail) = n;
}
else
{
VAR(tail)->VAR(next) = n;
VAR(tail) = n;
}
pthread_mutex_unlock(&mtx);
if (was_empty)
pthread_cond_broadcast(&cv);
}
void* dequeue()
{
node_t* n = 0;
pthread_mutex_lock(&mtx);
while (VAR(head) == 0)
pthread_cond_wait(&cv, &mtx);
n = VAR(head);
if (n->VAR(next) == 0)
VAR(tail) = 0;
VAR(head) = n->VAR(next);
pthread_mutex_unlock(&mtx);
void* data = n->VAR(data);
delete n;
return data;
}
private:
struct node_t
{
VAR_T(node_t*) next;
VAR_T(void*) data;
};
VAR_T(node_t*) head;
VAR_T(node_t*) tail;
pthread_mutex_t mtx;
pthread_cond_t cv;
};
void* enqueue_thread(void* ctx)
{
queue_t* q = static_cast<queue_t*>(ctx);
for (size_t i = 0; i != 4; i += 1)
q->enqueue((void*)(i + 1));
return 0;
}
void* dequeue_thread(void* ctx)
{
queue_t* q = static_cast<queue_t*>(ctx);
for (size_t i = 0; i != 4; i += 1)
{
void* data = q->dequeue();
assert((int)(uintptr_t)data >= 1 && (int)(uintptr_t)data <= 4);
}
return 0;
}
void queue_test()
{
queue_t q;
pthread_t th [4];
for (size_t i = 0; i != 2; i += 1)
pthread_create(&th[i], 0, enqueue_thread, &q);
for (size_t i = 2; i != 4; i += 1)
pthread_create(&th[i], 0, dequeue_thread, &q);
void* res = 0;
for (size_t i = 0; i != 4; i += 1)
pthread_join(th[i], &res);
}
/*
class recursive_timed_mutex
{
public:
recursive_timed_mutex()
{
sema.init(false, 1, 1, $);
owner = -1;
recursion_count = 0;
}
~recursive_timed_mutex()
{
assert(owner == -1 && recursion_count == 0);
sema.deinit($);
}
void lock(rl::debug_info_param info)
{
rl::context& c = rl::ctx();
if (owner == c.current_thread())
{
RL_HIST(rl::user_msg_event) {"recursive mutex lock"} RL_HIST_END();
assert(recursion_count > 0);
recursion_count += 1;
}
else
{
sema.wait(false, false, info);
assert(owner == -1 && recursion_count == 0);
owner = c.current_thread();
recursion_count = 1;
}
}
bool try_lock(rl::debug_info_param info)
{
rl::context& c = rl::ctx();
if (owner == c.current_thread())
{
RL_HIST(rl::user_msg_event) {"recursive mutex try lock"} RL_HIST_END();
assert(recursion_count > 0);
recursion_count += 1;
return true;
}
else
{
rl::sema_wakeup_reason r = sema.wait(true, false, info);
if (r == rl::sema_wakeup_reason_success)
{
assert(owner == -1 && recursion_count == 0);
owner = c.current_thread();
recursion_count = 1;
return true;
}
else
{
return false;
}
}
}
void unlock(rl::debug_info_param info)
{
rl::context& c = rl::ctx();
assert(owner == c.current_thread() && recursion_count > 0);
RL_HIST(rl::user_msg_event) {"recursive mutex unlock"} RL_HIST_END();
recursion_count -= 1;
if (recursion_count == 0)
{
owner = -1;
unsigned prev;
sema.post(1, prev, info);
}
}
bool timed_lock(rl::debug_info_param info, ... )
{
rl::context& c = rl::ctx();
if (owner == c.current_thread())
{
RL_HIST(rl::user_msg_event) {"recursive mutex timed lock"} RL_HIST_END();
assert(recursion_count > 0);
recursion_count += 1;
return true;
}
else
{
rl::sema_wakeup_reason r = sema.wait(false, true, info);
if (r == rl::sema_wakeup_reason_success)
{
assert(owner == -1 && recursion_count == 0);
owner = c.current_thread();
recursion_count = 1;
return true;
}
else
{
return false;
}
}
}
private:
struct tag_t;
rl::semaphore<tag_t> sema;
rl::thread_id_t owner;
int recursion_count;
recursive_timed_mutex(recursive_timed_mutex const&);
recursive_timed_mutex& operator = (recursive_timed_mutex const&);
};
*/
class recursive_timed_mutex
{
public:
recursive_timed_mutex()
{
mtx = CreateMutex(0, 0, 0);
}
~recursive_timed_mutex()
{
CloseHandle(mtx);
}
void lock(rl::debug_info_param info)
{
rl::rl_WaitForSingleObject(mtx, INFINITE, info);
}
bool try_lock(rl::debug_info_param info)
{
return WAIT_OBJECT_0 == rl::rl_WaitForSingleObject(mtx, 0, info);
}
void unlock(rl::debug_info_param info)
{
rl::rl_ReleaseMutex(mtx, info);
}
bool timed_lock(rl::debug_info_param info, ... /*abs_time*/)
{
return WAIT_OBJECT_0 == rl::rl_WaitForSingleObject(mtx, 1, info);
}
private:
HANDLE mtx;
recursive_timed_mutex(recursive_timed_mutex const&);
recursive_timed_mutex& operator = (recursive_timed_mutex const&);
};
struct recursive_timed_mutex_test : rl::test_suite<recursive_timed_mutex_test, 3>
{
recursive_timed_mutex mtx;
VAR_T(int) data;
void thread(unsigned idx)
{
if (idx)
{
mtx.lock($);
mtx.lock($);
VAR(data) = 1;
mtx.unlock($);
mtx.unlock($);
}
else
{
if (mtx.timed_lock($))
{
VAR(data) = 2;
mtx.unlock($);
}
}
}
void after()
{
//assert(VAR(data) != 2);
}
};
int main()
{
//rl::test_params p;
//p.search_type = rl::sched_full;
//p.context_bound = 5;
//p.execution_depth_limit = 200;
//rl::simulate<test_pthread_condvar>(p);
//if (rand() <= RAND_MAX) return 0;
//rl::execute<queue_test, 4>();
//if (rand() <= RAND_MAX) return 0;
//rl::test_params p;
//p.initial_state = "1000000";
//p.iteration_count = 2000000;
//p.collect_history = true;
//p.output_history = true;
//p.search_type = rl::sched_bound;
//p.search_type = rl::sched_full;
//p.execution_depth_limit = 500;
//p.context_bound = 1;
//rl::simulate<test_pthread_condvar>(p);
//std::cout << "scheduler state = \"" << p.final_state << "\"" << std::endl;
//std::cout << std::endl;
//if (rand() <= RAND_MAX) return 0;
//rl::test_params p;
//p.iteration_count = 80000000;
//p.initial_state = "50000000";
//p.search_type = rl::fair_context_bound_scheduler_type;
//p.context_bound = 1;
//p.collect_history = true;
//p.output_history = true;
//rl::simulate<test>(p);
//if (rand() <= RAND_MAX) return 0;
//rl::test_params p;
//p.context_bound = 1;
//p.iteration_count = 1000;
//p.search_type = rl::fair_full_search_scheduler_type;
//p.search_type = rl::random_scheduler_type;
//p.collect_history = true;
//p.output_history = true;
//p.execution_depth_limit = 1000;
//p.initial_state = "550 24 3 0 0 3 0 0 3 0 0 3 0 0 2 0 4 2 0 0 2 0 4 2 1 0 2 0 4 3 1 0 3 0 0 2 0 0 1 0 4 2 0 4 3 0 0 3 0 0 2 0 4 3 1 0 3 0 0 2 1 0 2 0 4 2 1 0 2 1 0 2 1 4";
//bool result = rl::simulate<test>(p);
//std::cout << "result=" << result << std::endl;
//simulate<my_test>();
//if (rand() <= RAND_MAX) return 0;
rl::simulate_f tests[] =
{
#if 1
&rl::simulate<test_FlushProcessWriteBuffers>,
&rl::simulate<test_addr_hash>,
&rl::simulate<test_addr_hash2>,
//!!! fails &rl::simulate<sched_load_test>,
&rl::simulate<test_memory_allocation>,
// memory model
&rl::simulate<test_pthread_thread>,
&rl::simulate<test_pthread_mutex>,
&rl::simulate<test_pthread_rwlock>,
&rl::simulate<test_pthread_condvar>,
&rl::simulate<test_pthread_condvar2>,
&rl::simulate<test_pthread_sem>,
&rl::simulate<coherent_read_read_test>,
&rl::simulate<order_relaxed_test<0> >,
&rl::simulate<order_relaxed_test<1> >,
&rl::simulate<order_relaxed_test<2> >,
&rl::simulate<order_relaxed_test<3> >,
&rl::simulate<order_relaxed_test<4> >,
&rl::simulate<reorder_single_var_test>,
&rl::simulate<acq_rel_test>,
&rl::simulate<seq_cst_test<0> >,
&rl::simulate<seq_cst_test<1> >,
&rl::simulate<reordering_test>,
&rl::simulate<reordering_test2>,
&rl::simulate<test_win_thread>,
&rl::simulate<test_win_mutex>,
&rl::simulate<test_win_cs>,
&rl::simulate<test_win_condvar>,
&rl::simulate<test_win_condvar_srw>,
&rl::simulate<test_win_sem>,
&rl::simulate<test_win_event>,
&rl::simulate<modification_order_test>,
&rl::simulate<transitive_test>,
&rl::simulate<cc_transitive_test>,
&rl::simulate<occasional_test>,
// fences
&rl::simulate<fence_synch_test<0, 0> >,
&rl::simulate<fence_synch_test<1, 0> >,
&rl::simulate<fence_synch_test<2, 0> >,
&rl::simulate<fence_synch_test<0, 1> >,
&rl::simulate<fence_synch_test<1, 1> >,
&rl::simulate<fence_synch_test<2, 1> >,
&rl::simulate<two_fence_synch_test>,
&rl::simulate<seq_cst_fence_test<0> >,
&rl::simulate<seq_cst_fence_test<1> >,
// data races
&rl::simulate<race_ld_ld_test>,
&rl::simulate<race_ld_st_test>,
&rl::simulate<race_st_st_test>,
&rl::simulate<race_seq_ld_ld_test>,
&rl::simulate<race_seq_ld_st_test>,
&rl::simulate<race_seq_st_ld_test>,
&rl::simulate<race_seq_st_st_test>,
&rl::simulate<race_uninit_test>,
&rl::simulate<race_indirect_test>,
// compare_exchange
&rl::simulate<cas_spurious_fail_test<0> >,
&rl::simulate<cas_spurious_fail_test<1> >,
&rl::simulate<cas_spurious_fail_test<2> >,
// mutex
&rl::simulate<test_deadlock>,
&rl::simulate<test_deadlock2>,
&rl::simulate<test_mutex_destuction>,
&rl::simulate<test_mutex_destuction2>,
&rl::simulate<test_mutex_recursion>,
&rl::simulate<test_mutex_recursion_error>,
&rl::simulate<test_mutex_unlock_error>,
&rl::simulate<test_mutex_leak>,
&rl::simulate<test_mutex>,
&rl::simulate<test_mutex_try_lock>,
// futex
&rl::simulate<test_futex>,
&rl::simulate<test_futex_deadlock>,
&rl::simulate<test_futex_sync1>,
&rl::simulate<test_futex_sync2>,
&rl::simulate<test_futex_intr>,
// condition variable
&rl::simulate<test_condvar>,
&rl::simulate<test_condvar2>,
// semaphore
&rl::simulate<test_semaphore>,
&rl::simulate<test_semaphore_atomic>,
// event
&rl::simulate<test_event_auto>,
&rl::simulate<test_event_manual>,
&rl::simulate<test_event_atomic>,
//wfmo
&rl::simulate<test_wfmo_all>,
&rl::simulate<test_wfmo_single>,
&rl::simulate<test_wfmo_timeout>,
&rl::simulate<test_wfmo_try>,
&rl::simulate<test_wfmo_mixed>,
&rl::simulate<test_wfmo_mixed2>,
&rl::simulate<test_wfmo_event_all>,
&rl::simulate<test_wfmo_event_any>,
&rl::simulate<test_wfmo_atomic>,
// thread local storage
&rl::simulate<tls_basic_test>,
&rl::simulate<tls_reset_test>,
&rl::simulate<tls_global_test>,
&rl::simulate<tls_win32_test>,
// dynamic thread
&rl::simulate<dyn_thread_basic_test>,
&rl::simulate<dyn_thread_win32_test>,
&rl::simulate<dyn_thread_visibility_test>,
#endif
};
for (size_t sched = 0; sched != rl::sched_count; ++sched)
{
std::cout << format((rl::scheduler_type_e)sched) << " tests:" << std::endl;
for (size_t i = 0; i != sizeof(tests)/sizeof(*tests); ++i)
{
//!!! make it work under sched_full
if (sched == rl::sched_full
&& (tests[i] == (rl::simulate_f)&rl::simulate<test_pthread_condvar>
|| tests[i] == (rl::simulate_f)&rl::simulate<test_win_condvar>))
continue;
rl::ostringstream stream;
rl::test_params params;
params.search_type = (rl::scheduler_type_e)sched;
params.iteration_count =
(params.test_result == rl::test_result_success ? 100000 : 500);
params.output_stream = &stream;
params.progress_stream = &stream;
params.context_bound = 2;
params.execution_depth_limit = 500;
if (false == tests[i](params))
{
std::cout << std::endl;
std::cout << "FAILED" << std::endl;
std::cout << stream.str();
std::cout << std::endl;
return 1;
}
else
{
std::cout << params.test_name << "...OK" << std::endl;
}
}
std::cout << std::endl;
}
rl::simulate_f scheduler_tests[] =
{
&rl::simulate<livelock_test>,
&rl::simulate<yield_livelock_test>,
};
std::cout << "full search scheduler tests:" << std::endl;
for (size_t i = 0; i != sizeof(scheduler_tests)/sizeof(*scheduler_tests); ++i)
{
rl::ostringstream stream;
rl::test_params params;
params.search_type = rl::sched_full;
params.output_stream = &stream;
params.progress_stream = &stream;
params.context_bound = 2;
params.execution_depth_limit = 500;
if (false == scheduler_tests[i](params))
{
std::cout << std::endl;
std::cout << "FAILED" << std::endl;
std::cout << stream.str();
return 1;
}
else
{
std::cout << params.test_name << "...OK" << std::endl;
}
}
std::cout << std::endl;
std::cout << "SUCCESS" << std::endl;
}
@@ -0,0 +1,29 @@
#pragma once
#include "../relacy/relacy_std.hpp"
struct test_memory_allocation : rl::test_suite<test_memory_allocation, 2>
{
void thread(unsigned /*index*/)
{
VAR_T(int)* p1 = new VAR_T(int) (5), i1 = 5, * p11 = new VAR_T(int) (6);
VAR(p1[0]) = 1;
delete p1, delete p11;
VAR_T(int)* p2 = new VAR_T(int) [10], i2 = 6, *p22 = new VAR_T(int) [20];
VAR(p2[0]) = 1;
delete [] p2, delete [] p22;
void* p3 = malloc(10), *i3 = 0, *p33 = malloc(20);
free(p3), free(p33);
void* p4 = malloc(sizeof(int));
int* i4 = new (p4) int (11);
free(p4);
//RL_ASSERT(false);
(void)i1, (void)i2, (void)i3; (void)i4;
}
};
@@ -0,0 +1,415 @@
#pragma once
#include "../relacy/relacy_std.hpp"
struct coherent_read_read_test : rl::test_suite<coherent_read_read_test, 3>
{
std::atomic<int> x;
std::atomic<int> y;
void before()
{
x($) = 0;
y($) = 0;
}
void thread(unsigned th)
{
if (0 == th)
x.store(1, rl::memory_order_relaxed);
else if (1 == th)
{
if (0 == x.load(rl::memory_order_relaxed))
return;
y.store(1, rl::memory_order_release);
x.load(rl::memory_order_relaxed);
}
else
{
if (0 == y.load(rl::memory_order_acquire))
return;
RL_ASSERT(1 == x.load(rl::memory_order_relaxed));
}
}
};
template<int index>
struct order_relaxed_test : rl::test_suite<order_relaxed_test<index>, 2>
{
std::atomic<int> x1;
std::atomic<int> x2;
void before()
{
x1($) = 0;
x2($) = 0;
}
void thread(unsigned th)
{
if (th)
{
x1.store(1, order().first, $);
x2.store(1, order().first, $);
}
else
{
int y2 = x2.load(order().second, $);
int y1 = x1.load(order().second, $);
//RL_UNTIL(0 == y1 && 0 != y2);
(void)y2;
(void)y1;
}
}
std::pair<rl::memory_order, rl::memory_order> order()
{
switch (index)
{
default: RL_VERIFY(false);
case 0: return std::make_pair(rl::mo_relaxed, rl::mo_relaxed);
case 1: return std::make_pair(rl::mo_release, rl::mo_relaxed);
case 2: return std::make_pair(rl::mo_seq_cst, rl::mo_relaxed);
case 3: return std::make_pair(rl::mo_relaxed, rl::mo_acquire);
case 4: return std::make_pair(rl::mo_relaxed, rl::mo_seq_cst);
}
}
};
struct reorder_single_var_test : rl::test_suite<reorder_single_var_test, 2>
{
std::atomic<int> x;
void before()
{
x($) = 0;
}
void thread(unsigned index)
{
if (index)
{
x.store(1, rl::memory_order_relaxed);
}
else
{
int y1 = x.load(rl::memory_order_relaxed);
int y2 = x.load(rl::memory_order_relaxed);
RL_ASSERT(y1 == 0 || y2 == 1);
}
}
};
struct acq_rel_test : rl::test_suite<acq_rel_test, 2>
{
std::atomic<int> x;
rl::var<int> y;
void before()
{
x($) = 0;
}
void thread(unsigned index)
{
if (index)
{
VAR(y) = 1;
x.store(1, std::memory_order_release);
}
else
{
int f = x.load(rl::memory_order_acquire);
if (f)
{
int d = VAR(y);
RL_ASSERT(1 == d);
}
}
}
};
template<int index>
struct seq_cst_test : rl::test_suite<seq_cst_test<index>, 4,
(rl::test_result_e)((1 - index) * rl::test_result_until_condition_hit)>
{
std::atomic<int> x1;
std::atomic<int> x2;
int res;
void before()
{
x1($) = 0;
x2($) = 0;
res = 0;
}
void thread(unsigned th)
{
if (0 == th)
{
x1.store(1, order().first, $);
}
else if (1 == th)
{
x2.store(1, order().first, $);
}
else if (2 == th)
{
int v1 = x1.load(order().second, $);
int v2 = x2.load(order().second, $);
res += (v1 == 1 && v2 == 0);
}
else if (3 == th)
{
int v2 = x2.load(order().second, $);
int v1 = x1.load(order().second, $);
res += (v2 == 1 && v1 == 0);
}
}
void after()
{
if ((void)0, 0 == index)
{
RL_UNTIL(2 == res);
}
else
{
RL_ASSERT(2 != res);
}
}
std::pair<rl::memory_order, rl::memory_order> order()
{
switch (index)
{
default: RL_VERIFY(false);
case 0: return std::make_pair(rl::mo_release, rl::mo_acquire);
case 1: return std::make_pair(rl::mo_seq_cst, rl::mo_seq_cst);
}
}
};
struct modification_order_test : rl::test_suite<modification_order_test, 2>
{
std::atomic<int> a;
rl::var<int> x;
void before()
{
a($) = 0;
x($) = 0;
}
void thread(unsigned index)
{
if (index)
{
x($) = 1;
a.store(1, rl::memory_order_release);
a.store(2, rl::memory_order_relaxed);
}
else
{
if (a.load(rl::memory_order_acquire))
x($).load();
}
}
};
struct reordering_test : rl::test_suite<reordering_test, 3>
{
std::atomic<int> x;
std::atomic<int> y;
std::atomic<int> r;
void before()
{
x($) = 0;
y($) = 0;
r($) = 0;
}
void thread(unsigned index)
{
if (0 == index)
{
x.store(1, rl::memory_order_relaxed);
}
else if (1 == index)
{
if (x.load(rl::memory_order_relaxed))
r.store(1, rl::memory_order_relaxed);
y.store(1, rl::memory_order_release);
}
else
{
if (y.load(rl::memory_order_acquire))
{
if (r.load(rl::memory_order_relaxed))
{
RL_ASSERT(x.load(rl::memory_order_relaxed));
}
}
}
}
};
struct reordering_test2 : rl::test_suite<reordering_test2, 3, rl::test_result_until_condition_hit>
{
std::atomic<int> x1;
std::atomic<int> x2;
std::atomic<int> y;
std::atomic<int> r;
void before()
{
std::atomic<char*> x (0);
char* ch = 0;
x.compare_exchange_weak(ch, 0, std::memory_order_seq_cst);
x1($) = 0;
x2($) = 0;
y($) = 0;
r($) = 0;
}
void thread(unsigned index)
{
if (0 == index)
{
x1.store(1, rl::memory_order_relaxed);
x2.store(1, rl::memory_order_relaxed);
}
else if (1 == index)
{
if (x2.load(rl::memory_order_relaxed))
r.store(1, rl::memory_order_relaxed);
y.store(1, rl::memory_order_release);
}
else
{
if (y.load(rl::memory_order_acquire))
{
if (r.load(rl::memory_order_relaxed))
{
RL_UNTIL(0 == x1.load(rl::memory_order_relaxed));
}
}
}
}
};
struct transitive_test : rl::test_suite<transitive_test, 3>
{
std::atomic<int> x;
rl::var<int> y;
void before()
{
x($) = 0;
}
void thread(unsigned index)
{
if (0 == index)
{
VAR(y) = 1;
x.fetch_add(1, rl::memory_order_release);
}
else if (1 == index)
{
x.fetch_add(2, rl::memory_order_acquire);
}
else
{
x.load(rl::memory_order_acquire);
int w = x.load(rl::memory_order_acquire);
if (1 == w || 3 == w)
{
y($).load();
}
}
}
};
struct cc_transitive_test : rl::test_suite<cc_transitive_test, 3>
{
std::atomic<int> x;
std::atomic<int> y;
void before()
{
x.store(0, std::memory_order_relaxed);
y.store(0, std::memory_order_relaxed);
}
void thread(unsigned index)
{
if (0 == index)
{
x.store(1, std::memory_order_relaxed);
}
else if (1 == index)
{
if (x.load(std::memory_order_relaxed))
y.store(1, std::memory_order_release);
}
else
{
if (y.load(std::memory_order_acquire))
assert(x.load(std::memory_order_relaxed));
}
}
};
struct occasional_test : rl::test_suite<occasional_test, 3, rl::test_result_until_condition_hit>
{
std::atomic<int> x, y, z;
void before()
{
x.store(0, std::memory_order_relaxed);
y.store(0, std::memory_order_relaxed);
z.store(0, std::memory_order_relaxed);
}
void thread(unsigned index)
{
if (0 == index)
{
x.store(1, rl::memory_order_relaxed);
y.store(1, rl::memory_order_release);
}
else if (1 == index)
{
if (y.load(rl::memory_order_relaxed))
z.store(1, rl::memory_order_release);
}
else
{
if (z.load(rl::memory_order_acquire))
{
RL_ASSERT(y.load(rl::memory_order_relaxed));
RL_UNTIL(0 == x.load(rl::memory_order_relaxed));
}
}
}
};
@@ -0,0 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{8C8174E2-2B2E-484D-9EB4-85D29347F22F}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{8C8174E2-2B2E-484D-9EB4-85D29347F22F}.Debug.ActiveCfg = Debug|Win32
{8C8174E2-2B2E-484D-9EB4-85D29347F22F}.Debug.Build.0 = Debug|Win32
{8C8174E2-2B2E-484D-9EB4-85D29347F22F}.Release.ActiveCfg = Release|Win32
{8C8174E2-2B2E-484D-9EB4-85D29347F22F}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal
@@ -0,0 +1,159 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="test"
ProjectGUID="{8C8174E2-2B2E-484D-9EB4-85D29347F22F}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="3"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/test.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/test.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/test.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\blocking_mutex.hpp">
</File>
<File
RelativePath="..\compare_swap.hpp">
</File>
<File
RelativePath="..\condvar.hpp">
</File>
<File
RelativePath="..\data_race.hpp">
</File>
<File
RelativePath="..\fence.hpp">
</File>
<File
RelativePath="..\foo.cpp">
</File>
<File
RelativePath="..\main.cpp">
</File>
<File
RelativePath="..\memory_order.hpp">
</File>
<File
RelativePath="..\scheduler.hpp">
</File>
<File
RelativePath="..\stdafx.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\stdafx.h">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,194 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{99882C71-3316-411F-A8AE-EC1E40702040}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "peterson", "..\..\example\peterson\msvc8\peterson.vcproj", "{D4756EE9-3953-4E17-B1B5-E89F853303C1}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "proxy_collector", "..\..\example\proxy_collector\msvc8\proxy_collector.vcproj", "{31994C0C-3BAD-4F25-8BC8-3206FF349B29}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ref_counting", "..\..\example\ref_counting\msvc8\ref_counting.vcproj", "{31994C0C-3BAD-4F25-8BC8-3206FF349B28}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stack", "..\..\example\stack\msvc8\stack.vcproj", "{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spsc_queue", "..\..\example\spsc_queue\msvc8\spsc_queue.vcproj", "{2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "condvar", "..\..\example\condvar\msvc8\condvar.vcproj", "{6CC59CF8-408B-441B-8F65-15651210CB82}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smr", "..\..\example\smr\msvc8\smr.vcproj", "{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mutex_business_logic", "..\..\example\mutex_business_logic\msvc8\mutex_business_logic.vcproj", "{B03A7216-E196-44C6-8861-C77D90055512}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ws_deque", "..\..\example\ws_deque\msvc8\ws_deque.vcproj", "{0B597F19-DEBB-4832-B520-9A93A286D595}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jtest", "..\..\jtest\msvc8\jtest.vcproj", "{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntest", "..\..\ntest\msvc8\ntest.vcproj", "{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cli_ws_deque", "..\..\example\cli_ws_deque\msvc8\cli_ws_deque.vcproj", "{967F376B-BDBF-4AC8-9325-371CC8ABD8FD}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "java_ws_deque", "..\..\example\java_ws_deque\msvc8\java_ws_deque.vcproj", "{9E88433F-779E-4461-9963-35E3338873AC}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Profile|Win32 = Profile|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.ActiveCfg = Debug|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.Build.0 = Debug|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Profile|Win32.ActiveCfg = Profile|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.ActiveCfg = Release|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.Build.0 = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.Build.0 = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32
{D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.ActiveCfg = Debug|Win32
{D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.Build.0 = Debug|Win32
{D4756EE9-3953-4E17-B1B5-E89F853303C1}.Profile|Win32.ActiveCfg = Release|Win32
{D4756EE9-3953-4E17-B1B5-E89F853303C1}.Profile|Win32.Build.0 = Release|Win32
{D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.ActiveCfg = Release|Win32
{D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.Build.0 = Release|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Debug|Win32.ActiveCfg = Debug|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Debug|Win32.Build.0 = Debug|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Profile|Win32.ActiveCfg = Profile|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Profile|Win32.Build.0 = Profile|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Release|Win32.ActiveCfg = Release|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Release|Win32.Build.0 = Release|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Debug|Win32.ActiveCfg = Debug|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Debug|Win32.Build.0 = Debug|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Profile|Win32.ActiveCfg = Release|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Profile|Win32.Build.0 = Release|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Release|Win32.ActiveCfg = Release|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Release|Win32.Build.0 = Release|Win32
{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Debug|Win32.ActiveCfg = Debug|Win32
{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Debug|Win32.Build.0 = Debug|Win32
{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Profile|Win32.ActiveCfg = Release|Win32
{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Profile|Win32.Build.0 = Release|Win32
{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Release|Win32.ActiveCfg = Release|Win32
{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Release|Win32.Build.0 = Release|Win32
{2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Debug|Win32.ActiveCfg = Debug|Win32
{2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Debug|Win32.Build.0 = Debug|Win32
{2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Profile|Win32.ActiveCfg = Release|Win32
{2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Profile|Win32.Build.0 = Release|Win32
{2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Release|Win32.ActiveCfg = Release|Win32
{2F0B1A3B-27CA-47D4-A9D1-5EC66BB0A85B}.Release|Win32.Build.0 = Release|Win32
{6CC59CF8-408B-441B-8F65-15651210CB82}.Debug|Win32.ActiveCfg = Debug|Win32
{6CC59CF8-408B-441B-8F65-15651210CB82}.Debug|Win32.Build.0 = Debug|Win32
{6CC59CF8-408B-441B-8F65-15651210CB82}.Profile|Win32.ActiveCfg = Release|Win32
{6CC59CF8-408B-441B-8F65-15651210CB82}.Profile|Win32.Build.0 = Release|Win32
{6CC59CF8-408B-441B-8F65-15651210CB82}.Release|Win32.ActiveCfg = Release|Win32
{6CC59CF8-408B-441B-8F65-15651210CB82}.Release|Win32.Build.0 = Release|Win32
{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Debug|Win32.ActiveCfg = Debug|Win32
{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Debug|Win32.Build.0 = Debug|Win32
{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Profile|Win32.ActiveCfg = Release|Win32
{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Profile|Win32.Build.0 = Release|Win32
{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Release|Win32.ActiveCfg = Release|Win32
{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Release|Win32.Build.0 = Release|Win32
{B03A7216-E196-44C6-8861-C77D90055512}.Debug|Win32.ActiveCfg = Debug|Win32
{B03A7216-E196-44C6-8861-C77D90055512}.Debug|Win32.Build.0 = Debug|Win32
{B03A7216-E196-44C6-8861-C77D90055512}.Profile|Win32.ActiveCfg = Release|Win32
{B03A7216-E196-44C6-8861-C77D90055512}.Profile|Win32.Build.0 = Release|Win32
{B03A7216-E196-44C6-8861-C77D90055512}.Release|Win32.ActiveCfg = Release|Win32
{B03A7216-E196-44C6-8861-C77D90055512}.Release|Win32.Build.0 = Release|Win32
{0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.ActiveCfg = Debug|Win32
{0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.Build.0 = Debug|Win32
{0B597F19-DEBB-4832-B520-9A93A286D595}.Profile|Win32.ActiveCfg = Release|Win32
{0B597F19-DEBB-4832-B520-9A93A286D595}.Profile|Win32.Build.0 = Release|Win32
{0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.ActiveCfg = Release|Win32
{0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.Build.0 = Release|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.ActiveCfg = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.Build.0 = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Profile|Win32.ActiveCfg = Release|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Profile|Win32.Build.0 = Release|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.ActiveCfg = Release|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.Build.0 = Release|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.ActiveCfg = Debug|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.Build.0 = Debug|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Profile|Win32.ActiveCfg = Release|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Profile|Win32.Build.0 = Release|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.ActiveCfg = Release|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.Build.0 = Release|Win32
{967F376B-BDBF-4AC8-9325-371CC8ABD8FD}.Debug|Win32.ActiveCfg = Debug|Win32
{967F376B-BDBF-4AC8-9325-371CC8ABD8FD}.Debug|Win32.Build.0 = Debug|Win32
{967F376B-BDBF-4AC8-9325-371CC8ABD8FD}.Profile|Win32.ActiveCfg = Release|Win32
{967F376B-BDBF-4AC8-9325-371CC8ABD8FD}.Profile|Win32.Build.0 = Release|Win32
{967F376B-BDBF-4AC8-9325-371CC8ABD8FD}.Release|Win32.ActiveCfg = Release|Win32
{967F376B-BDBF-4AC8-9325-371CC8ABD8FD}.Release|Win32.Build.0 = Release|Win32
{9E88433F-779E-4461-9963-35E3338873AC}.Debug|Win32.ActiveCfg = Debug|Win32
{9E88433F-779E-4461-9963-35E3338873AC}.Debug|Win32.Build.0 = Debug|Win32
{9E88433F-779E-4461-9963-35E3338873AC}.Profile|Win32.ActiveCfg = Release|Win32
{9E88433F-779E-4461-9963-35E3338873AC}.Profile|Win32.Build.0 = Release|Win32
{9E88433F-779E-4461-9963-35E3338873AC}.Release|Win32.ActiveCfg = Release|Win32
{9E88433F-779E-4461-9963-35E3338873AC}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,615 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="rrd"
ProjectGUID="{D4F501D0-382D-4CBC-86F4-56181F383444}"
RootNamespace="rrd"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug64|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug64|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="front-end"
>
<File
RelativePath="..\..\relacy\atomic.hpp"
>
</File>
<File
RelativePath="..\..\relacy\atomic_events.hpp"
>
</File>
<File
RelativePath="..\..\relacy\atomic_fence.hpp"
>
</File>
<File
RelativePath="..\..\relacy\backoff.hpp"
>
</File>
<File
RelativePath="..\..\relacy\cli.hpp"
>
</File>
<File
RelativePath="..\..\relacy\cli_interlocked.hpp"
>
</File>
<File
RelativePath="..\..\relacy\cli_var.hpp"
>
</File>
<File
RelativePath="..\..\relacy\cli_volatile.hpp"
>
</File>
<File
RelativePath="..\..\relacy\java.hpp"
>
</File>
<File
RelativePath="..\..\relacy\java_atomic.hpp"
>
</File>
<File
RelativePath="..\..\relacy\java_var.hpp"
>
</File>
<File
RelativePath="..\..\relacy\java_volatile.hpp"
>
</File>
<File
RelativePath="..\..\relacy\var.hpp"
>
</File>
<File
RelativePath="..\..\relacy\volatile.hpp"
>
</File>
</Filter>
<Filter
Name="scheduler"
>
<File
RelativePath="..\..\relacy\context_bound_scheduler.hpp"
>
</File>
<File
RelativePath="..\..\relacy\full_search_scheduler.hpp"
>
</File>
<File
RelativePath="..\..\relacy\random_scheduler.hpp"
>
</File>
<File
RelativePath="..\..\relacy\scheduler.hpp"
>
</File>
</Filter>
<Filter
Name="base"
>
<File
RelativePath="..\..\relacy\base.hpp"
>
</File>
<File
RelativePath="..\..\relacy\foreach.hpp"
>
</File>
<File
RelativePath="..\..\relacy\pch.hpp"
>
</File>
<File
RelativePath="..\..\relacy\platform.hpp"
>
</File>
<File
RelativePath="..\..\relacy\random.hpp"
>
</File>
<File
RelativePath="..\..\relacy\signature.hpp"
>
</File>
</Filter>
<Filter
Name="stdlib"
>
<File
RelativePath="..\..\relacy\stdlib\condition_variable.hpp"
>
</File>
<File
RelativePath="..\..\relacy\stdlib\event.hpp"
>
</File>
<File
RelativePath="..\..\relacy\stdlib\mutex.hpp"
>
</File>
<File
RelativePath="..\..\relacy\stdlib\recursive_mutex.hpp"
>
</File>
<File
RelativePath="..\..\relacy\stdlib\semaphore.hpp"
>
</File>
<File
RelativePath="..\..\relacy\stdlib\shared_mutex.hpp"
>
</File>
</Filter>
<File
RelativePath="..\..\relacy\context.hpp"
>
</File>
<File
RelativePath="..\..\relacy\context_base.hpp"
>
</File>
<File
RelativePath="..\..\relacy\context_base_impl.hpp"
>
</File>
<File
RelativePath="..\..\relacy\history.hpp"
>
</File>
<File
RelativePath="..\..\relacy\memory.hpp"
>
</File>
<File
RelativePath="..\..\relacy\memory_order.hpp"
>
</File>
<File
RelativePath="..\..\relacy\pthread.h"
>
</File>
<File
RelativePath="..\..\relacy\relacy.hpp"
>
</File>
<File
RelativePath="..\..\relacy\relacy_cli.hpp"
>
</File>
<File
RelativePath="..\..\relacy\relacy_java.hpp"
>
</File>
<File
RelativePath="..\..\relacy\relacy_std.hpp"
>
</File>
<File
RelativePath="..\..\relacy\rmw.hpp"
>
</File>
<File
RelativePath="..\..\relacy\slab_allocator.hpp"
>
</File>
<File
RelativePath="..\..\relacy\sync_var.hpp"
>
</File>
<File
RelativePath="..\..\relacy\test_params.hpp"
>
</File>
<File
RelativePath="..\..\relacy\test_result.hpp"
>
</File>
<File
RelativePath="..\..\relacy\test_suite.hpp"
>
</File>
<File
RelativePath="..\..\relacy\thread.hpp"
>
</File>
<File
RelativePath="..\..\relacy\waitset.hpp"
>
</File>
<File
RelativePath="..\..\relacy\windows.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,56 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{99882C71-3316-411F-A8AE-EC1E40702040}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Debug64|Win32 = Debug64|Win32
Debug64|x64 = Debug64|x64
Profile|Win32 = Profile|Win32
Profile|x64 = Profile|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.ActiveCfg = Debug|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.Build.0 = Debug|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug|x64.ActiveCfg = Debug|x64
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug|x64.Build.0 = Debug|x64
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug64|Win32.ActiveCfg = Debug64|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug64|Win32.Build.0 = Debug64|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug64|x64.ActiveCfg = Debug64|x64
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug64|x64.Build.0 = Debug64|x64
{99882C71-3316-411F-A8AE-EC1E40702040}.Profile|Win32.ActiveCfg = Profile|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Profile|Win32.Build.0 = Profile|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Profile|x64.ActiveCfg = Profile|x64
{99882C71-3316-411F-A8AE-EC1E40702040}.Profile|x64.Build.0 = Profile|x64
{99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.ActiveCfg = Release|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.Build.0 = Release|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Release|x64.ActiveCfg = Release|x64
{99882C71-3316-411F-A8AE-EC1E40702040}.Release|x64.Build.0 = Release|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.ActiveCfg = Debug|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.Build.0 = Debug|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|Win32.ActiveCfg = Debug64|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|Win32.Build.0 = Debug64|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|x64.ActiveCfg = Debug64|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug64|x64.Build.0 = Debug64|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.Build.0 = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|x64.ActiveCfg = Debug64|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|x64.Build.0 = Debug64|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.ActiveCfg = Release|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,796 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="test"
ProjectGUID="{99882C71-3316-411F-A8AE-EC1E40702040}"
RootNamespace="test"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="4"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="4"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
EnableFiberSafeOptimizations="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
BufferSecurityCheck="false"
EnableEnhancedInstructionSet="2"
UsePrecompiledHeader="2"
WarningLevel="4"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
EnableFiberSafeOptimizations="true"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
BufferSecurityCheck="false"
EnableEnhancedInstructionSet="2"
UsePrecompiledHeader="2"
WarningLevel="4"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Profile|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/Ob0"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
EnableFiberSafeOptimizations="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
BufferSecurityCheck="false"
UsePrecompiledHeader="2"
WarningLevel="4"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Profile|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/Ob0"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
EnableFiberSafeOptimizations="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
BufferSecurityCheck="false"
UsePrecompiledHeader="2"
WarningLevel="4"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="0"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug64|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="4"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug64|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="4"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\compare_swap.hpp"
>
</File>
<File
RelativePath="..\condvar.hpp"
>
</File>
<File
RelativePath="..\data_race.hpp"
>
</File>
<File
RelativePath="..\event.hpp"
>
</File>
<File
RelativePath="..\fence.hpp"
>
</File>
<File
RelativePath="..\foo.cpp"
>
</File>
<File
RelativePath="..\main.cpp"
>
</File>
<File
RelativePath="..\memory_order.hpp"
>
</File>
<File
RelativePath="..\mutex.hpp"
>
</File>
<File
RelativePath="..\scheduler.hpp"
>
</File>
<File
RelativePath="..\semaphore.hpp"
>
</File>
<File
RelativePath="..\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Profile|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Profile|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug64|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug64|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\stdafx.h"
>
</File>
<File
RelativePath="..\todo.txt"
>
</File>
<File
RelativePath="..\wfmo.hpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,118 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{99882C71-3316-411F-A8AE-EC1E40702040}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ref_counting", "..\..\example\ref_counting\msvc9\ref_counting.vcproj", "{31994C0C-3BAD-4F25-8BC8-3206FF349B28}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "peterson", "..\..\example\peterson\msvc9\peterson.vcproj", "{D4756EE9-3953-4E17-B1B5-E89F853303C1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stack", "..\..\example\stack\msvc9\stack.vcproj", "{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "proxy_collector", "..\..\example\proxy_collector\msvc9\proxy_collector.vcproj", "{31994C0C-3BAD-4F25-8BC8-3206FF349B29}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntest", "..\..\ntest\msvc9\ntest.vcproj", "{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jtest", "..\..\jtest\msvc9\jtest.vcproj", "{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smr", "..\..\example\smr\msvc9\smr.vcproj", "{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spsc_queue", "..\..\example\spsc_queue\msvc9\spsc_queue.vcproj", "{3F32C4FA-E451-42BC-9E65-74129120B6E4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "condvar", "..\..\example\condvar\msvc9\condvar.vcproj", "{6CC59CF8-408B-441B-8F65-15651210CB82}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ws_deque", "..\..\example\ws_deque\msvc9\ws_deque.vcproj", "{0B597F19-DEBB-4832-B520-9A93A286D595}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples", "..\..\example\examples\msvc9\examples.vcproj", "{1EB73A6F-7F94-4ED4-8EB3-C245E773207A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Profile|Win32 = Profile|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.ActiveCfg = Debug|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.Build.0 = Debug|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Profile|Win32.ActiveCfg = Profile|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.ActiveCfg = Release|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.Build.0 = Release|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Debug|Win32.ActiveCfg = Debug|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Debug|Win32.Build.0 = Debug|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Profile|Win32.ActiveCfg = Release|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Profile|Win32.Build.0 = Release|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Release|Win32.ActiveCfg = Release|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B28}.Release|Win32.Build.0 = Release|Win32
{D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.ActiveCfg = Debug|Win32
{D4756EE9-3953-4E17-B1B5-E89F853303C1}.Debug|Win32.Build.0 = Debug|Win32
{D4756EE9-3953-4E17-B1B5-E89F853303C1}.Profile|Win32.ActiveCfg = Release|Win32
{D4756EE9-3953-4E17-B1B5-E89F853303C1}.Profile|Win32.Build.0 = Release|Win32
{D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.ActiveCfg = Release|Win32
{D4756EE9-3953-4E17-B1B5-E89F853303C1}.Release|Win32.Build.0 = Release|Win32
{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Debug|Win32.ActiveCfg = Debug|Win32
{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Debug|Win32.Build.0 = Debug|Win32
{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Profile|Win32.ActiveCfg = Release|Win32
{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Profile|Win32.Build.0 = Release|Win32
{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Release|Win32.ActiveCfg = Release|Win32
{4D6D7FC3-66D1-4F80-B434-2FDCBBFBC9F5}.Release|Win32.Build.0 = Release|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Debug|Win32.ActiveCfg = Debug|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Debug|Win32.Build.0 = Debug|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Profile|Win32.ActiveCfg = Profile|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Profile|Win32.Build.0 = Profile|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Release|Win32.ActiveCfg = Release|Win32
{31994C0C-3BAD-4F25-8BC8-3206FF349B29}.Release|Win32.Build.0 = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.Build.0 = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.ActiveCfg = Debug|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.Build.0 = Debug|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Profile|Win32.ActiveCfg = Release|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Profile|Win32.Build.0 = Release|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.ActiveCfg = Release|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.Build.0 = Release|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.ActiveCfg = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Debug|Win32.Build.0 = Debug|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Profile|Win32.ActiveCfg = Release|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Profile|Win32.Build.0 = Release|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.ActiveCfg = Release|Win32
{1889E8F4-47F7-48B6-9FC7-61FD7CD000C8}.Release|Win32.Build.0 = Release|Win32
{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Debug|Win32.ActiveCfg = Debug|Win32
{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Debug|Win32.Build.0 = Debug|Win32
{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Profile|Win32.ActiveCfg = Release|Win32
{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Profile|Win32.Build.0 = Release|Win32
{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Release|Win32.ActiveCfg = Release|Win32
{BC168133-5E3D-4691-BA15-8E0FD61DFDB5}.Release|Win32.Build.0 = Release|Win32
{3F32C4FA-E451-42BC-9E65-74129120B6E4}.Debug|Win32.ActiveCfg = Debug|Win32
{3F32C4FA-E451-42BC-9E65-74129120B6E4}.Debug|Win32.Build.0 = Debug|Win32
{3F32C4FA-E451-42BC-9E65-74129120B6E4}.Profile|Win32.ActiveCfg = Release|Win32
{3F32C4FA-E451-42BC-9E65-74129120B6E4}.Profile|Win32.Build.0 = Release|Win32
{3F32C4FA-E451-42BC-9E65-74129120B6E4}.Release|Win32.ActiveCfg = Release|Win32
{3F32C4FA-E451-42BC-9E65-74129120B6E4}.Release|Win32.Build.0 = Release|Win32
{6CC59CF8-408B-441B-8F65-15651210CB82}.Debug|Win32.ActiveCfg = Debug|Win32
{6CC59CF8-408B-441B-8F65-15651210CB82}.Debug|Win32.Build.0 = Debug|Win32
{6CC59CF8-408B-441B-8F65-15651210CB82}.Profile|Win32.ActiveCfg = Release|Win32
{6CC59CF8-408B-441B-8F65-15651210CB82}.Profile|Win32.Build.0 = Release|Win32
{6CC59CF8-408B-441B-8F65-15651210CB82}.Release|Win32.ActiveCfg = Release|Win32
{6CC59CF8-408B-441B-8F65-15651210CB82}.Release|Win32.Build.0 = Release|Win32
{0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.ActiveCfg = Debug|Win32
{0B597F19-DEBB-4832-B520-9A93A286D595}.Debug|Win32.Build.0 = Debug|Win32
{0B597F19-DEBB-4832-B520-9A93A286D595}.Profile|Win32.ActiveCfg = Release|Win32
{0B597F19-DEBB-4832-B520-9A93A286D595}.Profile|Win32.Build.0 = Release|Win32
{0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.ActiveCfg = Release|Win32
{0B597F19-DEBB-4832-B520-9A93A286D595}.Release|Win32.Build.0 = Release|Win32
{1EB73A6F-7F94-4ED4-8EB3-C245E773207A}.Debug|Win32.ActiveCfg = Debug|Win32
{1EB73A6F-7F94-4ED4-8EB3-C245E773207A}.Debug|Win32.Build.0 = Debug|Win32
{1EB73A6F-7F94-4ED4-8EB3-C245E773207A}.Profile|Win32.ActiveCfg = Release|Win32
{1EB73A6F-7F94-4ED4-8EB3-C245E773207A}.Profile|Win32.Build.0 = Release|Win32
{1EB73A6F-7F94-4ED4-8EB3-C245E773207A}.Release|Win32.ActiveCfg = Release|Win32
{1EB73A6F-7F94-4ED4-8EB3-C245E773207A}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,523 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="rrd"
ProjectGUID="{D4F501D0-382D-4CBC-86F4-56181F383444}"
RootNamespace="rrd"
Keyword="Win32Proj"
TargetFrameworkVersion="0"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="front-end"
>
<File
RelativePath="..\..\relacy\atomic.hpp"
>
</File>
<File
RelativePath="..\..\relacy\atomic_events.hpp"
>
</File>
<File
RelativePath="..\..\relacy\atomic_fence.hpp"
>
</File>
<File
RelativePath="..\..\relacy\backoff.hpp"
>
</File>
<File
RelativePath="..\..\relacy\cli.hpp"
>
</File>
<File
RelativePath="..\..\relacy\cli_interlocked.hpp"
>
</File>
<File
RelativePath="..\..\relacy\cli_var.hpp"
>
</File>
<File
RelativePath="..\..\relacy\cli_volatile.hpp"
>
</File>
<File
RelativePath="..\..\relacy\java.hpp"
>
</File>
<File
RelativePath="..\..\relacy\java_atomic.hpp"
>
</File>
<File
RelativePath="..\..\relacy\java_var.hpp"
>
</File>
<File
RelativePath="..\..\relacy\java_volatile.hpp"
>
</File>
<File
RelativePath="..\..\relacy\var.hpp"
>
</File>
<File
RelativePath="..\..\relacy\volatile.hpp"
>
</File>
</Filter>
<Filter
Name="scheduler"
>
<File
RelativePath="..\..\relacy\context_bound_scheduler.hpp"
>
</File>
<File
RelativePath="..\..\relacy\full_search_scheduler.hpp"
>
</File>
<File
RelativePath="..\..\relacy\random_scheduler.hpp"
>
</File>
<File
RelativePath="..\..\relacy\scheduler.hpp"
>
</File>
</Filter>
<Filter
Name="base"
>
<File
RelativePath="..\..\relacy\base.hpp"
>
</File>
<File
RelativePath="..\..\relacy\foreach.hpp"
>
</File>
<File
RelativePath="..\..\relacy\pch.hpp"
>
</File>
<File
RelativePath="..\..\relacy\platform.hpp"
>
</File>
<File
RelativePath="..\..\relacy\random.hpp"
>
</File>
<File
RelativePath="..\..\relacy\signature.hpp"
>
</File>
</Filter>
<Filter
Name="stdlib"
>
<File
RelativePath="..\..\relacy\stdlib\condition_variable.hpp"
>
</File>
<File
RelativePath="..\..\relacy\stdlib\event.hpp"
>
</File>
<File
RelativePath="..\..\relacy\stdlib\mutex.hpp"
>
</File>
<File
RelativePath="..\..\relacy\stdlib\pthread.hpp"
>
</File>
<File
RelativePath="..\..\relacy\stdlib\semaphore.hpp"
>
</File>
<File
RelativePath="..\..\relacy\stdlib\windows.hpp"
>
</File>
</Filter>
<File
RelativePath="..\addr_hash.hpp"
>
</File>
<File
RelativePath="..\..\relacy\context.hpp"
>
</File>
<File
RelativePath="..\..\relacy\context_addr_hash.hpp"
>
</File>
<File
RelativePath="..\..\relacy\context_base.hpp"
>
</File>
<File
RelativePath="..\..\relacy\context_base_impl.hpp"
>
</File>
<File
RelativePath="..\..\relacy\defs.hpp"
>
</File>
<File
RelativePath="..\..\relacy\dyn_thread.hpp"
>
</File>
<File
RelativePath="..\..\relacy\dyn_thread_ctx.hpp"
>
</File>
<File
RelativePath="..\..\relacy\history.hpp"
>
</File>
<File
RelativePath="..\..\relacy\memory.hpp"
>
</File>
<File
RelativePath="..\..\relacy\memory_order.hpp"
>
</File>
<File
RelativePath="..\..\relacy\pthread.h"
>
</File>
<File
RelativePath="..\..\relacy\relacy.hpp"
>
</File>
<File
RelativePath="..\..\relacy\relacy_cli.hpp"
>
</File>
<File
RelativePath="..\..\relacy\relacy_java.hpp"
>
</File>
<File
RelativePath="..\..\relacy\relacy_std.hpp"
>
</File>
<File
RelativePath="..\..\relacy\rmw.hpp"
>
</File>
<File
RelativePath="..\..\relacy\slab_allocator.hpp"
>
</File>
<File
RelativePath="..\..\relacy\sync_var.hpp"
>
</File>
<File
RelativePath="..\..\relacy\test_params.hpp"
>
</File>
<File
RelativePath="..\..\relacy\test_result.hpp"
>
</File>
<File
RelativePath="..\..\relacy\test_suite.hpp"
>
</File>
<File
RelativePath="..\..\relacy\thread.hpp"
>
</File>
<File
RelativePath="..\..\relacy\thread_base.hpp"
>
</File>
<File
RelativePath="..\..\relacy\thread_local.hpp"
>
</File>
<File
RelativePath="..\..\relacy\thread_local_ctx.hpp"
>
</File>
<File
RelativePath="..\..\relacy\waitset.hpp"
>
</File>
<File
RelativePath="..\..\relacy\windows.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,46 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{99882C71-3316-411F-A8AE-EC1E40702040}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Profile|Win32 = Profile|Win32
Profile|x64 = Profile|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.ActiveCfg = Debug|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug|Win32.Build.0 = Debug|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug|x64.ActiveCfg = Debug|x64
{99882C71-3316-411F-A8AE-EC1E40702040}.Debug|x64.Build.0 = Debug|x64
{99882C71-3316-411F-A8AE-EC1E40702040}.Profile|Win32.ActiveCfg = Profile|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Profile|Win32.Build.0 = Profile|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Profile|x64.ActiveCfg = Profile|x64
{99882C71-3316-411F-A8AE-EC1E40702040}.Profile|x64.Build.0 = Profile|x64
{99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.ActiveCfg = Release|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Release|Win32.Build.0 = Release|Win32
{99882C71-3316-411F-A8AE-EC1E40702040}.Release|x64.ActiveCfg = Release|x64
{99882C71-3316-411F-A8AE-EC1E40702040}.Release|x64.Build.0 = Release|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.ActiveCfg = Debug|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|x64.Build.0 = Debug|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|Win32.Build.0 = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|x64.ActiveCfg = Release|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Profile|x64.Build.0 = Release|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.ActiveCfg = Release|x64
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,639 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="test"
ProjectGUID="{99882C71-3316-411F-A8AE-EC1E40702040}"
RootNamespace="test"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="4"
DebugInformationFormat="4"
EnablePREfast="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
PageHeapConserveMemory="true"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/bigobj"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="4"
DebugInformationFormat="3"
EnablePREfast="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
PageHeapConserveMemory="true"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
EnableFiberSafeOptimizations="true"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
BufferSecurityCheck="false"
EnableEnhancedInstructionSet="2"
UsePrecompiledHeader="2"
WarningLevel="4"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/bigobj"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
EnableFiberSafeOptimizations="true"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
BufferSecurityCheck="false"
UsePrecompiledHeader="2"
WarningLevel="4"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Profile|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/Ob0"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
EnableFiberSafeOptimizations="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
BufferSecurityCheck="false"
UsePrecompiledHeader="2"
WarningLevel="4"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="0"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Profile|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/bigobj"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
EnableFiberSafeOptimizations="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
BufferSecurityCheck="false"
UsePrecompiledHeader="2"
WarningLevel="4"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="0"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\..\CHANGES.TXT"
>
</File>
<File
RelativePath="..\compare_swap.hpp"
>
</File>
<File
RelativePath="..\condvar.hpp"
>
</File>
<File
RelativePath="..\data_race.hpp"
>
</File>
<File
RelativePath="..\dyn_thread.hpp"
>
</File>
<File
RelativePath="..\event.hpp"
>
</File>
<File
RelativePath="..\fence.hpp"
>
</File>
<File
RelativePath="..\main.cpp"
>
</File>
<File
RelativePath="..\memory.hpp"
>
</File>
<File
RelativePath="..\memory_order.hpp"
>
</File>
<File
RelativePath="..\mutex.hpp"
>
</File>
<File
RelativePath="..\pthread.hpp"
>
</File>
<File
RelativePath="..\scheduler.hpp"
>
</File>
<File
RelativePath="..\semaphore.hpp"
>
</File>
<File
RelativePath="..\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Profile|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Profile|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\stdafx.h"
>
</File>
<File
RelativePath="..\thread_local.hpp"
>
</File>
<File
RelativePath="..\todo.txt"
>
</File>
<File
RelativePath="..\wfmo.hpp"
>
</File>
<File
RelativePath="..\windows.hpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,221 @@
#pragma once
#include "../relacy/relacy_std.hpp"
struct test_mutex : rl::test_suite<test_mutex, 3>
{
rl::mutex mtx;
rl::var<int> data;
void before()
{
data($) = 0;
}
void after()
{
RL_ASSERT(data($) == 3);
}
void thread(unsigned /*index*/)
{
mtx.lock($);
data($) += 1;
mtx.unlock($);
}
};
struct test_deadlock : rl::test_suite<test_deadlock, 2, rl::test_result_deadlock>
{
rl::mutex mtx1;
rl::mutex mtx2;
void thread(unsigned index)
{
if (0 == index)
{
mtx1.lock($);
mtx2.lock($);
mtx1.unlock($);
mtx2.unlock($);
}
else
{
mtx2.lock($);
mtx1.lock($);
mtx1.unlock($);
mtx2.unlock($);
}
}
};
struct test_deadlock2 : rl::test_suite<test_deadlock2, 2, rl::test_result_deadlock>
{
std::mutex m;
std::atomic<int> f;
void before()
{
f($) = 0;
}
void thread(unsigned index)
{
if (index)
{
m.lock($);
f($) = 1;
for (int i = 0; i != 100; ++i)
rl::yield(1, $);
}
else
{
while (0 == f($))
rl::yield(1, $);
m.lock($);
}
}
};
struct test_mutex_destuction : rl::test_suite<test_mutex_destuction, 1, rl::test_result_destroying_owned_mutex>
{
void thread(unsigned)
{
std::mutex* m = new std::mutex;
m->lock($);
delete m;
}
};
struct test_mutex_destuction2 : rl::test_suite<test_mutex_destuction2, 2, rl::test_result_destroying_owned_mutex>
{
std::mutex* m;
std::atomic<int> f;
void before()
{
m = new std::mutex;
f($) = 0;
}
void thread(unsigned index)
{
if (0 == index)
{
m->lock($);
f($) = 1;
while (1 == f($))
rl::yield(1, $);
m->unlock($);
}
else
{
while (0 == f($))
rl::yield(1, $);
delete m;
f($) = 2;
}
}
};
struct test_mutex_recursion : rl::test_suite<test_mutex_recursion, 2>
{
std::recursive_mutex mtx;
rl::var<int> data;
void before()
{
data($) = 0;
}
void after()
{
RL_ASSERT(data($) == 2);
}
void thread(unsigned /*index*/)
{
mtx.lock($);
mtx.lock($);
data($) += 1;
mtx.unlock($);
mtx.unlock($);
}
};
struct test_mutex_try_lock : rl::test_suite<test_mutex_try_lock, 2>
{
std::recursive_mutex mtx;
rl::var<int> data;
void before()
{
data($) = 0;
}
void after()
{
RL_ASSERT(data($) == 2);
}
void thread(unsigned /*index*/)
{
while (false == mtx.try_lock($))
rl::yield(1, $);
RL_ASSERT(mtx.try_lock($));
data($) += 1;
mtx.unlock($);
mtx.unlock($);
}
};
struct test_mutex_recursion_error : rl::test_suite<test_mutex_recursion_error, 1, rl::test_result_recursion_on_nonrecursive_mutex>
{
void thread(unsigned)
{
std::mutex m;
m.lock($);
m.lock($);
}
};
struct test_mutex_unlock_error : rl::test_suite<test_mutex_unlock_error, 1, rl::test_result_unlocking_mutex_wo_ownership>
{
void thread(unsigned)
{
std::mutex m;
m.lock($);
m.unlock($);
m.unlock($);
}
};
struct test_mutex_leak : rl::test_suite<test_mutex_leak, 1, rl::test_result_resource_leak>
{
void thread(unsigned)
{
char* p = new char [sizeof(std::mutex)];
new (p) std::mutex();
delete [] p;
}
};
@@ -0,0 +1,26 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntest", "ntest.vcproj", "{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "..\..\test\msvc8\rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.ActiveCfg = Debug|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.Build.0 = Debug|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.ActiveCfg = Release|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.Build.0 = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,204 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="ntest"
ProjectGUID="{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}"
RootNamespace="ntest"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\ntest.cpp"
>
</File>
<File
RelativePath="..\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\stdafx.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,26 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntest", "ntest.vcproj", "{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrd", "..\..\test\msvc9\rrd.vcproj", "{D4F501D0-382D-4CBC-86F4-56181F383444}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.ActiveCfg = Debug|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Debug|Win32.Build.0 = Debug|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.ActiveCfg = Release|Win32
{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}.Release|Win32.Build.0 = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.ActiveCfg = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Debug|Win32.Build.0 = Debug|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.ActiveCfg = Release|Win32
{D4F501D0-382D-4CBC-86F4-56181F383444}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,199 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="ntest"
ProjectGUID="{D8A75C0E-3C9A-42E5-97EC-75AEBE64C372}"
RootNamespace="ntest"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\ntest.cpp"
>
</File>
<File
RelativePath="..\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\stdafx.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -0,0 +1,315 @@
#include "stdafx.h"
#include "../../relacy/relacy_cli.hpp"
using rl::nvar;
using rl::nvolatile;
using rl::mutex;
template<typename T>
class ws_deque
{
public:
ws_deque()
{
m_mask($) = initial_size - 1;
m_headIndex($) = 0;
m_tailIndex($) = 0;
m_array($) = new nvar<T> [initial_size];
m_arraySize($) = initial_size;
}
bool IsEmpty()
{
return m_headIndex($) >= m_tailIndex($);
}
size_t Count()
{
return m_tailIndex($) - m_headIndex($);
}
void push(T item)
{
size_t tail = m_tailIndex($);
// original version:
//if (tail < m_headIndex($) + m_mask($))
// corrected version:
if (tail <= m_headIndex($) + m_mask($))
{
m_array($)[tail & m_mask($)]($) = item;
m_tailIndex($) = tail + 1;
}
else
{
m_foreignLock.lock($);
size_t head = m_headIndex($);
size_t count = Count();
if (count >= m_mask($))
{
size_t arraySize = m_arraySize($);
size_t mask = m_mask($);
nvar<T>* newArray = new nvar<T> [arraySize * 2];
nvar<T>* arr = m_array($);
// original version:
//for (size_t i = 0; i != arraySize; ++i)
// corrected version:
for (size_t i = 0; i != count; ++i)
newArray[i]($) = arr[(i + head) & mask]($);
m_array($) = newArray;
m_arraySize($) = arraySize * 2;
m_headIndex($) = 0;
m_tailIndex($) = count;
tail = count;
m_mask($) = (mask * 2) | 1;
}
m_array($)[tail & m_mask($)]($) = item;
m_tailIndex($) = tail + 1;
m_foreignLock.unlock($);
}
}
bool pop(T& item)
{
size_t tail = m_tailIndex($);
// original version:
//if (m_headIndex($) >= tail)
// return false;
// corrected version:
if (tail == 0)
return false;
tail -= 1;
rl::Interlocked::Exchange(m_tailIndex, tail, $);
if (m_headIndex($) <= tail)
{
item = m_array($)[tail & m_mask($)]($);
return true;
}
else
{
m_foreignLock.lock($);
if (m_headIndex($) <= tail)
{
item = m_array($)[tail & m_mask($)]($);
m_foreignLock.unlock($);
return true;
}
else
{
m_tailIndex($) = tail + 1;
m_foreignLock.unlock($);
return false;
}
}
}
bool steal(T& item)
{
if (false == m_foreignLock.try_lock($))
return false;
size_t head = m_headIndex($);
rl::Interlocked::Exchange(m_headIndex, head + 1, $);
if (head < m_tailIndex($))
{
item = m_array($)[head & m_mask($)]($);
m_foreignLock.unlock($);
return true;
}
else
{
m_headIndex($) = head;
m_foreignLock.unlock($);
return false;
}
}
private:
static size_t const initial_size = 2;
nvar<nvar<T>*> m_array;
nvar<size_t> m_mask;
nvar<size_t> m_arraySize;
nvolatile<size_t> m_headIndex;
nvolatile<size_t> m_tailIndex;
mutex m_foreignLock;
};
struct ws_deque_test : rl::test_suite<ws_deque_test, 2>
{
ws_deque<int> q;
bool state [2];
void before()
{
state[0] = true;
state[1] = true;
}
void after()
{
RL_ASSERT(state[0] == false);
RL_ASSERT(state[1] == false);
}
void thread(unsigned index)
{
if (0 == index)
{
q.push(1);
q.push(2);
int item = 0;
bool res = q.pop(item);
RL_ASSERT(res && item == 2);
RL_ASSERT(state[1]);
state[1] = false;
item = 0;
res = q.pop(item);
if (res)
{
RL_ASSERT(state[0]);
state[0] = false;
}
item = 0;
res = q.pop(item);
RL_ASSERT(res == false);
}
else
{
int item = 0;
bool res = q.steal(item);
if (res)
{
RL_ASSERT(item == 1);
RL_ASSERT(state[0]);
state[0] = false;
}
}
}
};
struct test_api : rl::test_suite<test_api, 1>
{
void thread(unsigned)
{
rl::nvar<int> cv1, cv2(3), cv3(cv1($)), cv4(cv1);
cv1($) = cv2($);
cv1($) = 1;
(int)cv1($);
cv1($) += 1;
cv1($) -= 1;
cv1($)++;
cv1($)--;
++cv1($);
--cv1($);
int x = rl::Interlocked::Add(cv1, 3, $);
x = rl::Interlocked::CompareExchange(cv1, 3, x, $);
x = rl::Interlocked::Exchange(cv2, 6, $);
x = rl::Interlocked::Read(cv2, $);
x = rl::Interlocked::Increment(cv2, $);
x = rl::Interlocked::Decrement(cv2, $);
rl::Thread::MemoryBarrier($);
x = rl::Thread::VolatileRead(cv1, $);
rl::Thread::VolatileWrite(cv1, 5, $);
rl::Thread::SpinWait(1, $);
}
};
struct ws_deque_test0 : rl::test_suite<ws_deque_test0, 4>
{
ws_deque<int> q;
void before()
{
}
void after()
{
}
void thread(unsigned index)
{
if (0 == index)
{
for (size_t i = 0; i != 4; ++i)
{
q.push(10);
}
for (size_t i = 0; i != 5; ++i)
{
int p = 0;
bool res = q.pop(p);
RL_ASSERT(10 == p || false == res);
}
for (size_t i = 0; i != 4; ++i)
{
q.push(10);
int p = 0;
bool res = q.pop(p);
RL_ASSERT(10 == p || false == res);
}
for (size_t i = 0; i != 4; ++i)
{
q.push(10);
q.push(10);
int p = 0;
bool res = q.pop(p);
RL_ASSERT(10 == p || false == res);
p = 0;
res = q.pop(p);
RL_ASSERT(10 == p || false == res);
}
for (size_t i = 0; i != 4; ++i)
{
q.push(10);
q.push(10);
q.push(10);
int p = 0;
bool res = q.pop(p);
RL_ASSERT(10 == p || false == res);
}
for (size_t i = 0; i != 14; ++i)
{
q.push(10);
int p = 0;
bool res = q.pop(p);
RL_ASSERT(10 == p || false == res);
}
}
else
{
for (size_t i = 0; i != 4; ++i)
{
int p = 0;
bool res = q.steal(p);
RL_ASSERT(10 == p || false == res);
}
}
}
};
int main()
{
rl::test_params p;
p.iteration_count = 1000;
rl::simulate<ws_deque_test0>(p);
rl::simulate<ws_deque_test>(p);
rl::simulate<test_api>();
}
@@ -0,0 +1,3 @@
#include "stdafx.h"
@@ -0,0 +1,12 @@
#ifndef STDAFX_H
#define STDAFX_H
#ifdef _MSC_VER
# pragma once
#endif
#include "../../relacy/pch.hpp"
#endif
@@ -0,0 +1,281 @@
#pragma once
#include "../relacy/pthread.h"
struct test_pthread_thread : rl::test_suite<test_pthread_thread, 1>
{
static size_t const dynamic_thread_count = 2;
VAR_T(int) data;
static void* func(void* param)
{
static_cast<test_pthread_thread*>(param)->VAR(data) += 1;
return 0;
}
void thread(unsigned)
{
VAR(data) = 0;
pthread_t th1;
pthread_create(&th1, 0, &test_pthread_thread::func, this);
void* res1 = 0;
pthread_join(th1, &res1);
RL_ASSERT(VAR(data) == 1);
pthread_t th2;
pthread_create(&th2, 0, &test_pthread_thread::func, this);
void* res2 = 0;
pthread_join(th2, &res2);
RL_ASSERT(VAR(data) == 2);
}
};
struct test_pthread_mutex : rl::test_suite<test_pthread_mutex, 2>
{
pthread_mutex_t mtx;
VAR_T(int) data;
void before()
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mtx, &attr);
pthread_mutexattr_destroy(&attr);
VAR(data) = 0;
}
void after()
{
pthread_mutex_destroy(&mtx);
}
void thread(unsigned /*index*/)
{
pthread_mutex_lock(&mtx);
VAR(data) += 1;
pthread_mutex_unlock(&mtx);
if (0 == pthread_mutex_try_lock(&mtx))
{
VAR(data) += 1;
pthread_mutex_unlock(&mtx);
}
//pthread_mutex_timedlock
}
};
struct test_pthread_condvar : rl::test_suite<test_pthread_condvar, 3>
{
pthread_cond_t cv;
pthread_mutex_t mtx;
VAR_T(int) stage;
void before()
{
pthread_condattr_t attr;
pthread_cond_init(&cv, &attr);
pthread_mutex_init(&mtx, 0);
VAR(stage) = 0;
}
void after()
{
pthread_cond_destroy(&cv);
pthread_mutex_destroy(&mtx);
}
void thread(unsigned index)
{
if (0 == index)
{
pthread_mutex_lock(&mtx);
VAR(stage) += 1;
pthread_cond_broadcast(&cv);
while (VAR(stage) != 2)
pthread_cond_wait(&cv, &mtx);
pthread_mutex_unlock(&mtx);
}
else if (1 == index)
{
pthread_mutex_lock(&mtx);
while (VAR(stage) != 1)
{
int ts = 1;
pthread_cond_timedwait(&cv, &mtx, &ts);
}
VAR(stage) += 1;
pthread_cond_broadcast(&cv);
pthread_mutex_unlock(&mtx);
}
else if (2 == index)
{
pthread_mutex_lock(&mtx);
while (VAR(stage) != 2)
pthread_cond_wait(&cv, &mtx);
pthread_mutex_unlock(&mtx);
pthread_cond_signal(&cv);
}
}
};
struct test_pthread_condvar2 : rl::test_suite<test_pthread_condvar2, 2>
{
pthread_cond_t cv1, cv2;
pthread_mutex_t mtx1, mtx2;
VAR_T(int) stage;
void before()
{
pthread_cond_init(&cv1, 0);
pthread_cond_init(&cv2, 0);
pthread_mutex_init(&mtx1, 0);
pthread_mutex_init(&mtx2, 0);
VAR(stage) = 0;
}
void after()
{
pthread_cond_destroy(&cv1);
pthread_cond_destroy(&cv2);
pthread_mutex_destroy(&mtx1);
pthread_mutex_destroy(&mtx2);
}
void thread(unsigned index)
{
if (0 == index)
{
pthread_mutex_lock(&mtx1);
int ts = 1;
pthread_cond_timedwait(&cv1, &mtx1, &ts);
pthread_mutex_unlock(&mtx1);
}
else if (1 == index)
{
pthread_mutex_lock(&mtx2);
int ts = 1;
pthread_cond_timedwait(&cv2, &mtx2, &ts);
pthread_mutex_unlock(&mtx2);
}
}
};
struct test_pthread_rwlock : rl::test_suite<test_pthread_rwlock, 3>
{
pthread_rwlock_t mtx;
VAR_T(int) data;
void before()
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_rwlock_init(&mtx, &attr);
pthread_mutexattr_destroy(&attr);
VAR(data) = 0;
}
void after()
{
pthread_rwlock_destroy(&mtx);
}
void thread(unsigned /*index*/)
{
pthread_rwlock_wrlock(&mtx);
VAR(data) += 1;
pthread_rwlock_unlock(&mtx);
if (0 == pthread_rwlock_trywrlock(&mtx))
{
VAR(data) += 1;
pthread_rwlock_unlock(&mtx);
}
pthread_rwlock_rdlock(&mtx);
(void)(int)VAR(data);
pthread_rwlock_unlock(&mtx);
if (0 == pthread_rwlock_tryrdlock(&mtx))
{
(void)(int)VAR(data);
pthread_rwlock_unlock(&mtx);
}
}
};
struct test_pthread_sem : rl::test_suite<test_pthread_sem, 2>
{
sem_t sem1, sem2;
VAR_T(int) data;
void before()
{
sem_init(&sem1, 0, 0);
sem_init(&sem2, 0, 0);
VAR(data) = 0;
}
void after()
{
sem_destroy(&sem1);
sem_destroy(&sem2);
}
void thread(unsigned index)
{
if (index)
{
VAR(data) = 1;
sem_post(&sem1);
while (sem_trywait(&sem2))
{
assert(errno == EINTR || errno == EAGAIN);
pthread_yield();
}
RL_ASSERT(VAR(data) == 2);
VAR(data) = 3;
int count = -1;
sem_getvalue(&sem2, &count);
RL_ASSERT(count == 0);
sem_post(&sem2);
sem_getvalue(&sem2, &count);
RL_ASSERT(count == 1);
}
else
{
while (sem_wait(&sem1))
assert(errno == EINTR);
RL_ASSERT(VAR(data) == 1);
VAR(data) = 2;
sem_post(&sem2);
}
}
};
@@ -0,0 +1,183 @@
#pragma once
#include "../relacy/relacy_std.hpp"
struct livelock_test : rl::test_suite<livelock_test, 2, rl::test_result_livelock>
{
std::atomic<int> x;
void before()
{
x($) = 0;
}
void thread(unsigned index)
{
if (0 == index)
{
for (;;)
{
int cmp = 1;
if (x($).compare_exchange_weak(cmp, 2))
break;
}
}
else if (1 == index)
{
x($).store(1);
}
}
};
struct yield_livelock_test : rl::test_suite<yield_livelock_test, 2, rl::test_result_livelock>
{
std::atomic<int> x, y;
void before()
{
x($) = 0;
y($) = 0;
}
void thread(unsigned index)
{
if (0 == index)
{
rl::backoff b;
for (;;)
{
int cmp = 0;
if (x($).compare_exchange_weak(cmp, 1))
{
cmp = 0;
if (y($).compare_exchange_weak(cmp, 1))
{
x($).store(0);
y($).store(0);
break;
}
else
{
x($).store(0);
}
}
b.yield($);
}
}
else if (1 == index)
{
rl::backoff b;
for (;;)
{
int cmp = 0;
if (y($).compare_exchange_weak(cmp, 1))
{
cmp = 0;
if (x($).compare_exchange_weak(cmp, 1))
{
y($).store(0);
x($).store(0);
break;
}
else
{
y($).store(0);
}
}
b.yield($);
}
}
}
};
struct sched_load_test : rl::test_suite<sched_load_test, 2>
{
std::recursive_mutex mtx1, mtx2;
std::condition_variable_any cv1, cv2;
VAR_T(int) data1, data2;
void before()
{
}
void thread(unsigned index)
{
if (index % 2)
{
mtx1.lock($);
VAR(data1) = 1;
mtx1.unlock($);
mtx2.lock($);
mtx2.lock($);
VAR(data2) = 1;
mtx2.unlock($);
mtx2.unlock($);
if (mtx1.try_lock($))
{
//mtx1.lock($);
VAR(data1) = 1;
//mtx1.unlock($);
mtx1.unlock($);
}
mtx1.lock($);
VAR(data1) = 2;
cv1.notify_all($);
mtx1.unlock($);
mtx2.lock($);
while (VAR(data2) != 2)
{
rl::yield(1, $);
cv2.wait_for(mtx2, 1, $);
}
mtx2.unlock($);
}
else
{
mtx2.lock($);
VAR(data2) = 1;
mtx2.unlock($);
mtx1.lock($);
mtx1.lock($);
VAR(data1) = 1;
mtx1.unlock($);
mtx1.unlock($);
if (mtx2.try_lock($))
{
//mtx2.lock($);
VAR(data2) = 1;
//mtx2.unlock($);
mtx2.unlock($);
}
mtx2.lock($);
VAR(data2) = 2;
mtx2.unlock($);
cv2.notify_all($);
mtx1.lock($);
while (VAR(data1) != 2)
{
rl::yield(1, $);
cv1.wait_for(mtx1, 1, $);
}
mtx1.unlock($);
}
}
};
@@ -0,0 +1,84 @@
#pragma once
#include "../relacy/relacy_std.hpp"
struct test_semaphore : rl::test_suite<test_semaphore, 2>
{
HANDLE sema;
VAR_T(int) data;
void before()
{
VAR(data) = 0;
sema = CreateSemaphore(0, 0, 2, 0);
}
void after()
{
CloseHandle(sema);
}
void thread(unsigned index)
{
if (0 == index)
{
VAR(data) = 1;
ReleaseSemaphore(sema, 1, 0);
}
else
{
unsigned rv = WaitForSingleObject(sema, INFINITE);
assert(rv == WAIT_OBJECT_0);
assert(VAR(data) == 1);
rv = WaitForSingleObject(sema, 0);
assert(rv == WAIT_TIMEOUT);
}
}
};
struct test_semaphore_atomic : rl::test_suite<test_semaphore_atomic, 2>
{
HANDLE sem [2];
void before()
{
sem[0] = CreateSemaphore(0, 0, 2, 0);
sem[1] = CreateSemaphore(0, 0, 2, 0);
}
void after()
{
CloseHandle(sem[0]);
CloseHandle(sem[1]);
}
void thread(unsigned index)
{
if (0 == index)
{
unsigned rv = WaitForSingleObject(sem[0], INFINITE);
assert(rv == WAIT_OBJECT_0);
ReleaseSemaphore(sem[1], 1, 0);
rv = WaitForSingleObject(sem[1], 0);
assert(rv == WAIT_TIMEOUT);
}
else
{
unsigned rv = SignalObjectAndWait(sem[0], sem[1], INFINITE, 0);
assert(rv == WAIT_OBJECT_0);
rv = WaitForSingleObject(sem[1], 0);
assert(rv == WAIT_TIMEOUT);
rv = WaitForSingleObject(sem[0], 0);
assert(rv == WAIT_TIMEOUT);
}
}
};
@@ -0,0 +1,2 @@
#include "stdafx.h"
@@ -0,0 +1,25 @@
#ifndef STDAFX_H
#define STDAFX_H
#ifdef _MSC_VER
# pragma once
#endif
#ifdef _MSC_VER
# pragma warning (disable: 4127)
#endif
#if defined(_MSC_VER) && (_MSC_VER <= 1310)
//# pragma warning (disable: 4511)
//# pragma warning (disable: 4512)
#endif
#ifdef NDEBUG
# define _SECURE_SCL 0
#endif
#include "../relacy/pch.hpp"
#endif
@@ -0,0 +1,80 @@
#pragma once
#include "../relacy/relacy.hpp"
struct tls_basic_test : rl::test_suite<tls_basic_test, 3>
{
rl::thread_local_var<unsigned> x;
void thread(unsigned index)
{
RL_ASSERT(x.get($) == 0);
x.set(index + 10, $);
RL_ASSERT(x.get($) == index + 10);
}
};
struct tls_basic_test2 : rl::test_suite<tls_basic_test2, 3>
{
TLS_T(unsigned) x;
void thread(unsigned index)
{
RL_ASSERT(VAR(x) == 0);
VAR(x) = index + 10;
RL_ASSERT(VAR(x) == index + 10);
}
};
struct tls_reset_test : rl::test_suite<tls_reset_test, 3, rl::test_result_user_assert_failed>
{
rl::thread_local_var<unsigned> x;
void thread(unsigned index)
{
RL_ASSERT(x.get($) == 0);
x.set(index + 10, $);
RL_ASSERT(x.get($) == index + 10);
RL_ASSERT(false);
}
};
rl::thread_local_var<unsigned> tls_global_test_x;
struct tls_global_test : rl::test_suite<tls_global_test, 3, rl::test_result_user_assert_failed>
{
void thread(unsigned index)
{
RL_ASSERT(tls_global_test_x.get($) == 0);
tls_global_test_x.set(index + 10, $);
RL_ASSERT(tls_global_test_x.get($) == index + 10);
RL_ASSERT(false);
}
};
struct tls_win32_test : rl::test_suite<tls_win32_test, 3>
{
unsigned long slot;
void before()
{
slot = TlsAlloc();
}
void after()
{
TlsFree(slot);
}
void thread(unsigned index)
{
RL_ASSERT(TlsGetValue(slot) == 0);
TlsSetValue(slot, (void*)(uintptr_t)(index + 10));
RL_ASSERT(TlsGetValue(slot) == (void*)(uintptr_t)(index + 10));
}
};
@@ -0,0 +1,60 @@
Relacy Race Detector Todo List:
- use indirection and indices for TLS, because on Windows TLS index is DWORD (not DWORD_PTR) (eliminate pointers?)
+ provide rl::hash_ptr()
- support for fair timed waits
+ remove iteration count estimation from full sched -> causes division by 0
- history: memory allocation before object ctor (new T (...))
+ code in test::after() affects iteration count with full scheduler -> final and estimated iteration counts are the same
- non-deterministic sub-expression calculation:
foo(bar.load(std::memory_order_acquire), baz.load(std::memory_order_acquire));
- post issue:
can't simulate some modification orders in presence of data-races-type-2 for atomic vars:
//thread 1
x.store(1, std::memory_order_relaxed);
y.store(1, std::memory_order_relaxed);
//thread 2
while (y.load(std::memory_order_relaxed) == 0
{}
x.store(2, std::memory_order_relaxed);
-> modification order of 'x' will never be "2, 1"
[CORE]
- initially run threads one by one
- initially run some iterations twice, in order to check that unit-test is deterministic
? add unique identifiers to atomics, vars, mutexes etc (address can be useful too)
- example catalog (description, used techniques, what error is found)
- do I need sched() before atomic loads?
- do I need sched() before mutex unlock?
- for loads output in history value of which store is loaded
- detect dead-code
- output which operations cause data race
? output happens-before matrix, synchronizes-with matrix etc
- SEH handler to catch paging faults
- sched before malloc/free to allow more ABA
[PERF]
- implement performance simulation
- cacheline transfers
- atomic rmw operations
- fences
[OTHER]
- parallelize the run-time for random scheduler
- parallelize the run-time for tree search scheduler
- manual control over scheduler
- persistent checkpointing of scheduler state (to allow "continue")
- atomic blocks (pdr implementation -> pdr component)
? state space reductions (sleep sets, dynamic persistent sets)
? what can I do with serialization points -> user specifies "visible" results
system checks for linearizablity -> "visible" results equal to some sequential execution
? save program state inside iteration (save point), continue other iterations from this save point
? partial order reductions by memorizing happens-before graphs, not program state
? estimate progress by seeing how many iterations it gets to move 0->1 on some stree level
? lower bound, upper bound, mean of progress
O(X) = (P^(C + 3)) * (N^(P + C + 1)) * (P + C)!
@@ -0,0 +1,444 @@
Here is a recent version of the revised pc_sample.c which uses inline x86
ASM and compiles under VC++ (I am planning on coding the entire thing in
pure assembly language):
____________________________________________________________________
#if ! defined(PC_SAMPLE_INCLUDE_H)
# define PC_SAMPLE_INCLUDE_H
# pragma warning(push)
# pragma warning (disable : 4100 4505 4706)
# if defined(__cplusplus)
extern "C" {
# endif
/*===========================================================*/
/* Very Simple x86 Atomic Operations API & Implmentation
_____________________________________________________________*/
typedef __int32 atomicword;
typedef atomicword volatile* const atomicword_pthis;
static int
x86_DWCASPTR(
void volatile* const,
void* const,
void const* const
);
static atomicword
x86_XADDWORD(
atomicword_pthis,
atomicword const
);
static atomicword
x86_XCHGWORD(
atomicword_pthis,
atomicword const
);
__declspec(naked) int
x86_DWCASPTR(
void volatile* const _pthis,
void* const pcmp,
void const* const pxhcg
) {
_asm {
PUSH ESI
PUSH EBX
MOV ESI, [ESP + 16]
MOV EAX, [ESI]
MOV EDX, [ESI + 4]
MOV ESI, [ESP + 20]
MOV EBX, [ESI]
MOV ECX, [ESI + 4]
MOV ESI, [ESP + 12]
LOCK CMPXCHG8B QWORD PTR [ESI]
JNE x86_DWCASPTR_failed
MOV EAX, 1
POP EBX
POP ESI
RET
x86_DWCASPTR_failed:
MOV ESI, [ESP + 16]
MOV [ESI], EAX
MOV [ESI + 4], EDX
MOV EAX, 0
POP EBX
POP ESI
RET
}
}
__declspec(naked) atomicword
x86_XADDWORD(
atomicword_pthis _pthis,
atomicword const value
) {
_asm {
MOV EDX, [ESP + 4]
MOV EAX, [ESP + 8]
LOCK XADD [EDX], EAX
RET
}
}
__declspec(naked) atomicword
x86_XCHGWORD(
atomicword_pthis _pthis,
atomicword const value
) {
_asm {
MOV EDX, [ESP + 4]
MOV EAX, [ESP + 8]
XCHG [EDX], EAX
RET
}
}
#define x86_XCHGPTR(mp_pdest, mp_src) ( \
(void*)x86_XCHGWORD( \
((atomicword_pthis)(mp_pdest)), \
((atomicword const)(mp_src)) \
) \
)
#define XCHGWORD x86_XCHGWORD
#define XCHGPTR x86_XCHGPTR
#define XADDWORD x86_XADDWORD
#define DWCASPTR x86_DWCASPTR
/* Proxy-Collector API & Implmentation (Revisited) ;^)
Inventor: Chris M. Thomasson
_____________________________________________________________*/
#include <stddef.h>
#include <assert.h>
#if ! defined(NDEBUG)
# include <stdio.h>
#endif
#define CONTAINER_OF(mp_this, mp_type, mp_member) ( \
(mp_type*)(((unsigned char*)(mp_this)) - \
offsetof(mp_type, mp_member)) \
)
typedef struct pc_region_s pc_region, pc_node;
typedef struct pc_master_s pc_master;
typedef void (pc_fp_dtor) (pc_node*);
typedef struct pc_sys_anchor_s pc_sys_anchor;
struct pc_sys_anchor_s {
atomicword refcnt;
pc_region* region;
};
struct pc_region_s {
pc_sys_anchor next;
pc_node* defer;
};
struct pc_master_s {
pc_sys_anchor head;
pc_region region;
pc_fp_dtor* fp_dtor;
};
#define PC_MASTER_STATICINIT(mp_this, mp_fp_dtor) { \
{ 0, &(mp_this)->region }, \
{ { 0, NULL }, NULL }, (mp_fp_dtor) \
}
static void
pc_sys_dtor(
pc_master* const,
pc_region* const
);
static void
pc_init(
pc_master* const,
pc_fp_dtor* const
);
static void
pc_node_init(
pc_node* const
);
static void
pc_node_link(
pc_node* const,
pc_node* const
);
static pc_region*
pc_acquire(
pc_master* const
);
static void
pc_release(
pc_master* const,
pc_region* const
);
static void
pc_defer(
pc_region* const,
pc_node* const
);
static void
pc_mutate(
pc_master* const,
pc_node* const
);
void
pc_init(
pc_master* const _this,
pc_fp_dtor* const fp_dtor
) {
pc_master src = { { 0 } };
*_this = src;
_this->head.region = &_this->region;
_this->fp_dtor = fp_dtor;
}
pc_region*
pc_acquire(
pc_master* const _this
) {
pc_sys_anchor cmp = _this->head, xchg;
do {
xchg.refcnt = cmp.refcnt + 2;
xchg.region = cmp.region;
} while (! DWCASPTR(&_this->head, &cmp, &xchg));
return cmp.region;
}
void
pc_release(
pc_master* const _this,
pc_region* const region
) {
if (XADDWORD(&region->next.refcnt, -2) == 3) {
pc_sys_dtor(_this, region);
}
}
void
pc_node_init(
pc_node* const _this
) {
pc_node src = { { 0 } };
*_this = src;
}
void
pc_node_link(
pc_node* const _this,
pc_node* const next
) {
_this->defer = next;
}
void
pc_defer(
pc_region* const _this,
pc_node* const node
) {
node->defer = XCHGPTR(&_this->defer, node);
}
void
pc_mutate(
pc_master* const _this,
pc_node* const node
) {
pc_sys_anchor cmp = _this->head, xchg = { 0 };
node->next.refcnt = 2;
node->next.region = NULL;
xchg.region = node;
while (! DWCASPTR(&_this->head, &cmp, &xchg));
cmp.region->next.region = node;
if (XADDWORD(&cmp.region->next.refcnt,
cmp.refcnt + 1) == -cmp.refcnt) {
pc_sys_dtor(_this, cmp.region);
}
}
void
pc_sys_dtor(
pc_master* const _this,
pc_region* const region
) {
int dtors = 0, reset = 0;
pc_region* head = region;
pc_region* tail = region;
pc_region* next = region->next.region;
while (next) {
if (XADDWORD(&next->next.refcnt, -2) != 3) {
break;
}
tail = next;
next = next->next.region;
}
tail->next.region = NULL;
while (head) {
pc_region* const next = head->next.region;
pc_node* defer = head->defer;
assert(head->next.refcnt == 1);
if (head != &_this->region) {
head->defer = defer;
defer = head;
} else {
reset = 1;
}
while (defer) {
pc_node* const next = defer->defer;
_this->fp_dtor(defer);
++dtors;
defer = next;
}
head = next;
}
if (reset) {
_this->region.defer = NULL;
pc_mutate(_this, &_this->region);
}
#if ! defined(NDEBUG)
{
static atomicword g_pc_sys_epoch = 0;
atomicword const epoch = XADDWORD(&g_pc_sys_epoch, 1);
if (dtors) {
printf("pc_sys_dtor::epoch/dtors(%d/%d)\n",
epoch, dtors);
}
}
#endif
}
/*===========================================================*/
# if defined(__cplusplus)
}
# endif
# pragma warning(pop)
#endif
____________________________________________________________________
struct foo_node {
foo_node* next;
pc_node pcn;
};
struct foo_list {
foo_node* head;
pc_master pc;
};
static foo_list g_list = {
NULL, PC_MASTER_STATICINIT()
};
void foo_node_dtor(pc_node* pcn) {
foo_node* const _this = container_of(pcn, foo_node, pcn);
free(_this);
}
void foo_reader() {
int i;
foo_node* node;
pc_region* pcr = pc_acquire(&g_list.pc);
for (i = 1 ;; ++i) {
node = LOAD_DEPENDS(&g_list.head);
while (node) {
foo_node* const next = LOAD_MBDEPEND(&node->next);
[...];
node = next;
}
if (! (i % 1000)) {
pc_release(&g_list.pc, pcr);
pcr = pc_acquire(&g_list.pc);
}
}
pc_release(&g_list.pc, pcr);
}
void foo_writer() {
int i;
foo_node* node, *cmp;
pc_region* pcr = pc_acquire(&g_list.pc);
for (i = 1 ;; ++i) {
if (i % 10) {
node = malloc(sizeof(*node));
if (node) {
foo_node* cmp;
pc_node_init(node, NULL, foo_node_dtor);
cmp = g_list.head;
do {
node->next = cmp;
} while (! CASIBM_MBREL(&g_list.head, &cmp, node));
}
} else {
node = g_list.head;
do {
if (! node) { break; }
} while (! CASIBM_MBACQ(&g_list.head, &node, node->next));
if (node) {
if (! (i % 20)) {
pc_mutate(&g_list.pc, &node->pcn);
} else {
pc_defer(pcr, &node->pcn);
}
}
}
if (! (i % 500)) {
pc_release(&g_list.pc, pcr);
pcr = pc_acquire(&g_list.pc);
}
}
pc_release(&g_list.pc, pcr);
}
1. Region 1 is current
2. Thread 1 acquires region 1
3. Thread 2 executes pc_mutate()
4. Region 2 is current
5. Thread 3 acquires region 2
6. Thread 3 loads pointer to node 1
7. Thread 1 removes node 1 from data structure
8. Thread 1 executes pc_defer() and defers node 1 to region 1
9. Thread 1 releases region 1
10. Dtor executed for region 1, node 1 is deleted
11. Thread 3 accesses node 1
12. Bang!
@@ -0,0 +1,359 @@
#pragma once
#include "../../relacy/relacy_std.hpp"
intptr_t const lock_value = (intptr_t)-1;
struct rdesc
{
rl::var<std::atomic<intptr_t> const*> addr;
rl::var<intptr_t> cmp;
};
struct wdesc
{
rl::var<std::atomic<intptr_t>*> addr;
rl::var<intptr_t> cmp;
rl::var<intptr_t> xchg;
};
struct trx
{
static size_t const rset_max_size = 64;
static size_t const wset_max_size = 32;
rl::var<size_t> rset_idx;
rl::var<size_t> wset_idx;
rdesc rset [rset_max_size];
wdesc wset [wset_max_size];
rl::var<rdesc*> read(std::atomic<intptr_t> const* addr, std::memory_order mo = std::memory_order_relaxed)
{
intptr_t value = (*addr)($).load(mo);
if (lock_value == value)
return 0;
rdesc* desc = &rset[rset_idx($)];
++rset_idx($);
desc->addr($) = addr;
desc->cmp($) = value;
return desc;
}
rl::var<wdesc*> write(std::atomic<intptr_t>* addr)
{
intptr_t value = (*addr)($).swap(lock_value, rl::memory_order_acq_rel);
if (lock_value == value)
return 0;
wdesc* desc = &wset[wset_idx($)];
++wset_idx($);
desc->addr($) = addr;
desc->cmp($) = value;
return desc;
}
bool begin()
{
std::atomic_signal_fence($)(std::memory_order_acquire);
rset_idx($) = 0;
wset_idx($) = 0;
return true;
}
bool commit()
{
std::atomic_signal_fence($)(std::memory_order_release);
size_t i;
for (i = 0; i != rset_idx($); ++i)
{
rdesc const* desc = &rset[i];
if ((*(desc->addr($)))($).load(std::memory_order_relaxed) != desc->cmp($))
break;
}
if (i != rset_idx($))
{
return rollback();
}
std::atomic_thread_fence($)(std::memory_order_release);
for (i = 0; i != wset_idx($); ++i)
{
wdesc const* desc = &wset[i];
(*(desc->addr($)))($).store(desc->xchg($), std::memory_order_relaxed);
}
//std::atomic_thread_fence(std::memory_order_acq_rel);
return true;
}
bool rollback()
{
for (size_t i = 0; i != wset_idx($); ++i)
{
wdesc const* desc = &wset[i];
(*(desc->addr($)))($).store(desc->cmp($), std::memory_order_relaxed);
}
wset_idx($) = 0;
rset_idx($) = 0;
return false;
}
/*
bool readset_validate()
{
for (size_t i = 0; i != rset_idx; ++i)
{
rdesc const* desc = &rset[i];
if (*(intptr_t const volatile*)desc->addr != desc->cmp)
return true;
}
return false;
}
bool writeset_load(intptr_t* addr, intptr_t* value)
{
for (size_t i = 0; i != wset_idx; ++i)
{
wdesc const* desc = &wset[i];
if (desc->addr == addr)
{
*value = desc->xchg;
return true;
}
}
return false;
}
*/
};
inline void pdr_lock()
{
}
inline void pdr_unlock()
{
}
inline void pdr_acquire(void*)
{
}
inline void pdr_release(void*)
{
}
inline void pdr_dispose(void*)
{
}
struct dlist_trx_node
{
std::atomic<intptr_t> prev; // dlist_trx_node*
std::atomic<intptr_t> next; // dlist_trx_node*
rl::var<intptr_t> key;
rl::var<intptr_t> value;
dlist_trx_node(intptr_t key = 0, intptr_t value = 0)
: key(key)
, value(value)
{}
};
class dlist_trx
{
public:
dlist_trx()
: first(0, 0)
, last(0, 0)
{
first.prev($).store(0, std::memory_order_relaxed);
first.next($).store((intptr_t)&last, std::memory_order_relaxed);
last.prev($).store((intptr_t)&first, std::memory_order_relaxed);
last.next($).store(0, std::memory_order_relaxed);
}
__declspec(noinline) void remove(dlist_trx_node* node)
{
pdr_lock();
for (trx t; t.begin(); t.rollback())
{
rdesc* r1 = t.read(&node->prev)($);
if (0 == r1)
continue;
dlist_trx_node* prev = (dlist_trx_node*)(intptr_t)r1->cmp($);
rdesc* r2 = t.read(&node->next)($);
if (0 == r2)
continue;
dlist_trx_node* next = (dlist_trx_node*)(intptr_t)r2->cmp($);
wdesc* w1 = t.write(&prev->next)($);
if (0 == w1)
continue;
//dlist_trx_node* prev_next = (dlist_trx_node*)w1->cmp;
wdesc* w2 = t.write(&next->prev)($);
if (0 == w2)
continue;
//dlist_trx_node* next_prev = (dlist_trx_node*)w2->cmp;
w1->xchg($) = (intptr_t)next;
w2->xchg($) = (intptr_t)prev;
if (t.commit())
break;
}
pdr_unlock();
}
__declspec(noinline) void insert(dlist_trx_node* node)
{
pdr_lock();
for (trx t; t.begin(); t.rollback())
{
wdesc* w1 = t.write(&first.next)($);
if (0 == w1)
continue;
dlist_trx_node* next = (dlist_trx_node*)(intptr_t)w1->cmp($);
wdesc* w2 = t.write(&next->prev)($);
if (0 == w2)
continue;
dlist_trx_node* const& prev = (dlist_trx_node*)(intptr_t)w2->cmp($);
if (prev != &first)
continue;
node->prev($).store((intptr_t)prev, std::memory_order_relaxed);
node->next($).store((intptr_t)next, std::memory_order_relaxed);
w1->xchg($) = (intptr_t)node;
w2->xchg($) = (intptr_t)node;
if (t.commit())
break;
}
pdr_unlock();
}
__declspec(noinline) void foreach(void (*f)(void*, dlist_trx_node*), void (*reset)(void*), void* ctx)
{
pdr_lock();
for (trx t; t.begin(); t.rollback())
{
reset(ctx);
rdesc* r1 = t.read(&first.next, std::memory_order_consume)($);
if (0 == r1)
continue;
dlist_trx_node* node = (dlist_trx_node*)(intptr_t)r1->cmp($);
while (node->next($).load(std::memory_order_consume))
{
rdesc* r = t.read(&node->next)($);
if (0 == r)
break;
dlist_trx_node* next = (dlist_trx_node*)(intptr_t)r->cmp($);
f(ctx, node);
node = next;
}
if (node->next($).load(std::memory_order_relaxed))
continue;
if (t.commit())
break;
}
pdr_unlock();
}
dlist_trx_node first;
dlist_trx_node last;
};
struct dlist_trx_test : rl::test_suite<dlist_trx_test, 4>
{
dlist_trx list;
static int const count = 4;
dlist_trx_node nodes[2][count];
void thread(unsigned index)
{
if (0 == index || 1 == index)
{
for (int i = 0; i != count; ++i)
{
dlist_trx_node* n = &nodes[index][i];
intptr_t value = 1 << ((index * count + i) * 4);
n->key($) = value;
n->value($) = value;
list.insert(n);
}
for (int i = 0; i != count; ++i)
{
dlist_trx_node* n = &nodes[index][i];
list.remove(n);
}
}
else if (2 == index || 3 == index)
{
struct local
{
static void reset(void* ctx)
{
*(int*)ctx = 0;
}
static void apply(void* ctx, dlist_trx_node* n)
{
*(int*)ctx += (int)n->value($);
}
};
int volatile sum = 0;
list.foreach(&local::apply, &local::reset, (void*)&sum);
int volatile x = sum;
(void)x;
}
}
void invariant()
{
int volatile sum = 0;
dlist_trx_node* n = (dlist_trx_node*)list.first.next($).load();
for (;;)
{
if (lock_value == (intptr_t)n)
break;
dlist_trx_node* next = (dlist_trx_node*)n->next($).load();
if (0 == next)
break;
sum += (int)n->value($);
n = next;
}
}
};
@@ -0,0 +1,80 @@
1. Add
#include <relacy/relacy_std.hpp>
2. For atomic variables use type std::atomic<T>:
std::atomic<void*> head;
3. For usual non-atomic variables use type rl::var<T>:
rl::var<int> data;
Such vars will be checked for races and included into trace.
4. All accesses to std::atomic<T> and rl::var<T> variables postfix with '($)':
std::atomic<void*> head;
rl::var<int> data;
head($).store(0);
data($) = head($).load();
5. Strictly thread-private variables use can leave as-is:
for (int i = 0; i != 10; ++i)
Such vars will be NOT checked for races NOR included into trace. But they will accelerate verification.
6. Describe test-suite: number of threads, thread function, before/after/invariant functions. See example below.
7. Place asserts:
int x = g($).load();
RL_ASSERT(x > 0);
8. Start verification:
rl::simulate<test_suite_t>();
Here is complete example:
#include <relacy/relacy_std.hpp>
// template parameter '2' is number of threads
struct race_test : rl::test_suite<race_test, 2>
{
std::atomic<int> a;
rl::var<int> x;
// executed in single thread before main thread function
void before()
{
a($) = 0;
x($) = 0;
}
// main thread function
void thread(unsigned thread_index)
{
if (0 == thread_index)
{
x($) = 1;
a($).store(1, rl::memory_order_relaxed);
}
else
{
if (1 == a($).load(rl::memory_order_relaxed))
x($) = 2;
}
}
// executed in single thread after main thread function
void after()
{
}
// executed in single thread after every 'visible' action in main threads
// disallowed to modify any state
void invariant()
{
}
};
int main()
{
rl::simulate<race_test>();
}
@@ -0,0 +1,369 @@
#pragma once
#include "../relacy/relacy_std.hpp"
struct test_wfmo_all : rl::test_suite<test_wfmo_all, 2>
{
HANDLE sema1;
HANDLE sema2;
rl::var<int> data;
void before()
{
sema1 = CreateSemaphore(0, 0, 2, 0);
sema2 = CreateSemaphore(0, 0, 2, 0);
data($) = 0;
}
void after()
{
CloseHandle(sema1);
CloseHandle(sema2);
}
void thread(unsigned index)
{
if (0 == index)
{
HANDLE handles [2] = {sema1, sema2};
WaitForMultipleObjects(2, handles, 1, INFINITE);
RL_ASSERT(data($) == 2);
}
else
{
data($) = 1;
ReleaseSemaphore(sema1, 1, 0);
data($) = 2;
ReleaseSemaphore(sema2, 1, 0);
}
}
};
struct test_wfmo_single : rl::test_suite<test_wfmo_single, 2, rl::test_result_until_condition_hit>
{
HANDLE sema1;
HANDLE sema2;
rl::atomic<int> data;
void before()
{
sema1 = CreateSemaphore(0, 0, 2, 0);
sema2 = CreateSemaphore(0, 0, 2, 0);
data($) = 0;
}
void after()
{
CloseHandle(sema1);
CloseHandle(sema2);
}
void thread(unsigned index)
{
if (0 == index)
{
HANDLE handles [2] = {sema1, sema2};
WaitForMultipleObjects(2, handles, 0, INFINITE);
int d = data.load(rl::memory_order_relaxed);
RL_ASSERT(d == 1 || d == 2);
RL_UNTIL(d == 1);
}
else
{
data.store(1, rl::memory_order_relaxed);
ReleaseSemaphore(sema1, 1, 0);
data.store(2, rl::memory_order_relaxed);
ReleaseSemaphore(sema2, 1, 0);
}
}
};
struct test_wfmo_timeout : rl::test_suite<test_wfmo_timeout, 2, rl::test_result_until_condition_hit>
{
HANDLE sema1;
HANDLE sema2;
rl::atomic<int> data;
void before()
{
sema1 = CreateSemaphore(0, 0, 2, 0);
sema2 = CreateSemaphore(0, 0, 2, 0);
data($) = 0;
}
void after()
{
CloseHandle(sema1);
CloseHandle(sema2);
}
void thread(unsigned index)
{
if (0 == index)
{
HANDLE handles [2] = {sema1, sema2};
WaitForMultipleObjects(2, handles, 0, 100);
int d = data.load(rl::memory_order_relaxed);
RL_ASSERT(d == 0 || d == 1 || d == 2);
RL_UNTIL(d == 0);
}
else
{
data.store(1, rl::memory_order_relaxed);
ReleaseSemaphore(sema1, 1, 0);
data.store(2, rl::memory_order_relaxed);
ReleaseSemaphore(sema2, 1, 0);
}
}
};
struct test_wfmo_try : rl::test_suite<test_wfmo_try, 2>
{
HANDLE sema1;
HANDLE sema2;
rl::atomic<int> d;
rl::atomic<int> d1;
rl::atomic<int> d2;
void before()
{
sema1 = CreateSemaphore(0, 1, 2, 0);
sema2 = CreateSemaphore(0, 1, 2, 0);
d1($) = 0;
d2($) = 0;
}
void after()
{
CloseHandle(sema1);
CloseHandle(sema2);
}
void thread(unsigned index)
{
if (0 == index)
{
d1.store(1, rl::memory_order_relaxed);
HANDLE handles [2] = {sema1, sema2};
if (WAIT_TIMEOUT == WaitForMultipleObjects(2, handles, 1, 0))
RL_ASSERT(1 == d2.load(rl::memory_order_relaxed));
}
else if (1 == index)
{
d2.store(1, rl::memory_order_relaxed);
HANDLE handles [2] = {sema2, sema1};
if (WAIT_TIMEOUT == WaitForMultipleObjects(2, handles, 1, 0))
RL_ASSERT(1 == d1.load(rl::memory_order_relaxed));
}
}
};
struct test_wfmo_mixed : rl::test_suite<test_wfmo_mixed, 3>
{
HANDLE sem [2];
void before()
{
sem[0] = CreateSemaphore(0, 0, 2, 0);
sem[1] = CreateSemaphore(0, 0, 2, 0);
}
void after()
{
CloseHandle(sem[0]);
CloseHandle(sem[1]);
}
void thread(unsigned index)
{
if (0 == index)
{
ReleaseSemaphore(sem[0], 1, 0);
ReleaseSemaphore(sem[0], 1, 0);
ReleaseSemaphore(sem[1], 1, 0);
}
else if (1 == index)
{
unsigned rv = WaitForMultipleObjects(2, sem, 1, INFINITE);
assert(rv == WAIT_OBJECT_0);
}
else if (2 == index)
{
unsigned rv = WaitForSingleObject(sem[0], INFINITE);
assert(rv == WAIT_OBJECT_0);
}
}
};
struct test_wfmo_mixed2 : rl::test_suite<test_wfmo_mixed2, 4>
{
HANDLE sem [2];
void before()
{
sem[0] = CreateSemaphore(0, 0, 2, 0);
sem[1] = CreateSemaphore(0, 0, 2, 0);
}
void after()
{
CloseHandle(sem[0]);
CloseHandle(sem[1]);
}
void thread(unsigned index)
{
if (0 == index)
{
ReleaseSemaphore(sem[1], 1, 0);
ReleaseSemaphore(sem[0], 1, 0);
ReleaseSemaphore(sem[0], 1, 0);
}
else if (1 == index)
{
unsigned rv = WaitForSingleObject(sem[0], INFINITE);
assert(rv == WAIT_OBJECT_0);
}
else if (2 == index || 3 == index)
{
unsigned rv = WaitForMultipleObjects(2, sem, 1, 42);
assert(rv == WAIT_OBJECT_0 || rv == WAIT_TIMEOUT);
}
}
};
struct test_wfmo_event_all : rl::test_suite<test_wfmo_event_all, 2>
{
HANDLE ev [2];
rl::atomic<int> state;
void before()
{
ev[0] = CreateEvent(0, 0, 0, 0);
ev[1] = CreateEvent(0, 1, 0, 0);
state.store(0, rl::memory_order_relaxed);
}
void after()
{
CloseHandle(ev[0]);
CloseHandle(ev[1]);
}
void thread(unsigned index)
{
if (0 == index)
{
unsigned rv = WaitForMultipleObjects(2, ev, 1, INFINITE);
assert(rv == WAIT_OBJECT_0 + 0 || rv == WAIT_OBJECT_0 + 1);
assert(state.load(rl::memory_order_relaxed) == 1);
}
else if (1 == index)
{
SetEvent(ev[0]);
state.store(1, rl::memory_order_relaxed);
SetEvent(ev[1]);
}
}
};
struct test_wfmo_event_any : rl::test_suite<test_wfmo_event_any, 2>
{
HANDLE ev [2];
rl::atomic<int> state;
void before()
{
ev[0] = CreateEvent(0, 0, 0, 0);
ev[1] = CreateEvent(0, 1, 0, 0);
state.store(0, rl::memory_order_relaxed);
}
void after()
{
CloseHandle(ev[0]);
CloseHandle(ev[1]);
}
void thread(unsigned index)
{
if (0 == index)
{
unsigned rv = WaitForMultipleObjects(2, ev, 0, INFINITE);
assert(rv == WAIT_OBJECT_0 + 0 || rv == WAIT_OBJECT_0 + 1);
assert(state.load(rl::memory_order_relaxed) == 1);
}
else if (1 == index)
{
state.store(1, rl::memory_order_relaxed);
SetEvent(ev[0]);
SetEvent(ev[1]);
}
}
};
struct test_wfmo_atomic : rl::test_suite<test_wfmo_atomic, 2, rl::test_result_until_condition_hit>
{
HANDLE ev [2];
rl::atomic<int> state;
void before()
{
ev[0] = CreateEvent(0, 0, 0, 0);
ev[1] = CreateEvent(0, 0, 0, 0);
}
void after()
{
CloseHandle(ev[0]);
CloseHandle(ev[1]);
}
void thread(unsigned index)
{
if (0 == index)
{
state.store(1, rl::memory_order_relaxed);
WaitForMultipleObjects(2, ev, 0, 1);
}
else if (1 == index)
{
SetEvent(ev[0]);
SetEvent(ev[1]);
unsigned rv = WaitForSingleObject(ev[0], 0);
if (rv == WAIT_TIMEOUT) {
assert(state.load(rl::memory_order_relaxed) == 1);
RL_UNTIL(true);
}
}
}
};
@@ -0,0 +1,339 @@
#pragma once
#include "../relacy/windows.h"
struct test_win_thread : rl::test_suite<test_win_thread, 1>
{
static size_t const dynamic_thread_count = 2;
VAR_T(int) data;
static unsigned long RL_STDCALL win_func(void* param)
{
static_cast<test_win_thread*>(param)->VAR(data) += 1;
return 0;
}
static unsigned RL_STDCALL msvc_func(void* param)
{
static_cast<test_win_thread*>(param)->VAR(data) += 1;
return 0;
}
void thread(unsigned)
{
VAR(data) = 0;
HANDLE th1 = CreateThread(0, 0, &test_win_thread::win_func, this, 0, 0);
WaitForSingleObject(th1, INFINITE);
RL_ASSERT(VAR(data) == 1);
HANDLE th2 = (HANDLE)_beginthreadex(0, 0, &test_win_thread::msvc_func, this, 0, 0);
WaitForSingleObject(th2, INFINITE);
RL_ASSERT(VAR(data) == 2);
}
};
struct test_win_mutex : rl::test_suite<test_win_mutex, 2>
{
HANDLE mtx;
VAR_T(int) data;
void before()
{
mtx = CreateMutex(0, 0, 0);
VAR(data) = 0;
}
void after()
{
CloseHandle(mtx);
}
void thread(unsigned)
{
WaitForSingleObject(mtx, INFINITE);
WaitForSingleObject(mtx, INFINITE);
VAR(data) += 1;
ReleaseMutex(mtx);
ReleaseMutex(mtx);
if (WAIT_OBJECT_0 == WaitForSingleObject(mtx, 0))
{
VAR(data) += 1;
ReleaseMutex(mtx);
}
}
};
struct test_win_cs : rl::test_suite<test_win_cs, 2>
{
CRITICAL_SECTION mtx;
VAR_T(int) data;
void before()
{
InitializeCriticalSection(&mtx);
VAR(data) = 0;
}
void after()
{
DeleteCriticalSection(&mtx);
}
void thread(unsigned)
{
EnterCriticalSection(&mtx);
VAR(data) += 1;
LeaveCriticalSection(&mtx);
if (TryEnterCriticalSection(&mtx))
{
VAR(data) += 1;
LeaveCriticalSection(&mtx);
}
}
};
struct test_win_condvar : rl::test_suite<test_win_condvar, 3>
{
CONDITION_VARIABLE cv;
CRITICAL_SECTION mtx;
VAR_T(int) stage;
void before()
{
InitializeConditionVariable(&cv);
InitializeCriticalSection(&mtx);
VAR(stage) = 0;
}
void after()
{
DeleteCriticalSection(&mtx);
DeleteConditionVariable(&cv);
}
void thread(unsigned index)
{
if (0 == index)
{
EnterCriticalSection(&mtx);
VAR(stage) += 1;
WakeAllConditionVariable(&cv);
while (VAR(stage) != 2)
SleepConditionVariableCS(&cv, &mtx, INFINITE);
LeaveCriticalSection(&mtx);
}
else if (1 == index)
{
EnterCriticalSection(&mtx);
while (VAR(stage) != 1)
SleepConditionVariableCS(&cv, &mtx, 1);
VAR(stage) += 1;
WakeAllConditionVariable(&cv);
LeaveCriticalSection(&mtx);
}
else if (2 == index)
{
EnterCriticalSection(&mtx);
while (VAR(stage) != 2)
SleepConditionVariableCS(&cv, &mtx, INFINITE);
LeaveCriticalSection(&mtx);
WakeConditionVariable(&cv);
}
}
};
struct test_win_condvar_srw : rl::test_suite<test_win_condvar_srw, 2>
{
CONDITION_VARIABLE cv;
SRWLOCK mtx;
VAR_T(int) stage;
void before()
{
InitializeConditionVariable(&cv);
InitializeSRWLock(&mtx);
VAR(stage) = 0;
}
void after()
{
DeleteSRWLock(&mtx);
DeleteConditionVariable(&cv);
}
void thread(unsigned index)
{
if (0 == index)
{
AcquireSRWLockExclusive(&mtx);
VAR(stage) += 1;
WakeAllConditionVariable(&cv);
while (VAR(stage) != 2)
SleepConditionVariableSRW(&cv, &mtx, INFINITE, 0);
ReleaseSRWLockExclusive(&mtx);
}
else if (1 == index)
{
AcquireSRWLockExclusive(&mtx);
while (VAR(stage) != 1)
SleepConditionVariableSRW(&cv, &mtx, 1, 0);
VAR(stage) += 1;
WakeAllConditionVariable(&cv);
ReleaseSRWLockExclusive(&mtx);
}
else if (2 == index)
{
AcquireSRWLockExclusive(&mtx);
while (VAR(stage) != 2)
SleepConditionVariableSRW(&cv, &mtx, INFINITE, 0);
ReleaseSRWLockExclusive(&mtx);
WakeConditionVariable(&cv);
}
}
};
struct test_win_sem : rl::test_suite<test_win_sem, 2>
{
HANDLE sem1, sem2;
VAR_T(int) data;
void before()
{
sem1 = CreateSemaphore(0, 0, 1, 0);
sem2 = CreateSemaphore(0, 0, 1, 0);
VAR(data) = 0;
}
void after()
{
CloseHandle(sem1);
CloseHandle(sem2);
}
void thread(unsigned index)
{
if (index)
{
VAR(data) = 1;
long count = -1;
ReleaseSemaphore(sem1, 1, &count);
assert(count == 0);
for (;;)
{
unsigned long rv = WaitForSingleObject(sem2, 0);
if (rv == WAIT_OBJECT_0)
break;
RL_ASSERT(rv == WAIT_TIMEOUT);
Sleep(0);
}
RL_ASSERT(VAR(data) == 2);
VAR(data) = 3;
ReleaseSemaphore(sem2, 1, &count);
RL_ASSERT(count == 0);
ReleaseSemaphore(sem2, 1, &count);
RL_ASSERT(count == 1);
}
else
{
unsigned long rv = WaitForSingleObject(sem1, INFINITE);
assert(rv == WAIT_OBJECT_0);
RL_ASSERT(VAR(data) == 1);
VAR(data) = 2;
ReleaseSemaphore(sem2, 1, 0);
}
}
};
struct test_win_event : rl::test_suite<test_win_event, 2>
{
HANDLE ev;
VAR_T(int) data;
void before()
{
VAR(data) = 0;
ev = CreateEvent(0, 0, 0, 0);
}
void after()
{
CloseHandle(ev);
}
void thread(unsigned index)
{
if (0 == index)
{
VAR(data) = 1;
SetEvent(ev);
PulseEvent(ev);
}
else
{
unsigned rv = WaitForSingleObject(ev, INFINITE);
assert(rv == WAIT_OBJECT_0);
assert(VAR(data) == 1);
rv = WaitForSingleObject(ev, 0);
assert(rv == WAIT_TIMEOUT);
ResetEvent(ev);
}
}
};
struct test_FlushProcessWriteBuffers : rl::test_suite<test_FlushProcessWriteBuffers, 2>
{
std::atomic<int> x1;
std::atomic<int> x2;
int r1;
int r2;
void before()
{
x1.store(0, std::memory_order_relaxed);
x2.store(0, std::memory_order_relaxed);
r1 = r2 = 0;
}
void after()
{
assert(r1 == 1 || r2 == 1);
}
void thread(unsigned index)
{
if (index)
{
x1.store(1, std::memory_order_relaxed);
r1 = x2.load(std::memory_order_relaxed);
}
else
{
x2.store(1, std::memory_order_relaxed);
FlushProcessWriteBuffers();
r2 = x1.load(std::memory_order_relaxed);
}
}
};