Fwiw, here is a total experiment of mine. I think it should work, need[...]
to verify in Relacy (no time right now), but its a way to have a work
stack and a critical section at the same time. I really need to add in a try_lock that pops the stack while trying to acquire the mutex. Anyway,
can go give it a go in your spare time? Thanks. Show me some output?
Be sure to take careful notice of the ct_stack_mutex struct...
C++20:
___________________________________
ct_work*
unlock()
{
ct_work* self_work = m_head.exchange(CT_UNLOCKED);
if (self_work == CT_CONTENTION)[...]
{
m_wset.release();
return nullptr;
}
return self_work;
}
Fwiw, here is a total experiment of mine. I think it should work, need[...]
to verify in Relacy (no time right now), but its a way to have a work
stack and a critical section at the same time. I really need to add in a try_lock that pops the stack while trying to acquire the mutex. Anyway,
can go give it a go in your spare time? Thanks. Show me some output?
Be sure to take careful notice of the ct_stack_mutex struct...
C++20:
___________________________________
struct ct_stack_mutex
{
std::atomic<ct_work*> m_head = { CT_UNLOCKED };
std::binary_semaphore m_wset{ 0 };
ct_work*
lock(ct_work* work)
{
ct_work* self_work = m_head.exchange(work, std::memory_order_acquire);
ct_work* local_work = nullptr;
if (self_work != CT_UNLOCKED || self_work == CT_CONTENTION)
{
if (self_work != CT_CONTENTION)
{
self_work->m_next.store(local_work, std::memory_order_relaxed);
local_work = self_work;
}
for (;;)
{
self_work = m_head.exchange(CT_CONTENTION, std::memory_order_acquire);
if (self_work != CT_UNLOCKED && self_work !=
CT_CONTENTION)
{
self_work->m_next.store(local_work, std::memory_order_relaxed);
local_work = self_work;
}
if (self_work == CT_UNLOCKED)
{
break;
}
m_wset.acquire();
}
}
else if (self_work != CT_UNLOCKED)
{
self_work->m_next.store(local_work,
std::memory_order_relaxed);
local_work = self_work;
}
return local_work;
}
Fwiw, here is a total experiment of mine. I think it should work, need
to verify in Relacy (no time right now), but its a way to have a work
stack and a critical section at the same time. I really need to add in a try_lock that pops the stack while trying to acquire the mutex. Anyway,
can go give it a go in your spare time? Thanks. Show me some output?
Be sure to take careful notice of the ct_stack_mutex struct...
C++20:
___________________________________
// A Fun Mutex Pattern? Or, a Nightmare? Humm...
// By: Chris M. Thomasson //___________________________________________________
#include <iostream>
#include <random>
#include <numeric>
#include <algorithm>
#include <thread>
#include <atomic>
#include <mutex>
#include <string>
#include <semaphore>
#define CT_WORKERS (100)
#define CT_ITERS (1000000)
static std::atomic<unsigned long> g_ct_work_alloc = { 0 };
static std::atomic<unsigned long> g_ct_work_dealloc = { 0 };
#define CT_UNLOCKED (nullptr)
#define CT_CONTENTION (reinterpret_cast<ct_work*>(0xDEADBEEF))
struct ct_work
{
std::atomic<ct_work*> m_next;
std::string m_payload;
ct_work(std::string const& payload)
: m_next(nullptr),
m_payload(payload)
{
g_ct_work_alloc.fetch_add(1, std::memory_order_relaxed);
}
~ct_work()
{
g_ct_work_dealloc.fetch_add(1, std::memory_order_relaxed);
}
void
dump() const
{
std::cout << "(" << this << ")->ct_work::m_payload = " <<
m_payload << "\n";
}
};
struct ct_stack_mutex
{
std::atomic<ct_work*> m_head = { CT_UNLOCKED };
std::binary_semaphore m_wset{ 0 };
ct_work*
lock(ct_work* work)
{
ct_work* self_work = m_head.exchange(work, std::memory_order_acquire);
ct_work* local_work = nullptr;
if (self_work != CT_UNLOCKED || self_work == CT_CONTENTION)
{
if (self_work != CT_CONTENTION)
{
self_work->m_next.store(local_work, std::memory_order_relaxed);
local_work = self_work;
}
for (;;)
{
self_work = m_head.exchange(CT_CONTENTION, std::memory_order_acquire);
if (self_work != CT_UNLOCKED && self_work !=
CT_CONTENTION)
{
self_work->m_next.store(local_work, std::memory_order_relaxed);
local_work = self_work;
}
if (self_work == CT_UNLOCKED)
{
break;
}
m_wset.acquire();
}
}
else if (self_work != CT_UNLOCKED)
{
self_work->m_next.store(local_work,
std::memory_order_relaxed);
local_work = self_work;
}
return local_work;
}
ct_work*
unlock()
{
ct_work* self_work = m_head.exchange(CT_UNLOCKED);
if (self_work == CT_CONTENTION)
{
m_wset.release();
return nullptr;
}
return self_work;
}
};
struct ct_shared
{
ct_stack_mutex m_mutex;
unsigned long m_var0 = 0;
};
void
ct_worker_entry(
ct_shared& shared
) {
//std::cout << "ct_worker_entry" << std::endl; // testing thread
race for sure...
{
for (unsigned long i = 0; i < CT_ITERS; ++i)
{
ct_work* w0 = new ct_work("ct_work");
ct_work* wlock = shared.m_mutex.lock(w0);
{
shared.m_var0 += 2;
}
ct_work* wunlock = shared.m_mutex.unlock();
while (wlock)
{
ct_work* next = wlock-
m_next.load(std::memory_order_relaxed);delete wlock;
wlock = next;
}
while (wunlock)
{
ct_work* next = wunlock-
m_next.load(std::memory_order_relaxed);delete wunlock;
wunlock = next;
}
}
}
}
int main()
{
// Hello... :^)
{
std::cout << "Hello ct_fun_mutex... lol? ;^) ver:(0.0.0)\n";
std::cout << "By: Chris M. Thomasson\n";
std::cout << "____________________________________________________\n";
std::cout.flush();
}
// Create our fun things... ;^)
ct_shared shared = { };
std::thread workers[CT_WORKERS] = { };
// Lanuch...
{
std::cout << "Launching " << CT_WORKERS << " Threads...\n";
std::cout.flush();
for (unsigned long i = 0; i < CT_WORKERS; ++i)
{
workers[i] = std::thread(ct_worker_entry, std::ref(shared));
}
}
// Join...
{
std::cout << "Joining Threads... (computing :^)\n";
std::cout.flush();
for (unsigned long i = 0; i < CT_WORKERS; ++i)
{
workers[i].join();
}
}
// Sanity Check...
{
std::cout << "shared.m_var0 = " << shared.m_var0 << "\n";
std::cout << "g_ct_work_alloc = " << g_ct_work_alloc.load(std::memory_order_relaxed) << "\n";
std::cout << "g_ct_work_dealloc = " << g_ct_work_dealloc.load(std::memory_order_relaxed) << "\n";
if (g_ct_work_alloc != g_ct_work_dealloc ||
shared.m_var0 != CT_WORKERS * CT_ITERS * 2)
{
std::cout << "\nOh God damn it!!!! ;^o\n";
}
}
// Fin...
{
std::cout << "____________________________________________________\n";
std::cout << "Fin... :^)\n" << std::endl;
}
return 0;
}
___________________________________
Am 18.08.2025 um 01:51 schrieb Chris M. Thomasson:
Fwiw, here is a total experiment of mine. I think it should work, need
to verify in Relacy (no time right now), but its a way to have a work
stack and a critical section at the same time. I really need to add in
a try_lock that pops the stack while trying to acquire the mutex.
Anyway, can go give it a go in your spare time? Thanks. Show me some
output?
Be sure to take careful notice of the ct_stack_mutex struct...
Sorry, you still don't understand that your idea is complete nonsense
because the "otherwise-task" could be completely omitted. And popping
a stack alone isn't sth. meaningful.
Find a paper that describes your idea. I'm pretty sure a lot of people
had this idea and they've all withdrawn it because of the issues I
mentioned.
You seem to be manic.
You're focussed on details and you don't see the
abstraction levels above that which make ideas like that completely gratitious. Take care that it doesn't get worse.
Sysop: | Tetrazocine |
---|---|
Location: | Melbourne, VIC, Australia |
Users: | 11 |
Nodes: | 8 (0 / 8) |
Uptime: | 50:07:19 |
Calls: | 166 |
Files: | 21,502 |
Messages: | 77,727 |