eclipse-iceoryx / eclipse-iceoryx/iceoryx
Map segments by name instead of access permissions, and allow publishers write access to multiple
- Dominant language
- C++
- Stars
- 2.2k
- Forks
- 492
- Avg merge
- 18h 57m
- Merged PRs (30d)
- 1
Description
## Brief feature description
Shared memory segments are currently mapped strictly by access controls. It would be beneficial to map instead by name or some other key so that processes aren't limited to writing to a single segment and we could better split up communication channels across multiple segments.
## Detailed information
Currently, it is possible to creating multiple shared memory segments with different access permissions, as described in the [configuration guide](https://github.com/eclipse-iceoryx/iceoryx/blob/master/doc/website/advanced/configuration-guide.md).
However, not only do the segments allow one to specify access controls, but they create really strong couplings based on those access controls. The implications include:
- The name of shared memory segments is automatically deduced as the name of the cgroup that has write access to it
- The above means that there can only be one segment that any given cgroup has write access to
- Publishers are allowed write access to only one segment, which is deduced as the segment that matches the cgroup of the process the publisher is contained in.
- It is therefore not possible to have a single publisher access multiple segments (This makes sense - it would be strange to do so).
- It is also not possible to have multiple publishers in the same process which access different segments
The last point is of particular interest to me because I can consider a couple notable reasons why one would want to be able to create many shared memory segments and be able to access them from within the same process:
- Splitting communication channels across separate shared memory segments ensures better [Freedom From Interference](https://heicon-ulm.de/en/iso26262-freedom-from-interference-what-is-that/) because should a bad publisher or subscriber access data past the end of a memory pool, it will usually result in a segfault rather than simply a corrupted read/write of another memory pool.
- We may wish to make use of the [MemoryInfo member of a segment config](https://github.com/eclipse-iceoryx/iceoryx/blob/6303f2ea7ec18381943e1f3edb150b7dae908fe1/iceoryx_posh/include/iceoryx_posh/mepoo/segment_config.hpp#L37) (currently just defaulted) to differentiate segments based on memory type. This would allow a simpler, cleaner solution to the issue described in #2092 because we could specify that a segment is intended to support `CUDA_PINNED_HOST` memory, and then each publisher / subscriber that needs access to such memory would identify that segment and pin the memory of only that segment.
**Possible Obstacles**
I've found a [curious comment in the code](https://github.com/eclipse-iceoryx/iceoryx/blob/master/iceoryx_posh/include/iceoryx_posh/internal/mepoo/segment_manager.inl#L66):
> a user is allowed to be only in one writer group, as we currently only support one memory manager per process
I have not dug around enough in the code to understand why only one memory manager can be supported per process and what it might take to support more. I'd appreciate more context on this statement if anyone knows more.
From my perhaps naive standpoint - I would expect that the proper restriction be that we only have one memory manager **per publisher**, but that within the same process we may have multiple publishers writing to possibly different segments. For example - one publisher publishing images with the help of some GPU acceleration taking advantage of the pinned host memory, and another publisher publishing some small metrics data that does not need pinned host memory, so it uses a different memory segment.
**Possible Implementation**
I am imagining extending the Roudi config so that it could conceivably look like
```
[general]
version = 2
[[segment]]
name = "foobar"
writer = "foo"
reader = "bar"
memoryType = 0
[[segment.mempool]]
size = 32
count = 10000
[[segment]]
name = "pinned_foobar"
writer = "foo"
reader = "bar"
memoryType = 1
[[segment.mempool]]
size = 12000000
count = 10
```
And then when creating a publisher one can optionally specify the name of a segment:
```
BasePublisher(const capro::ServiceDescription& service, const PublisherOptions& publisherOptions, optional shmSegmentName = {});
```
such that the name will be used directly to map the shared memory region rather than the access group of current process, as [is currently done](https://github.com/eclipse-iceoryx/iceoryx/blob/master/iceoryx_posh/include/iceoryx_posh/internal/mepoo/segment_manager.inl#L112).
For backwards compatibility then, we could simply make the name default to user of the current process.
Contributor guide
Assessment
This issue has not been assessed yet.