From: Andrew Gabriel on
In article <2e0b3ec1-481b-4c6a-bc71-747d6561ec34(a)j35g2000yqm.googlegroups.com>,
Shane <gshanemiller(a)verizon.net> writes:
> Hi,
>
> I have 3 different tasks from different source code which manipulate
> the same shared memory. Is there is a reasonable way to make each
> process map this shared memory into the same address inside each task?

Well, first off, you shouldn't design shared memory apps such that
they assume the shared memory is at the same virtual address (unless
they are forking from each other after attaching the memory).

However, lots of people get this wrong, and end up in a situation
where they have completely different processes sharing memory, and
riddled throughout the implementation is an irrepairable assumption
that the shared memory addresses are all the same.

At this point, there are some workarounds and you can probably make
it work, but bare in mind the implementation is broken, and any
workaround you use may need to be revisited if you patch, upgrade,
move to a different system, or change any of the processes.

Best method I've used: Find a big hole in the process's virtual
memory, and then allocate/attach the shared memory at the end of it.
You can find a hole by doing an mmap, PROT_NONE, MAP_NORESERVE, and
see what address it gives you back. The mmap size to allocate needs
to be bigger than the shared memory, plus the difference in executable
and library size between the smallest and largest of the processes.
As there's no resource consumed by this, you can make it huge, as
long as it's not so big the system can't find a virtual memory hole.
Then mummap it, and attach the shared memory at the end of the virtual
memory hole which was found. Now, the other processes will be able to
load up additional libraries, but will probably keep clear of the
address found by the first process which attached.

Second method is to make the attach address configurable. However,
that will require manual intervention and some knowledge of process
memory maps in order to set it up on each system.

Actually a combination of the first auto-location method, which can
be overriden by manual configuration, probably covers most bases,
and this is what I did.

As to how to communicate the shared memory address - the first
process to attach could write it to somewhere in the shared memory,
and then the other processes attach, read the address, detach and
reattach at the right address.

--
Andrew Gabriel
[email address is not usable -- followup in the newsgroup]
From: Andrew Gabriel on
In article <ca8c3cad-ac2e-4319-92aa-03228f194173(a)k19g2000yqm.googlegroups.com>,
Shane <gshanemiller(a)verizon.net> writes:
> Mr. Gabriel, I did not quite understand you're reply probably because
> I don't have right background. To be concrete suppose task A runs
> first and does,
> taskA:
> - key = ftok("/tmp/file1", 'R');
> - shmid = shmget(key, 1024, 0644 | IPC_CREAT);
> - data = shmat(shmid, (void *)0, 0);
> question 1 of 2: assuming task B, C know the key from task A, can they
> then do this:
> - data = shmat(shmid, (void *)0, 0); // attach to pre-allocated
> shared memory albeit tasks A,B,C
> // all have
> different values for data
> question 2 of 2: how might the shmat() call be changed for tasks B,C
> so that all tasks A,B,C
> all have the same value inside the pointer data.
> this way simple pointers into that shared memory can be passed and
> deferenced safely between
> A,B,C

Given you haven't written this yet, change the design to pass offsets
from the beginning of the shared data instead. Then it doesn't matter
that the shared memory addresses are different. Another option is to
define a struct for the shared data. I don't know enough about the
nature of the data it will hold to make more concrete suggestions.

--
Andrew Gabriel
[email address is not usable -- followup in the newsgroup]