On 04/28/2016 10:50 AM, Barry Spinney wrote:
Inter-process dynamic shared memory support.
This API provides a convenient method for multiple processes to share memory
using a persistent filesystem-based arena that is automatically mapped at the
same, fixed address in all processes sharing the arena. The application chooses
an address for the arena to be located at and a maximum size to which it can
grow, and the system manages coordinating access to memory mapped from the file
among the processes. Since the address is fixed, absolute pointer values, etc.,
may be safely stored into the arena.
The files are opened such that they are automatically closed if the process
calls exec() to start a new executable.
Thanks for copying me on this subject. As Christophe had mentioned in
an earlier email, in order to achieve pointer coherency across process
boundaries, the 'client' processes must be forked from the process which
does the initial allocation in order to inherit a copy of the initial
allocator's address map and then must avoid invalidating that address
map via any form of exec*() call. While this is a similar scenario to
that employed with the use of pthreads, I personally feel this is an
undesirable direction to take within ODP itself. It might make a good
addition to a helper suite.
As I understand it the primary reason for ODP is to promote application
portability and reuse. To my thinking this means ODP proper should make
no assumptions of address space layout across ODP threads.
While POSIX compliant systems may support these assumptions, there may
be other platforms which do not. Indeed there may be platforms in which
the combination of underlying hardware and OS do not support shared
memory at all. Therefore I regard it as a non-portable design if the
application assumes pointer validity across threads of execution which
may or may not have overlapping or even compatible address spaces. If
this is bad practice at the application level where the designer may
deliberately eschew portability in favor of performance, it is most
certainly bad practice to embed such assumptions in an underlying
foundational library.
Furthermore, I believe that when implementing a foundational library it
is extremely important to ensure that the library behaves consistently
with best practices in the rest of the platform environment. As a
general rule POSIX systems make no guarantees of pointer coherency
across process boundaries - so I do not favor a design which assumes
some pointers can be shared safely while others can not. I believe this
invites confusion and maintenance nightmares for the application designer.
In contrast, if the reference platform implementation of ODP shared
memory makes no assumptions about the address space layout of one ODP
thread versus another, it encourages application design which is
consistent with typical POSIX practice and available documentation. This
makes the library more intuitive to use and less prone to
misunderstanding and erroneous usage. I realize this might require
rethinking of some existing code, but I believe this will result in a
more robust and portable reference platform which will better serve as
an example for best implementation practices.
If my opinion regarding the importance of portability versus performance
is not shared then I question why the reference implementation should
bother to support process-based ODP threads at all.
The main reasons for using processes instead of pthreads include address
space isolation (or reconfiguration in a NUMA environment, for example)
or the lack of support for pthreads.
Address space reconfiguration invalidates pointer coherency across
processes, and obviously Linux has pthread support - so what would be
the use case for process-based ODP threads if they have to have pointer
coherency among themselves?
If process-based ODP threads are important then I believe for the sake
of consistency they should regard all pointers and memory map
configurations as thread-specific and not shareable. Any ODP data
constructs expected to be shared or inherited across ODP threads should
comply with this restriction regardless of whether the underlying
threads are implemented as processes or pthreads.
By the time odp_init_global() and odp_init_local() have completed
execution, there should be no differences in the ODP environment
inherited by processes as opposed to pthreads. Any shared data should
be resolved to process-local pointers. In the case of pthread-based ODP
threads executing with a data address map shared with the parent
process, this is a wash... in the case of shared memory objects pointers
might be resolved to local addresses the first time a descendant thread
needs to access a given shmem object. This could work the same way
whether the descendant ODP thread was a forked process with its own
address space or a cloned pthread sharing the address space of its
parent process. This approach also lends itself more readily to
file-based data sharing on platforms which lack memory-mapped file or
shared memory support.
With that I'll close this novel-length diatribe and wait for the flames
:-) If you stuck with it for this long, thanks for devoting so much
attention.
Gary Robertson
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp