Add loom tests for lock-free datastructures in iceoryx2-bb
Improvement Suggestion
Loom is a testing library for concurrent applications. It systematically explores all possible interleavings in a multithreaded program to detect subtle concurrency bugs.
It's already used in major projects, such as tokio-rs.
I believe adding Loom-based tests would improve the reliability of concurrent data structures like those in iceoryx2-bb/lock-free. (I also found that there is a todo comment for that.)
If you're okay with it, I'd be happy to submit a PR.
@mox692 We would be happy to receive a PR from you. If you need any support or pointers, please do not hesitate to ask us.
@mox692, Could you create one PR per lock-free data structure? Lock-free code is always hard and this would give us more focus on the individual tests.
Here is a list of the lock-free data structures and where they are used. You are free to start with any data structure you like but I would recommend to start at the top - those are the easiest and it would give us all the chance to get familiar with loom and the tests.
- Prepare codebase for loom
-
iceoryx2-bb/lock-free/src/spsc/index_queue.rs- Used to return pointer offsets from a receiver back to the sender -
iceoryx2-bb/lock-free/src/spsc/safely_overflowing_index_queue.rs- Used to deliver pointer offsets from a sender to the receiver. Handles backpressure by returning the oldest data back to the producer and replaces it with the newest data. -
iceoryx2-bb/lock-free/src/mpmc/unique_index_set.rs- Used by the pool allocator in the publishers data segment. The indices correspond to the allocators' buckets. -
iceoryx2-bb/lock-free/src/mpmc/container.rs- Used by the dynamic service segment and stores all connected ports. Whenever a sender is delivering data, it acquires the list of all the ports and iterates through them to deliver the pointer offset. - Then the remaining lock-free code ...
Loom requires that the atomics are substituted with their atomic types loom::sync::atomic::Atomic**. We already - partially - took care of this with: https://github.com/eclipse-iceoryx/iceoryx2/blob/main/iceoryx2-pal/concurrency-sync/src/iox_atomic.rs
Before we could start writing the first loom test, we would need to extend iceoryx2-pal-concurrency-sync to also cover the sync::atomic::Ordering. The idea is that everywhere in iceoryx2 only the atomics (and even maybe Arcs) defined in concurrency sync are used. This is ensured via clippy, see here: https://github.com/eclipse-iceoryx/iceoryx2/blob/main/clippy.toml
Then we need to introduce a feature flag like lock_free_testing in iceoryx2-pal-concurrency-sync that then uses the loom types instead of the core types in the atomic type aliases. Then we would be able to write directly the loom tests - they would also be only compiled when the feature flag is enabled.
@elfenpiff Thank you for your guidance! Yes, I'll probably submit a PR that provides the basic loom setup (e.g., add loom's sync types, introducing cfg, etc). Then we can add loom support incrementally for each data structures.