Efficiently implementing a large shared array of structs

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?

What do you do if a thread encounters a locked element? Spin?

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.

1 Like

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.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.