I am trying to re-implement in Rust something that I wrote in C (and in Zig).
I have an array of structs that I share among different threads.
Each element of the array contains various fields and an Atomic_bool which is used as a mutex to protect concurrent access to this particular element (using atomic_compare_exchange_weak() ); each element looks like that:
struct {
int sig;
int v;
atomic_bool m;}
What would be the "idiomatic way" to do that in Rust?
Assuming array refers to fixed-size array of static length…
…so the struct would be idiomatically put into a std::sync::Mutex instead of implementing your own “mutex” logic. The standard library implementation does have a fast-path that merely uses an atomic integer, and also a fast-path that spins for a short while before any OS-interaction happens and the thread is getting parked.
Let’s call the struct Foo, and the array length is 42 then you could just define
struct Foo {
sig: i32,
v: i32,
}
and then use a [Mutex<Foo>; 42] that’s shared between threads.
Either it can be shared between threads by shared reference – &[Mutex<Foo>; 42] – accessed from scoped threads, or by shared-ownership via Arc<[Mutex<Foo>; 42]>; or it could live in a global static variable.
By the way, there also is no memory overhead. E.g. Mutex<Foo> on linux would be an entirely flat struct, no heap allocations, and not significantly larger (if at all…) than your original C struct, as all it does is store a Foo struct along a single 32 bit atomic integer.
In that particular case, it is highly improbable that 2 threads might access the same data at the same time. But all threads access the table very often. So spin in that particular case is acceptable, as atomic_compare_exchange_weak() is almost always OK (the possibility of spinlock is small), but as it is called very often, making an OS system call instead would be expensive.