Experimental futex mutex test, c++20...
From
Chris M. Thomasson@chris.m.thomasson.1@gmail.com to
comp.lang.c++ on Sun Apr 14 12:53:01 2024
From Newsgroup: comp.lang.c++
This is a quick and dirty impl of a mutex using c++20 futexes for slow paths... Now, before I go any further, can anybody else compile and run
the following code of mine? Thanks:
_______________________________________
#include <iostream>
#include <functional>
#include <atomic>
#include <thread>
#include <cstdlib>
// Ughh, some quick test params...
#define CT_L2_CACHE 128UL
#define CT_THREAD_N 8UL
#define CT_ITER_N 10000000UL
struct alignas(CT_L2_CACHE) ct_futex_mutex
{
std::atomic<unsigned int> m_state = 0;
void lock()
{
if (m_state.exchange(1, std::memory_order_acquire))
{
while (m_state.exchange(2, std::memory_order_acquire))
{
m_state.wait(2, std::memory_order_relaxed);
}
}
}
void unlock()
{
if (m_state.exchange(0, std::memory_order_release) == 2)
{
m_state.notify_one();
}
}
};
struct alignas(CT_L2_CACHE) ct_test_vars
{
long m_v0 = 0;
long m_v1 = 0;
long m_v2 = 0;
void update()
{
m_v0 += 1;
m_v1 += 1;
m_v2 += 2;
}
void dump_state()
{
std::cout << "ct_test_vars::dump_state()\n";
std::cout << "__________________________\n";
std::cout << "m_v0 = " << m_v0 << "\n";
std::cout << "m_v1 = " << m_v1 << "\n";
std::cout << "m_v2 = " << m_v2 << "\n";
std::cout << "__________________________\n" << std::endl;
}
};
struct ct_shared
{
ct_futex_mutex m_futex_mutex;
ct_test_vars m_test_vars;
void dump_state()
{
std::cout << "ct_shared::dump_state()\n";
m_test_vars.dump_state();
}
bool check_state()
{
if (m_test_vars.m_v0 == CT_ITER_N * CT_THREAD_N &&
m_test_vars.m_v1 == CT_ITER_N * CT_THREAD_N &&
m_test_vars.m_v2 == CT_ITER_N * CT_THREAD_N * 2)
{
return true;
}
return false;
}
};
void ct_thread(ct_shared& shared)
{
for (unsigned long i = 0; i < CT_ITER_N; ++i)
{
shared.m_futex_mutex.lock();
shared.m_test_vars.update();
shared.m_futex_mutex.unlock();
}
}
int main()
{
std::cout << "ct_c++20_futex_test\n\n";
std::cout << "__________________________________\n\n" << std::endl;
{
ct_shared shared;
std::cout << "Creating Threads..." << std::endl;
std::thread threads[CT_THREAD_N];
for (unsigned long i = 0; i < CT_THREAD_N; ++i)
{
threads[i] = std::thread(ct_thread, std::ref(shared));
}
std::cout << "Running...\n" << std::endl;
for (unsigned long i = 0; i < CT_THREAD_N; ++i)
{
threads[i].join();
}
shared.dump_state();
if (! shared.check_state())
{
std::cout << "OH SHIT!!!!! The crap sure hit the fan!!!\n";
}
}
std::cout << "Complete!" << std::endl;
return EXIT_SUCCESS;
}
_______________________________________
--- Synchronet 3.20a-Linux NewsLink 1.114