Re: Call a Function in Shared Memory?

From: Frank Cusack (fcusack_at_fcusack.com)
Date: 09/27/04


Date: Sun, 26 Sep 2004 15:51:01 -0700

On 26 Sep 2004 08:08:32 -0700 Paul Pluzhnikov <ppluzhnikov-nsp@charter.net> wrote:
> Frank Cusack <fcusack@fcusack.com> writes:
>
>> On Sun, 26 Sep 2004 04:30:38 -0400 Michael B Allen <mba2000@ioplex.com> wrote:
>> > Can a function be placed in shared memory such that two otherwise
>> > unrelated processes can call it?
>>
>> Sure. The dynamic linker in all modern unices does this.
>
> No dynamic linker I know of places anything in (SysV or POSIX)
> shared memory.

The OP didn't say SYSV shared memory. It appears he simply wants all
these processes to not duplicate the RAM usage. Clearly he did mean
SYSV shared mem, but given the problem (eg he didn't say anything
about self-modifying code) I'm simply answering the question
literally. (Because SYSV shared mem isn't required for this problem
as stated. And also I did mention copying the function into SYSV
shared mem.)

>> Maybe you could simply link your app against a shared lib containing
>> the shared function. [...]
>
> That would generally *not* work. Consider:
...
> Even if both processes link against libshared.so, there is no reason
> to expect that the address of print_simple will be the same in both
> (unless the processes are fork()ed from one another, or are running
> the same executable).

Right, that's why I explicitly said:

On Sun, 26 Sep 2004 03:09:32 -0700 Frank Cusack <fcusack@fcusack.com> wrote:
> perhaps not the same address. Maybe there's a way you can influence
> that.

I wouldn't have mentioned this if it wasn't clear that this was a problem.
And it is really a hint ... you can influence this (perhaps not 100%
reliably but also perhaps reliably enough for a given environment).

> And if it isn't, process2 will likely crash on the call to map1->print().

Easily handled. The fn pointers could be pointers-to-pointers in
process local address space. Then you need only ensure that the local
pointed-to address space is the same for every process; mmap() can
guarantee this. You load the shared lib, which is at a different
address for each process but because of the extra indirection it
works. (I hope you can decipher that! And that it makes sense.
You'd call *map1->print().)

This basically accomplishes what the OP wants, given that he didn't
mention updating the shared function, etc. I'm assuming the same
function for every element in the data structure as well, otherwise
it's a lot of work.

On 26 Sep 2004 10:37:48 -0700 Paul Pluzhnikov <ppluzhnikov-nsp@charter.net> wrote:
> Barry Margolin <barmar@alum.mit.edu> writes:
>
>> > No dynamic linker I know of places anything in (SysV or POSIX)
>> > shared memory.
>>
>> It mmaps the shared library file [...]
>
> Indeed, but it mmap()s it with MAP_PRIVATE, *not* MAP_SHARED,
> as can be seen in strace/truss output:
>
> open("/lib/libc.so.6", O_RDONLY) = 3
> read(3, "\177ELF [...]
> old_mmap(NULL, 1201988, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40034000
> old_mmap(0x4014f000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x11a000) = 0x4014f000
> old_mmap(0x40156000, 14148, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40156000
> close(3) = 0
>
> It (almost) might as well malloc() that memory.

??? mmap as above is simply an address space mapping.

> The physical RAM pages are shared, but this is not at all what
> people call "shared memory", and not what OP is asking about.
>
> In particular, modifications to these pages (as in
> e.g. self-modifying code), will not be seen by other processes.

For read-only it's the same. Global vars, even read-only ones, mess
this up also (both for SYSV shared mem and my shared lib suggestion).

/fc



Relevant Pages