they're all on https://github.com/samsquire/assembly, i tried to write multiple disruptor with multiple consumers, then one with multiple producers then one with multiple consumers AND multiple producers, inspired by LMAX Disruptor. (There's files for each of them and table in the repo. it's not proven yet!)
the contention on the same memory address (the read/write index) is the thing that seems difficult to address.
One thing I've learned about thread safety:
I think if you have thread-owned values then you can be thread safe with a simple semaphore, providing that you have unique, DISTINCT values for each thread.
If you have two threads that have this in a hot loop in parallel:
// thread 0
if buffer[x].available == 1:
// do stuff
buffer[x].available = 0
// thread 1
if buffer[x].available == 0:
// do stuff
buffer[x].available = 1
Due to causality, no matter the interleaving, thread 0 owns the buffer[x].available and body of the if statement when it is 1 and thread 1 owns the body of the if statement buffer[x].available when it is 0.The CMP is a cheap mutex with distinct valued memory locations.
Even though thread 1 is writing to buffer[x].available and thread 0 is writing to buffer[x].available it doesn't matter because the causality is mutually exclusive. There is no interleaving of buffer[x].available = x because of the if statement.
The buffer[x].available = 0 will never run while buffer[x].available is equal to 0 overwriting or causing a data race when setting buffer[x].available to 1. So the second line cannot happen in parallel.
I need to write a TLA model to assert its safety.
If you have more than 2 threads, then you need different tokens to provide admissability to the if statement.
Remember to use compiler memory barrier
asm volatile ("" ::: "memory");
so you don't need volatile struct values.