Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Dec 1996 15:25:15 -0600
From:      "Eric L. Hernes" <erich@lodgenet.com>
To:        "Marc G. Fournier" <scrappy@hub.org>
Cc:        "Eric L. Hernes" <erich@lodgenet.com>, hackers@FreeBSD.ORG
Subject:   Re: Multiple Buffer allocation of Shared Memory 
Message-ID:  <199612102125.PAA17784@jake.lodgenet.com>
In-Reply-To: Your message of "Tue, 10 Dec 1996 15:29:54 EST." <Pine.NEB.3.95.961210151724.374T-100000@hub.org> 

next in thread | previous in thread | raw e-mail | index | archive | help
"Marc G. Fournier" writes:
>	Okay...this makes a bit of sense (this is new to me, its got to 
>click into place first to make perfect sense *sigh*)...
>
>	So, if I where to be getting a frame of data from a remote end using
>sockets, I'd want to do something like:
>
>	get size of frame
>	open named file
>	ftruncate() named file to size of frame
>	mmap named file
>	write frame to mmap'd region
>
>
>	Does that make sense?
>
>	Now, "child" processes accessing that MMAP'd area...Terry (I believe?)

Again it depends on the application... If you've got a parent that gets
data, and a child that processes it, you can `share' memory with just
a fork and no exec.  The instant after the fork, both process are sharing
all of the memory, except for one page that has the fork return value,
and the proc/user structures.  The problem here is that the neither process
can share modifications, they can only read it.  Any modifications by
one process will not be seen by the other (copy on write).  To get
around this, you can mmap an anonymous region that is *not* associated
with a file at all (with MAP_ANON and -1 for the file descriptor), and
you can arrange to have the mapping preserved across exec (with
MAP_INHERIT).  For this example, mmap is like an extended malloc:

  someptr=mmap(0, sizeof_frame, PROT_READ|PROT_WRITE,
               MAP_ANON|MAP_INHERIT|MAP_SHARED, -1, 0);
  read(socket, someptr, sizeof_frame);

  if (pid=fork()) {
     ...parent stuff...
  } else {
    ... exec someother prog that will know what to do with the data
        that is at someptr, which is still a valid address ...
  }

you can even ask mmap() to use absolute address for the mapping, such
that your well known filenames are now well known addresses, providing
that they don't conflict with other regions of text/data/stack/bss.
Someone, Ron Minnich (?) posted a set of library routines that provided
a malloc using mmap instead of brk/sbrk, they should be in the archives
if they're still around.

>mentioned passing the file descriptor through a socket from the parent to
>the child, which, to me, sounds okay if you have few children reading the 
>mmap()'d region...but what I'm working on is going to require 1000's of
>child processes reading that mmap()'d region, and having 1 socket open for
>each child doesn't sound very efficient.
>

The correct answer for everything is `it depends' ;-)
If you can arrange for the parent to open the file before fork'ing, the
children will inherit it, but if you can do that, you can also mmap
with MAP_SHARED before forking and the child will automatically get the
shared memory with no added effort.  *But* if you have a child that
needs access to a memory segment that the parent doesn't allocate until
after the fork, you'll need something like Terry's fd passing trick, or
the well known file trick in order to get the memory.

>	You mention a named file in your example, so each frame could be
>called '001', '002'...'999', with the child processes accessing them 
sequentially, as they exist...but at that point, I may as well just write
>the date to 001, and have the child process open, read, close...
>

In theory yes, but mmap is much faster than open/read/close, for one
reason, there's fewer system calls. For another, the work of mmap
is done through the VM system, which may or may not read the information
from disk, although in theory the buffer cache should prevent the read()
from going to disk too.

>	I think what I'm still missing is that the way mmap() is being
>described is that it requires a file to work off of, and all that the
>benefit is is that each child can share the data from the same memory
>region...what I'm *trying* to accomplish is a completely "in memory"
>solution, without using something like MFS to get off of the physical 
>device.

See above.  In BSD, and in Unix in general, you've always got the
disk involved, whether implicitly as backing store for malloc/mmap or
explicitly as in open/read/write/close.  If you buy that, then even though
mmap may seem like it uses a file, it doesn't anymore than any other
memory operation.

>
>Marc G. Fournier                                 scrappy@hub.org
>Systems Administrator @ hub.org              scrappy@freebsd.org
>

eric.
-- 
erich@lodgenet.com
http://rrnet.com/~erich erich@rrnet.com






Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199612102125.PAA17784>