[comp.sys.amiga] Ami - MINIX problem for gurus

JPARR@UREGINA1.BITNET.UUCP (11/18/87)

Hi all:

     I ran across a technical difficulty when trying to port MINIX to the
Amiga.  How the heck can you do a fork?
     The problem is this.  When a process is first loaded in from disk, it
is nicely relocateable up until the time it runs.  Once it runs, however,
any pointers that it uses will be absolute addresses.  When copying the
parent over to the child, all pointers will still point to the parents
data area.  Amiga DOS must run up against similar problems, what does it do?
     Right now I can think of only two solutions.  The first is to have a
"running" area in memory.  Then whenever a process was scheduled, its image
would have to be copied into this area.  When finished, it would be recopied
back to its own area.  Obviously, this is not the best solution, although
it would work.  (maybe?)
     The second solution would be to remove the ability to fork altogether
and have a single fork_exec call to spawn new processes.  As soon as I do
this, MINIX is no longer very much like MINIX, so this isn't really too
ideal either.  Suggestions?
     (I guess that this means we will have to conceed that Intel did something
right . . . .)

Thanx,
JP

fish%calypso@Sun.COM (Lorenz Fish) (11/18/87)

I am posting the following for Doug Merritt (ucbvax!unisoft!certes!doug).
Reply to me and I will forward your message to him:

In article <8711180347.AA10717@jade.berkeley.edu> JPARR@UREGINA1.BITNET (John Parr) writes:
>     I ran across a technical difficulty when trying to port MINIX to the
>Amiga.  How the heck can you do a fork?
> [...] Right now I can think of only two solutions.  The first is to have a
>"running" area in memory.  Then whenever a process was scheduled, its image
>would have to be copied into this area.  When finished, it would be recopied
>back to its own area. Obviously, this is not the best solution, although [...]

This is in fact the best solution, given the lack of an MMU on the Amiga.
It is, unfortunately, somewhat slow, but you can't do any better and still
support fork(). And supporting fork() is absolutely essential to a port
of MINIX.

Andy Tanenbaum (author of Minix) confirmed that this was the best solution
for MMU-less machines like the ST and the Amiga earlier this year in
a conversation following a talk he gave at Computer Literacy. And it is
the one being used in the ST port of Minix.

Note, however, that this slow swapping of process images can cease as
soon as the forked() process does an exec(). And UNIX/MINIX programs almost
always do an exec() soon after being forked(). Thus the perceptible slowdown
will be minimal for 99% of what the user will run.

The discussion above assumes minor modifications to your suggested algorithm,
mainly giving all exec()'ed processes their own memory area, and having
one shared memory area per set of identical (forked) processes.

An amusing side benefit to *always* swapping (to fast ram) is that your MINIX
programs could now have "virtual" chip ram...i.e. each process would have the
entire 512K (less overhead) to itself. On the other hand, you couldn't expect
any real time performance from more than one of these programs at a time.
Functions like animation and sound probably wouldn't get along with swapping
very well. Might be handy for switching from one inactive task to another,
though (like on the MacIntosh :-) The times when you'd get something useful
from this are minimal, actually...maybe if you had a zillion very small
processes that wouldn't all fit in chip at once, but were small enough to
swap from fast to chip ram quickly. But I digress...

A potential optimization would be to swap only the data areas of the process,
since the text (instruction) areas will presumably remain identical (never
mind self modifying code). Unfortunately it may be difficult or even
impossible to reliably differentiate between text and data in the original
object file...Amiga compilers (et al) do not guarantee keeping them separate,
but perhaps you could fix this for the Minix software. Unclear whether it's
worth the trouble. Might be no trouble at all if you're going to use a
native Minix compiler/linker.

>     (I guess that this means we will have to conceed that Intel did something
>right . . . .)

Not at all. Even though I don't know what you are referring to, it is
well known that Intel never does anything right. :-) :-) :-)

	Doug Merritt		ucbvax!unisoft!certes!doug

		 o   	Lorenz Fish	{ucbvax}!sun!fish@calypso
		 o
		 o @^_ 
		  <_~_>{
		    V

				Sun Microsystems	Mountain View, CA

		|||   disclaimer:  The company would never say THAT!   |||

wolf@ssyx.UUCP (11/19/87)

In article <8711180347.AA10717@jade.berkeley.edu> JPARR@UREGINA1.BITNET (John Parr) writes:
>Once it runs, however,
>any pointers that it uses will be absolute addresses.  When copying the
>parent over to the child, all pointers will still point to the parents
>data area.
[stuff deleted]
>     (I guess that this means we will have to conceed that Intel did something
>right . . . .)

No it doesn't.  The Intel chips force you to address off a segment
pointer, which the 68000 doesn't.  You could, however, write a 68000
compiler which uses one register for a data segment pointer and reference
all data off the register.  The 68000 just gives you the choice.  If amiga
OS had been designed with that sort of thing in mind, then all programs
would be relocatable during runtime.  (note, this isn't a flame)  Personally,
I'll stick with the chip I'm using now.  (though a 68030 would be nice)

>Thanx,
>JP

	-- Mike Wolf

+------------------------------------+---------------------------------------+
|        Michael Wolf                | An old Scandinavian quote:            |
|  BITNET: wolf@ucscj.BITNET         |   "You can lead a herring to water,   |
|  ARPA:   wolf@ssyx.ucsc.edu        |    but you have to walk real fast,    |
|  UUCP: ...ucbvax!ucscc!ssyx!wolf   |    or else he'll die."                |
+------------------------------------+---------------------------------------+

ewhac@well.UUCP (11/19/87)

In article <8711180347.AA10717@jade.berkeley.edu> JPARR@UREGINA1.BITNET (John Parr) writes:
>     I ran across a technical difficulty when trying to port MINIX to the
>Amiga.  How the heck can you do a fork?

	You don't.

>     The problem is this.  When a process is first loaded in from disk, it
>is nicely relocateable up until the time it runs.  Once it runs, however,
>any pointers that it uses will be absolute addresses.  When copying the
>parent over to the child, all pointers will still point to the parents
>data area.  Amiga DOS must run up against similar problems, what does it do?

	It avoids it.  It never forks.  It merely loads a new copy of the
program in question and runs it.

>     Right now I can think of only two solutions.  The first is to have a
>"running" area in memory.  Then whenever a process was scheduled, its image
>would have to be copied into this area.  When finished, it would be recopied
>back to its own area.  Obviously, this is not the best solution, although
>it would work.  (maybe?)

	Congratulations.  You've just decribed Dual's first-generation UNIX
memory management scheme on the 68000 before MMU's existed.  It worked
great, but was.............s...............l...........o..........w.......

>     The second solution would be to remove the ability to fork altogether
>and have a single fork_exec call to spawn new processes.  As soon as I do
>this, MINIX is no longer very much like MINIX, so this isn't really too
>ideal either.  Suggestions?

	You have two choices:  One is to remember where the program came
from off mass storage, and when the user fork()s, you merely load in a new
copy of the program and run it.  Not elegant.

	The other is to impose a rule whereby no program is permitted to
store data or modify its code segment while running.  Then, when initially
loading the program, you seperate the data and code segments.  At startup, you
make a copy of the data segment, and point the program at the copy.  When
the program fork()s, you use the same copy of the code (shared text?), make
a new copy of the data segment, and point the fork()ed process at the fresh
data copy.  More elegant, but subject to pitfalls.

	Dunno how well either of these would work.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape	ihnp4!ptsfa -\
 \_ -_		Recumbent Bikes:	      dual ---> !{well,unicom}!ewhac
O----^o	      The Only Way To Fly.	      hplabs / (pronounced "AE-wack")
"Work FOR?  I don't work FOR anybody!  I'm just having fun."  -- The Doctor

ain@s.cc.purdue.edu (Patrick White) (11/19/87)

In article <8711180347.AA10717@jade.berkeley.edu> JPARR@UREGINA1.BITNET (John Parr) writes:
 >Hi all:
 >     I ran across a technical difficulty when trying to port MINIX to the
 >Amiga.  How the heck can you do a fork?
 >     The problem is this.  When a process is first loaded in from disk, it
 >is nicely relocateable up until the time it runs.  Once it runs, however,
 >any pointers that it uses will be absolute addresses.  When copying the
 >parent over to the child, all pointers will still point to the parents
 >data area.  Amiga DOS must run up against similar problems, what does it do?

   Let me mix a few ideas from my IBM PC days, and see if it creates a
possible solution:
   1) if the code is reentrant, then no problem here -- this seems like a
      valid assumption since few C programs that I have seen modify the
      code itself.
   2) stack is easy too if you know where it is and all stack references
      are done via offsets from the base of the stack (not necessarily a
      valid assumption, but one I'm willing to make).
   3) one problem is the data segment.  Now, on the IBM (in one of it's
      infamous "memory models") the data is referenced relative to a
      data-segment-pointer.  I believe that the Manx compiler for the
      Amiga does something like this too (my manuals are at home so forgive
      me if I'm wrong on this).
   4) the biggest problem I can see, is the heap memory.  Code usually
      deals with this stuff using "absolute" addresses (rather than relative
      addresses), and I can find no way without an MMU to fix this.  Copying
      the malloced memory around is the only way to make this work, and that
      will mean copying lots of little pieces of memory.
   
   It seems to me that there really is no "clean" way to implement a fork
without an MMU, but you can implement a vfork easily -- if the program execs
immediately, then nothing is lost (and it's faster too).
   
 >     (I guess that this means we will have to conceed that Intel did something
 >right . . . .)

#include opinion-warning

   Only thing they did right was segments -- makes multi-tasking easier, but
other things a pain when the segments are too small to contain an entire
program, or all it's data.

-- Pat White
UUCP: k.cc.purdue.edu!ain  BITNET: PATWHITE@PURCCVM   PHONE: (317) 743-8421
U.S.  Mail:  320 Brown St. apt. 406,    West Lafayette, IN 47906

dillon@CORY.BERKELEY.EDU (Matt Dillon) (11/20/87)

	Forget MINIX.  Forget Fork()/Vfork(), I want the Amiga's OS.

					-Matt

jpdres10@usl-pc.UUCP (Green Eric Lee) (11/21/87)

In message <8711180347.AA10717@jade.berkeley.edu>, JPARR@UREGINA1.BITNET (John Parr) says:
>Hi all:
>     I ran across a technical difficulty when trying to port MINIX to the
>Amiga.  How the heck can you do a fork?

With difficulty :-).

The best solution that I've thought of for this problem is to make
your compiler generate relative code, that is, all addresses either
PC-relative or relative to stack/frame registers. Then for your fork,
all you have to do is copy to a new place, adjust your registers
accordingly, and presto, you're truckin'. 

That has a couple of flaws. It slows things down, limits your program
to around 64K in size, etc. etc. etc. However, considering that Minix
was designed to run in 64K of program and 64K of data anyhow (albeit
with the more-compact 808x instruction coding), on a 4.7mhz 8088...

--
   Eric Green  elg@usl.CSNET       P.O. Box 92191, Lafayette, LA 70509
   {ihnp4,cbosgd}!killer!elg,      {ut-sally,killer}!usl!elg
"Clothes make the man.  Naked people have little or no influence on
 society."  -- Mark Twain

nj@ndmath.UUCP (Narciso Jaramillo) (11/22/87)

Green Eric Lee quotes JPARR@UREGINA1.BITNET (John Parr) as saying:
>>Hi all:
>>     I ran across a technical difficulty when trying to port MINIX to the
>>Amiga.  How the heck can you do a fork?

I don't know if this is what you want (I'm not a multitasking guru) but the
Lattice 4.0 C documentation has a fork() command in it.  If you've already
seen it and it's not what you want, please ignore this.

nj

-- 
nj: ...!{pur-ee, rutgers, uunet}!iuvax!ndmath!nj, ...!ucbvax!mica!nj
"I am not a book." -- RMN                |  __   __ 
"I am not Richard Nixon." -- GRF         | /  \ |oo|---- [what game,
"I am not referring to myself." -- DRH   | \/\/ |__|----  what maker?]