184 lines
3.9 KiB
C++
184 lines
3.9 KiB
C++
#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($);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
|