On 12/7/2018 3:57 PM, Chris M. Thomasson wrote:
> One can use a simple exchange to get a sort of work queue thing up and
> running, however the use case can be interesting and simply might not be
> compatible with with certain algorithms. There really is no distinction
> between producer and consumer threads in this scheme. The act of
> producing work, can actually consume work at the same time!
>
> So, it is kind of sometime like:
[...]
Fwiw, here is a hyper simple Relacy unit test:
// I love this, been using it for years...
https://github.com/dvyukov/relacy
___________________________
// A stupid simple swap queue... ;^)
//#define RL_DEBUGBREAK_ON_ASSERT
//#define RL_MSVC_OUTPUT
//#define RL_FORCE_SEQ_CST
//#define RL_GC
#include <relacy/relacy_std.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#define ct_mb_relaxed std::memory_order_relaxed
#define ct_mb_acquire std::memory_order_acquire
#define ct_mb_release std::memory_order_release
#define ct_mb_acq_rel std::memory_order_acq_rel
#define THREADS 5
#define ITERS 3
struct ct_swapq
{
struct work
{
VAR_T(unsigned int) m_data;
work(unsigned int data) : m_data(data) {}
void process()
{
unsigned int x = VAR(m_data);
RL_ASSERT(x >= 0);
//std::cout << VAR(m_data) << "\n";
}
};
std::atomic<work*> m_head;
ct_swapq() : m_head(nullptr) { }
work* swap(work* n)
{
return m_head.exchange(n, ct_mb_acq_rel);
}
};
// Test
struct ct_swapq_test
: rl::test_suite<ct_swapq_test, THREADS>
{
ct_swapq g_mpmc;
void before()
{
}
void after()
{
}
void thread(unsigned int tidx)
{
for (unsigned int i = 0; i < ITERS; ++i)
{
ct_swapq::work* wnew = new ct_swapq::work(tidx * tidx + i);
ct_swapq::work* wold = g_mpmc.swap(wnew);
if (wold)
{
wold->process();
delete wold;
}
}
ct_swapq::work* wold = g_mpmc.swap(nullptr);
if (wold)
{
wold->process();
delete wold;
}
}
};
int main()
{
{
rl::test_params p;
p.iteration_count = 5000000;
//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_swapq_test>(p);
}
return 0;
}
___________________________
Next code will be a simple C++11 example.