fork(), mmap_device_memory() and shm_ctl()

We have one program that does mmap one segment memory and then
mmap another physically contiguous memory with
mmap(), mmap_device_memory, shm_ctl().


Then we fork a child process, what we found is the mmap() memory
segements and exist in the child process, but the attempt to access the
physically contiguous memory from mmap_device_memory() would
fail.

Any one from QNX have any explaination?

\

-Tony Lee

A mmap() is not valid across a fork(). Well I guess it is perfectly valid
but it doesn’t do what you think it does.

mmap() creates a COPY of all memory. It does not create a copy of the
pointer to commonly mapped memory. I.E. you child process has a copy of the
commonly mapped memory as of the time of the fork() but no longer refers to
the same physical memory.

I.E. First do your fork(), then map in your memory.

“Tony Lee” <Tony.p.lee@nokia.com> wrote in message
news:abroob$kq3$1@inn.qnx.com

We have one program that does mmap one segment memory and then
mmap another physically contiguous memory with
mmap(), mmap_device_memory, shm_ctl().


Then we fork a child process, what we found is the mmap() memory
segements and exist in the child process, but the attempt to access the
physically contiguous memory from mmap_device_memory() would
fail.

Any one from QNX have any explaination?

\

-Tony Lee

I don’t think so. Doing mmap(MAP_ANON|MAP_SHARED) before fork() is perfectly
legal and is actualy the very reason to even have MAP_ANON|MAP_SHARED combo
(or it would not be usable). Apache works that way, FYI. It is
responsibility of process/memory manager to figure out which pages are
private and which are shared and handle creation of child process
accordingly. For all I know, QNX supports this.

Furthermore, on Unix systems fork() actually does NOT copy memory at all,
until it is attempted to be written into by either child or parent (this is
called Copy-On-Write). QNX does not support this feature.

– igor

“Bill Caroselli (Q-TPS)” <QTPS@EarthLink.net> wrote in message
news:abs1m4$r2d$1@inn.qnx.com

A mmap() is not valid across a fork(). Well I guess it is perfectly valid
but it doesn’t do what you think it does.

mmap() creates a COPY of all memory. It does not create a copy of the
pointer to commonly mapped memory. I.E. you child process has a copy of
the
commonly mapped memory as of the time of the fork() but no longer refers
to
the same physical memory.

I.E. First do your fork(), then map in your memory.

“Tony Lee” <> Tony.p.lee@nokia.com> > wrote in message
news:abroob$kq3$> 1@inn.qnx.com> …
We have one program that does mmap one segment memory and then
mmap another physically contiguous memory with
mmap(), mmap_device_memory, shm_ctl().


Then we fork a child process, what we found is the mmap() memory
segements and exist in the child process, but the attempt to access the
physically contiguous memory from mmap_device_memory() would
fail.

Any one from QNX have any explaination?

\

-Tony Lee

\

“Igor Kovalenko” <Igor.Kovalenko@motorola.com> wrote in message
news:absau0$3qf$1@inn.qnx.com

I don’t think so. Doing mmap(MAP_ANON|MAP_SHARED) before fork() is
perfectly
legal and is actualy the very reason to even have MAP_ANON|MAP_SHARED
combo
(or it would not be usable). Apache works that way, FYI. It is
responsibility of process/memory manager to figure out which pages are
private and which are shared and handle creation of child process
accordingly. For all I know, QNX supports this.

Furthermore, on Unix systems fork() actually does NOT copy memory at all,
until it is attempted to be written into by either child or parent (this
is
called Copy-On-Write). QNX does not support this feature.

We’re really careful not to support features that introduce all sorts of
non-determinancy into running applications. :wink:

– igor

“Bill Caroselli (Q-TPS)” <> QTPS@EarthLink.net> > wrote in message
news:abs1m4$r2d$> 1@inn.qnx.com> …
A mmap() is not valid across a fork(). Well I guess it is perfectly
valid
but it doesn’t do what you think it does.

mmap() creates a COPY of all memory. It does not create a copy of the
pointer to commonly mapped memory. I.E. you child process has a copy of
the
commonly mapped memory as of the time of the fork() but no longer refers
to
the same physical memory.

I.E. First do your fork(), then map in your memory.

“Tony Lee” <> Tony.p.lee@nokia.com> > wrote in message
news:abroob$kq3$> 1@inn.qnx.com> …
We have one program that does mmap one segment memory and then
mmap another physically contiguous memory with
mmap(), mmap_device_memory, shm_ctl().


Then we fork a child process, what we found is the mmap() memory
segements and exist in the child process, but the attempt to access
the
physically contiguous memory from mmap_device_memory() would
fail.

Any one from QNX have any explaination?

\

-Tony Lee



\

Tony Lee <Tony.p.lee@nokia.com> wrote:

We have one program that does mmap one segment memory and then
mmap another physically contiguous memory with
mmap(), mmap_device_memory, shm_ctl().



Then we fork a child process, what we found is the mmap() memory
segements and exist in the child process, but the attempt to access the
physically contiguous memory from mmap_device_memory() would
fail.

Any one from QNX have any explaination?

I’d like to see more details. The behaviour of all of the functions
you list can vary GREATLY depending on the various flags passed in.

The exact sequence of calls, with all the various flags and parameters
filled in, and exactly what fails, and how it fails, would be better.

A small sample program that demonstrates the problem, would be best.

Thanks,
-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

“Kris Warkentin” <kewarken@qnx.com> wrote in message
news:abtjkv$ccb$1@nntp.qnx.com

“Igor Kovalenko” <> Igor.Kovalenko@motorola.com> > wrote in message
news:absau0$3qf$> 1@inn.qnx.com> …
I don’t think so. Doing mmap(MAP_ANON|MAP_SHARED) before fork() is
perfectly
legal and is actualy the very reason to even have MAP_ANON|MAP_SHARED
combo
(or it would not be usable). Apache works that way, FYI. It is
responsibility of process/memory manager to figure out which pages are
private and which are shared and handle creation of child process
accordingly. For all I know, QNX supports this.

Furthermore, on Unix systems fork() actually does NOT copy memory at
all,
until it is attempted to be written into by either child or parent (this
is
called Copy-On-Write). QNX does not support this feature.

We’re really careful not to support features that introduce all sorts of
non-determinancy into running applications. > :wink:

That’s a nice face-saving way to say ‘our VM subsystem sucks’ :stuck_out_tongue:

You’re not forgetting that application doing fork() is also RUNNING, are
you? If you support COW, then you have ‘best case’ (no pages modified) and
‘worst case’ (all pages modified, which must be bloody rare) scenarios. If
you do not support it then you always have ‘worst case’. One might call that
‘determinism’, like in ‘deterministically poor performance’.

– igor

Previously, Kris Warkentin wrote in qdn.public.qnxrtp.os:

Furthermore, on Unix systems fork() actually does NOT copy memory at all,
until it is attempted to be written into by either child or parent (this
is
called Copy-On-Write). QNX does not support this feature.

We’re really careful not to support features that introduce all sorts of
non-determinancy into running applications. > :wink:

Wow, not only would this cause non-determinacy, it would also could
cause inconsistent results between different systems. What if one
process changes memory values after the fork, but before the Copy-on-write
occurs?

Mitchell Schoenbrun --------- maschoen@pobox.com

Previously, Igor Kovalenko wrote in qdn.public.qnxrtp.os:

You’re not forgetting that application doing fork() is also RUNNING, are
you? If you support COW, then you have ‘best case’ (no pages modified) and
‘worst case’ (all pages modified, which must be bloody rare) scenarios. If
you do not support it then you always have ‘worst case’. One might call that
‘determinism’, like in ‘deterministically poor performance’.

As a practical matter, don’t you think that fork’s usually occur as part
of startup, a period when most processes are not expected to provided
extremely short latencies, whereas after the fork occurs, a programmer
might be surpised that a single variable access would cause an entire
page of data to be moved?





Mitchell Schoenbrun --------- maschoen@pobox.com

“Igor Kovalenko” <Igor.Kovalenko@motorola.com> wrote in message
news:abush7$2ou$1@inn.qnx.com

“Kris Warkentin” <> kewarken@qnx.com> > wrote in message
news:abtjkv$ccb$> 1@nntp.qnx.com> …

We’re really careful not to support features that introduce all sorts of
non-determinancy into running applications. > :wink:

That’s a nice face-saving way to say ‘our VM subsystem sucks’ :stuck_out_tongue:

You’re not forgetting that application doing fork() is also RUNNING, are
you? If you support COW, then you have ‘best case’ (no pages modified) and
‘worst case’ (all pages modified, which must be bloody rare) scenarios. If
you do not support it then you always have ‘worst case’. One might call
that
‘determinism’, like in ‘deterministically poor performance’.

Yes, but the instant of long latency is at a very specific time, the time of

the fork(). And most of my programs that use fork() do their fork() when
they are first initializing and before they start handling client requests
anyway. Determinism is not as important during initialization.

“Mitchell Schoenbrun” <maschoen@pobox.com> wrote in message
news:Voyager.020515175316.20829C@node1…

Previously, Kris Warkentin wrote in qdn.public.qnxrtp.os:

We’re really careful not to support features that introduce all sorts of
non-determinancy into running applications. > :wink:

Wow, not only would this cause non-determinacy, it would also could
cause inconsistent results between different systems. What if one
process changes memory values after the fork, but before the Copy-on-write
occurs?

I believe that the kernel forces the Copy-on-write to be atomic WRT the data

change.

Kris Warkentin <kewarken@qnx.com> wrote:

“Igor Kovalenko” <> Igor.Kovalenko@motorola.com> > wrote in message
news:abush7$2ou$> 1@inn.qnx.com> …
“Kris Warkentin” <> kewarken@qnx.com> > wrote in message
news:abtjkv$ccb$> 1@nntp.qnx.com> …

“Igor Kovalenko” <> Igor.Kovalenko@motorola.com> > wrote in message
news:absau0$3qf$> 1@inn.qnx.com> …
I don’t think so. Doing mmap(MAP_ANON|MAP_SHARED) before fork() is
perfectly
legal and is actualy the very reason to even have MAP_ANON|MAP_SHARED
combo
(or it would not be usable). Apache works that way, FYI. It is
responsibility of process/memory manager to figure out which pages are
private and which are shared and handle creation of child process
accordingly. For all I know, QNX supports this.

Furthermore, on Unix systems fork() actually does NOT copy memory at
all,
until it is attempted to be written into by either child or parent
(this
is
called Copy-On-Write). QNX does not support this feature.

We’re really careful not to support features that introduce all sorts of
non-determinancy into running applications. > :wink:

That’s a nice face-saving way to say ‘our VM subsystem sucks’ :stuck_out_tongue:

You’re not forgetting that application doing fork() is also RUNNING, are
you? If you support COW, then you have ‘best case’ (no pages modified) and
‘worst case’ (all pages modified, which must be bloody rare) scenarios. If
you do not support it then you always have ‘worst case’. One might call
that
‘determinism’, like in ‘deterministically poor performance’.

I disagree. It is much easier to say ‘okay, I’m going to fork now’ at a
non-critical time in your program than to try and predict when some page
might need to be copied.

Help me out with the term “non-critical time in your program” when you are
discussing a system that may contain N processes, each of which determines
it’s own “critical” time? :slight_smile: Perhaps there’s a resource manager that
gets input from all the processes and then notifies the waiting-to-fork
process that it’s “ok now, nobody is expecting an interrupt?” :slight_smile:

Cheers,
-RK


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

“Igor Kovalenko” <Igor.Kovalenko@motorola.com> wrote in message
news:abush7$2ou$1@inn.qnx.com

“Kris Warkentin” <> kewarken@qnx.com> > wrote in message
news:abtjkv$ccb$> 1@nntp.qnx.com> …

“Igor Kovalenko” <> Igor.Kovalenko@motorola.com> > wrote in message
news:absau0$3qf$> 1@inn.qnx.com> …
I don’t think so. Doing mmap(MAP_ANON|MAP_SHARED) before fork() is
perfectly
legal and is actualy the very reason to even have MAP_ANON|MAP_SHARED
combo
(or it would not be usable). Apache works that way, FYI. It is
responsibility of process/memory manager to figure out which pages are
private and which are shared and handle creation of child process
accordingly. For all I know, QNX supports this.

Furthermore, on Unix systems fork() actually does NOT copy memory at
all,
until it is attempted to be written into by either child or parent
(this
is
called Copy-On-Write). QNX does not support this feature.

We’re really careful not to support features that introduce all sorts of
non-determinancy into running applications. > :wink:

That’s a nice face-saving way to say ‘our VM subsystem sucks’ :stuck_out_tongue:

You’re not forgetting that application doing fork() is also RUNNING, are
you? If you support COW, then you have ‘best case’ (no pages modified) and
‘worst case’ (all pages modified, which must be bloody rare) scenarios. If
you do not support it then you always have ‘worst case’. One might call
that
‘determinism’, like in ‘deterministically poor performance’.

I disagree. It is much easier to say ‘okay, I’m going to fork now’ at a
non-critical time in your program than to try and predict when some page
might need to be copied.

– igor

“Mitchell Schoenbrun” <maschoen@pobox.com> wrote in message
news:Voyager.020515175316.20829C@node1…

Previously, Kris Warkentin wrote in qdn.public.qnxrtp.os:

Furthermore, on Unix systems fork() actually does NOT copy memory at
all,
until it is attempted to be written into by either child or parent
(this
is
called Copy-On-Write). QNX does not support this feature.

We’re really careful not to support features that introduce all sorts of
non-determinancy into running applications. > :wink:

Wow, not only would this cause non-determinacy, it would also could
cause inconsistent results between different systems. What if one
process changes memory values after the fork, but before the Copy-on-write
occurs?

Exactly. There are any number of different times when you might take a hit
after the fork() with COW that would depend on a lot of different variables.
Without COW, you KNOW that you will take the hit at a certain time in your
execution an that’s it. Igor is looking for best case or average case
performance. We have to look at worst case for true real time.

This issue is exactly the same as why we don’t have lazy mapping of shared
libraries. Linux, et.al. will only run the linker when a function is first
called. That means you never really know when the linker will be taking
cycles from your app. We run the linker at startup to make sure everything
is mapped in before we start execution. You take a hit on program startup
but it’s a known hit at a known time.

Mitchell Schoenbrun --------- > maschoen@pobox.com

“Kris Warkentin” <kewarken@qnx.com> wrote in message
news:ac0t0d$1kn$1@nntp.qnx.com

“Igor Kovalenko” <> Igor.Kovalenko@motorola.com> > wrote in message
news:abush7$2ou$> 1@inn.qnx.com> …
“Kris Warkentin” <> kewarken@qnx.com> > wrote in message
news:abtjkv$ccb$> 1@nntp.qnx.com> …

“Igor Kovalenko” <> Igor.Kovalenko@motorola.com> > wrote in message
news:absau0$3qf$> 1@inn.qnx.com> …
I don’t think so. Doing mmap(MAP_ANON|MAP_SHARED) before fork() is
perfectly
legal and is actualy the very reason to even have
MAP_ANON|MAP_SHARED
combo
(or it would not be usable). Apache works that way, FYI. It is
responsibility of process/memory manager to figure out which pages
are
private and which are shared and handle creation of child process
accordingly. For all I know, QNX supports this.

Furthermore, on Unix systems fork() actually does NOT copy memory at
all,
until it is attempted to be written into by either child or parent
(this
is
called Copy-On-Write). QNX does not support this feature.

We’re really careful not to support features that introduce all sorts
of
non-determinancy into running applications. > :wink:

That’s a nice face-saving way to say ‘our VM subsystem sucks’ :stuck_out_tongue:

You’re not forgetting that application doing fork() is also RUNNING, are
you? If you support COW, then you have ‘best case’ (no pages modified)
and
‘worst case’ (all pages modified, which must be bloody rare) scenarios.
If
you do not support it then you always have ‘worst case’. One might call
that
‘determinism’, like in ‘deterministically poor performance’.

I disagree. It is much easier to say ‘okay, I’m going to fork now’ at a
non-critical time in your program than to try and predict when some page
might need to be copied.

As a followup, I might say that if you’re looking for the best performance
in the average case, you probably don’t need a realtime OS. I’ve often
thought that it would be neat to have a few performance booster be optional:
COW and lazy linking come to mind. It seems to me though that these kinds
of things are better left to OSes that need them rather than introducing new
layers of complexity. For realtime, deterministic execution, we don’t need
them.

– igor

\

“Robert Krten” <nospam88@parse.com> wrote in message
news:ac0teo$ij8$1@inn.qnx.com

I disagree. It is much easier to say ‘okay, I’m going to fork now’ at a
non-critical time in your program than to try and predict when some page
might need to be copied.

Help me out with the term “non-critical time in your program” when you are
discussing a system that may contain N processes, each of which determines
it’s own “critical” time? > :slight_smile: > Perhaps there’s a resource manager that
gets input from all the processes and then notifies the waiting-to-fork
process that it’s “ok now, nobody is expecting an interrupt?” > :slight_smile:

I consider system initialization to be non-critical. During power up it

just takes so long for the system to become ready to do it’s thing. But
once it’s up it should stay up (and deterministic).

“Robert Krten” <nospam88@parse.com> wrote in message
news:ac0teo$ij8$1@inn.qnx.com

Kris Warkentin <> kewarken@qnx.com> > wrote:
I disagree. It is much easier to say ‘okay, I’m going to fork now’ at a
non-critical time in your program than to try and predict when some page
might need to be copied.

Help me out with the term “non-critical time in your program” when you are
discussing a system that may contain N processes, each of which determines
it’s own “critical” time? > :slight_smile: > Perhaps there’s a resource manager that
gets input from all the processes and then notifies the waiting-to-fork
process that it’s “ok now, nobody is expecting an interrupt?” > :slight_smile:

Like Bill, I was thinking more along the lines of system initialization.
The other way of thinking is a client-server relationship where the overhead
is in the initial connection and then servicing the client is done as
deterministically as possible. Does one really expect real time performance
with N processes? I expect not - probably real time is only important for
some of them which is what priorities are for. Either way, I still think
it’s better to definitely be able to say, ‘this performance hit will happen
now’ rather than ‘performance hits will happen at random times some time
after this event’. If it were an option in the VM system then one could
choose whether or not to amortize the costs. I don’t know how feasible
those kind of options are to implement though. We do have a fairly
configurable scheduler though…

Kris

Disclaimer: I’m a junior tools developer so anything I tell you is
‘booklarnin’ and hearsay’. I expect to be ‘educated’ (smacked?) in most of
these discussions.

Cheers,
-RK


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at > www.parse.com> .
Email my initials at parse dot com.

Kris Warkentin wrote:

it’s better to definitely be able to say, ‘this performance hit will happen
now’ rather than ‘performance hits will happen at random times some time
after this event’.

That’s what determinism is, after all. Nobody ever said real-time
systems don’t experience “performance hits”, only that their temporal
locale and magnitude are predictable.

Rennie

“Bill Caroselli (Q-TPS)” <QTPS@EarthLink.net> wrote in message
news:ac0lkj$d57$1@inn.qnx.com

“Mitchell Schoenbrun” <> maschoen@pobox.com> > wrote in message
news:Voyager.020515175316.20829C@node1…
Previously, Kris Warkentin wrote in qdn.public.qnxrtp.os:

We’re really careful not to support features that introduce all sorts
of
non-determinancy into running applications. > :wink:

Wow, not only would this cause non-determinacy, it would also could
cause inconsistent results between different systems. What if one
process changes memory values after the fork, but before the
Copy-on-write
occurs?

I believe that the kernel forces the Copy-on-write to be atomic WRT the
data
change.

Yes. We were talking about non-determinancy, not indeterminancy. The first
one is okay if time isn’t critical. The second one is never okay (except
maybe in random number generators :wink:

Kris

“Rennie Allen” <rallen@csical.com> wrote in message
news:3CE4BD98.7000605@csical.com

Kris Warkentin wrote:

it’s better to definitely be able to say, ‘this performance hit will
happen
now’ rather than ‘performance hits will happen at random times some time
after this event’.

That’s what determinism is, after all. Nobody ever said real-time
systems don’t experience “performance hits”, only that their temporal
locale and magnitude are predictable.

Yeah…sooner or later, we have to use some CPU cycles. If we could just
get rid of all those pesky processes we’d be able to get real time operation
for sure. :wink:

In all seriousness though, optimization for average or best case performance
plus amortization of performance hits plus adaptive scheduling is what makes
for a very responsive (to the user) desktop or server. This is why you’ll
generally see Windows, Linux, BSD, Solaris outperform RTOSes on similar
hardware. We’re not about appearances though…we’re about guarantees. :wink:

Kris

Rennie

Igor.Kovalenko@motorola.com wrote in <abush7$2ou$1@inn.qnx.com>:

until it is attempted to be written into by either child or parent (this
is
called Copy-On-Write). QNX does not support this feature.
We’re really careful not to support features that introduce all sorts of
non-determinancy into running applications. > :wink:
That’s a nice face-saving way to say ‘our VM subsystem sucks’ :stuck_out_tongue:

I thought fork() was alien in QNX; the native syscall seems to be spawn()
which directly spawns away other executable.
(fork->exec sequence should look weird besides UNIX advocates)


kabe