> Can you please review my implementation of Dekker's algorithm and tell me if my memory ordering on atomic operations is correct. I think it is but I need to double check...
[...]
Fwiw, I can only get Dekker's algorihtm to work with the following
membars. This is a Relacy test unit, take a deep look at ct_dekker:
__________________________________
// Dekker Test
// Relacy Test By Chris M. Thomasson
//_______________________________________________
//#define RL_DEBUGBREAK_ON_ASSERT
//#define RL_MSVC_OUTPUT
//#define RL_FORCE_SEQ_CST
//#define RL_GC
#include <relacy/relacy_std.hpp>
#include <iostream>
#define THREADS (2) // Only 2 threads will work here...
struct ct_dekker
{
std::atomic<bool> f1;
std::atomic<bool> f2;
ct_dekker() : f1(false), f2(false) {}
void p0_lock()
{
for (;;)
{
f1.store(true, std::memory_order_seq_cst);
if (f2.load(std::memory_order_seq_cst) == false)
{
break;
}
f1.store(false, std::memory_order_relaxed);
rl::yield(1, $);
}
}
void p0_unlock()
{
f1.store(false, std::memory_order_release);
}
void p1_lock()
{
for (;;)
{
f2.store(true, std::memory_order_seq_cst);
if (f1.load(std::memory_order_seq_cst) == false)
{
break;
}
f2.store(false, std::memory_order_relaxed);
rl::yield(1, $);
}
}
void p1_unlock()
{
f2.store(false, std::memory_order_release);
}
};
// Relacy Dekker
struct ct_dekker_test
: rl::test_suite<ct_dekker_test, THREADS>
{
VAR_T(long) g_shared_state;
ct_dekker g_dekker;
void before()
{
VAR(g_shared_state) = 0;
}
void after()
{
}
void thread(unsigned int tidx)
{
if (tidx < 1)
{
g_dekker.p0_lock();
++VAR(g_shared_state);
g_dekker.p0_unlock();
}
else
{
g_dekker.p1_lock();
++VAR(g_shared_state);
g_dekker.p1_unlock();
}
}
};
// Test away... Or fly? Humm...
int main()
{
{
rl::test_params p;
p.iteration_count = 10000000;
//p.execution_depth_limit = 33333;
//p.search_type = rl::sched_bound;
//p.search_type = rl::fair_full_search_scheduler_type;
//p.search_type = rl::fair_context_bound_scheduler_type;
rl::simulate<ct_dekker_test>(p);
}
return 0;
}
__________________________________