[comp.arch] Multics & Memory mapped files

hammondr@sunroof.crd.ge.com (Richard A Hammond) (02/09/90)

Everybody seems to be missing the crucial fact about memory mapped files!

They ONLY work for cases where the file size is < virtual address space!!!

They are not a a generally useful solution which works over all possible
implementations.  UNIX file I/O does work over all situations!

In particular, the example of having to read sequentially through a file,
collecting info from each record in turn, works fine in UNIX on a PDP-11,
if implemented as fseek/fread/...
whereas if the memory mapped file paradigm was used, the largest file
you could handle would be, say 40k bytes(11/45, 11/70), clearly not an
interesting upper limit.

You can, under UNIX, do a stat(2) type call, get the file size, 
grow memory if necessary, and then read the whole dang file into memory.
If you're really going to look at every page of the file I'm not
convinced that this would be a major performance penalty versus
memory mapped I/O.

Now try to port that code to an 8088/80286/80386 running in 8086 mode.

With enough funny hardware and restrictions on saving pointers, I guess
you could trap increments of address registers when they crossed a
segment boundary.

If I recall properly, Multics hardware couldn't address more than 2^18
words(?) per segment.  While that was huge at the time, it isn't all
that interesting now as an upper limit.  What, if anything, did the
programmer do to handle files > 1 segment in length?

This is not to say that memory mapped files are a "BAD IDEA", just
that they have limits that must be considered by the programmer.

Rich Hammond

davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) (02/10/90)

In article <5180@crdgw1.crd.ge.com> hammondr@sunroof.crd.ge.com (Richard A Hammond) writes:
| Everybody seems to be missing the crucial fact about memory mapped files!
| 
| They ONLY work for cases where the file size is < virtual address space!!!
| 
| They are not a a generally useful solution which works over all possible
| implementations.  UNIX file I/O does work over all situations!

  You're right, but in general it doesn't matter. I looked over files on
about 200 Suns for large files, and the largest single file was under
100MB. Therefore for most applications there isn't a problem.

  I'm not disagreeing that a problem is not impossible, but it's really
uncommon. You have to support really large text and database files, but
the average application never get a large file by 32 bit standards.
-- 
bill davidsen	(davidsen@crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen)
            "Stupidity, like virtue, is its own reward" -me

davecb@yunexus.UUCP (David Collier-Brown) (02/10/90)

hammondr@sunroof.crd.ge.com (Richard A Hammond) writes:
| If I recall properly, Multics hardware couldn't address more than 2^18
| words(?) per segment.  While that was huge at the time, it isn't all
| that interesting now as an upper limit.  What, if anything, did the
| programmer do to handle files > 1 segment in length?

	Alas, this was badly handled in the first 9 or so releases...  The
	segment sizes were really 2^16 (words, I think! I remember
	discussion of leaving addressability to the byute in the design) and
	the maximum file size was something like 2^72 bits.

	The mechanism for doing large files was the so-called multi-segment
	file, which was really a directory containing more than one segment.
	Applications treating these as sequential constructs just opened
	them and read/write.  The segment manager looked after having
	multiple segments with the "same" name.  Applications doing random
	I/O (including one of mine) had a harder time, as the structure
	could be and occasionally was, manipulated directly by the idiot
	programmer. This was both hard and non-portable.

| This is not to say that memory mapped files are a "BAD IDEA", just
| that they have limits that must be considered by the programmer.

	The replacement, being worked on when I left, was the "extended
	object", which was a generalization of the file and contained the
	code for mapping very large segments into the address spaces in
	a programmer-independant manner: you said the equivalent of 
	stdio_$fseek(stream, offset, ptrname) and you were there

--dave (if you have limits, they should be 0, 1, or infinity) c-b


-- 
David Collier-Brown,  | davecb@yunexus, ...!yunexus!davecb or
72 Abitibi Ave.,      | {toronto area...}lethe!dave 
Willowdale, Ontario,  | Joyce C-B:
CANADA. 416-223-8968  |    He's so smart he's dumb.

mrc@Tomobiki-Cho.CAC.Washington.EDU (Mark Crispin) (02/10/90)

In article <5180@crdgw1.crd.ge.com> hammondr@sunroof.crd.ge.com (Richard A Hammond) writes:
>Everybody seems to be missing the crucial fact about memory mapped files!
>
>They ONLY work for cases where the file size is < virtual address space!!!
>
>They are not a a generally useful solution which works over all possible
>implementations.  UNIX file I/O does work over all situations!

As has already been pointed out, the case of a file that is larger
than the virtual address space is relatively infrequent on all but
very small machines such as PDP-11's.  I don't think anyone considers
a PDP-11 to be a modern platform.

Furthermore, I hope that no one would implement file/memory mapping
that only mapped the entire file in.  You should be able to map n
"pages" or "segments" from "page"/"segment" i of source to
"page"/"segment" j of destination.

It may be very common for n = size of file, i = 0, and j = free chunk
of memory big enough to hold the file.  However, this is not the only
form of file/memory mapping you may want to do.

I suppose it is also known that mapping in itself does not do any I/O
unless you also specify "preloading".  The overhead of mapping 1 page
should be more or less the same as mapping 100,000.

I'll acknowledge this requires some knowledge of page or segment
sizes, but that can be done in a .h file so you can write portable
code.  A good way (which is what TOPS-20 used) is to have the
filesystem allocation unit be the same as the memory allocation unit.
As long as your code is careful to calculate the number of units based
on the page size instead of assuming that it is 512 or 1024 or
whatever, it's portable.

For historical reference, here's a description of TOPS-20's memory
mapping system call.  Note that you could use either a file or a
process for source or destination, as well as have a bi-directional
file/memory map.  No file/file mapping though.  :-) :-) Disc I/O under
TOPS-20 was simply byte copies to an operating system buffer that was
PMAPed.  Direct PMAP I/O was much faster than disc I/O!

                              PMAP     JSYS 56

   Maps one or more complete pages from a file to a process (for  input),
   from  a process to a file (for output), or from one process to another
   process.  Also unmaps pages from a process and deletes  pages  from  a
   file.  Each of the five uses of PMAP is described below.

 
   Case I:  Mapping File Pages to a Process

   This use of the PMAP call does not actually  transfer  any  data;   it
   simply  changes  the  contents of the process' page map.  When changes
   are made to the  page  in  the  process,  the  changes  will  also  be
   reflected  in the page in the file, if write access has been specified
   for the file.

   ACCEPTS IN AC1:  JFN of the file in the left half, and the page number
                    in  the file in the right half.  This AC contains the
                    source.

              AC2:  process handle in the left half, and the page  number
                    in  the  process in the right half.  This AC contains
                    the destination.

              AC3:  B0(PM%CNT)  A count is in  the  right  half  of  AC3.
                                This   count   specifies  the  number  of
                                sequential pages to be mapped.   If  this
                                bit is not set, one page is mapped.

                    B2(PM%RD)   Permit read access to the page.

                    B3(PM%WR)   Permit write access to the page.

                    B4(PM%EX)   Reserved for future use.
                                The symbol PM%RWX  can  be  used  to  set
                                B2-4.

                    B5(PM%PLD)  Preload the page being mapped  (move  the
                                page immediately instead of waiting until
                                it is referenced).

                    B9(PM%CPY)  Create a private copy of the page when it
                                is  written into (copy-on-write).  If the
                                page  is  mapped  between  two  processes
                                (Case  III  below),  both  processes will
                                receive a private copy of the page.

|                   B10(PM%EPN) The  right  half  of  AC2   contains   an
|                               extended  process  page  number.   If the
|                               section  containing  the  page  does  not
|                               exist,  an  illegal  instruction  trap is
|                               generated.

                    B11(PM%ABT) Unmap  a  page  and  throw  its   changed
                                contents  away.   This bit is significant
                                only when unmapping  process  pages  that
                                were  mapped  from  a  file  (see case IV
                                below) and OF%DUD is set in the OPENF.

                                Normally, if a page is unmapped  and  has
                                been  changed  since  the  last  time the
                                monitor updated the associated file page,
                                the monitor will remove the page from the
                                process and place it on a queue in  order
                                to  update  the file page.  PM%ABT allows
                                the page to be unmapped, but prevents the
                                monitor  from  placing  the  page  on the
                                update queue.

                                This feature is useful  in  the  case  of
                                erroneous  data  written to a mapped page
                                of a file open for  simultaneous  access.
                                In  this  case,  it is important that the
                                erroneous page be discarded  and  not  be
                                used  to  update  the file page.  Another
                                application  is  to  allow  processes  in
                                separate jobs to communicate by sharing a
                                file page (and reading/writing the  page)
                                and  avoid  the  overhead  of the monitor
                                periodically updating the page.

                    B18-35      Number of pages to be mapped if
                    (PM%RPT)    B0(PM%CNT) is set.

   RETURNS     +1:  always

   This use of PMAP changes the map of the process such that addresses in
   the  process page specified by the right half of AC2 actually refer to
   the file page specified  by  the  right  half  of  AC1.   The  present
   contents  of the process page are removed.  If the page in the file is
   currently nonexistent, it will be created when it is written (when the
   corresponding page in the process is written).  If the process page is
   in a nonexistant section, an illegal instruction trap is generated.

   This use of PMAP is legal only if the file is opened for at least read
   access.  The access bits specified in the PMAP call are ANDed with the
   access  that  was  specified  when  the  file  was  opened.   However,
   copy-on-write is always granted, regardless of the file's access.  The
   access granted is placed in the process'  map.   The  file  cannot  be
   closed  while  any  of  its  pages are mapped into any process.  Thus,
   before the file is closed, pages must be unmapped from each process by
   a PMAP call with -1 in AC1 (see below).

 
   Case II Mapping Process Pages to a File

   This use of the PMAP  call  actually  transfers  data  by  moving  the
   contents of the specified page in the process to the specified page in
   the file.  The process' map for that page becomes empty.

   ACCEPTS IN AC1:  process handle in the left half, and the page  number
                    within  the  process  in  the  right  half.   This AC
                    contains the source.

              AC2:  JFN of the file in the left half, and the page number
                    within  the file in the right half.  This AC contains
                    the destination.

              AC3:  access bits and repetition count.  (Refer to Case I.)

   RETURNS     +1:  always

   The process page and  the  file  page  must  be  private  pages.   The
   ownership  of  the  process page is transferred to the file page.  The
   present contents of the page in the file is deleted.

   The access granted to the file page is determined by ANDing the access
   specified in the PMAP call with the access specified when the file was
   opened.  This function does not update the file's  byte  size  or  the
   end-of-file  pointer in the file's FDB.  Failure to update these items
   in the FDB can prevent the reading of the file by sequential I/O calls
   such as BIN and BOUT.

   To update the file's FDB  after  using  this  PMAP  function,  do  the
   following:

        1.  Use the CLOSF call with the CO%NRJ bit set to close the  file
            but keep the JFN.

        2.  Use the CHFDB call to update the end-of-file pointer and,  if
            necessary, the byte size in the file's FDB.

        3.  Use the RLJFN call to release the JFN.

   (Refer to Section 2.2.8 for the format of the FDB fields.)

   Case III Mapping One Process' Pages to Another Process

   This use of the PMAP call normally does not  transfer  any  data;   it
   simply  changes  the contents of the page maps of the processes.  When
   changes are made to the page in one process, the changes will also  be
   reflected in the corresponding page in the other process.

   ACCEPTS IN AC1:  process handle in the left half, and the page  number
                    in  the  process in the right half.  This AC contains
                    the source.

              AC2:  a second process handle in the left  half,  and  page
                    number  in  that  process in the right half.  This AC
                    contains the destination.

              AC3:  access bits and repetition count.  (Refer to Case I.)

   RETURNS     +1:  always

   This use of PMAP changes the map of the destination process such  that
   addresses  in  the  page  specified  by the right half of AC2 actually
   refer to the page in the source process specified by the right half of
   AC1.  The present contents of the destination page are deleted.

   The access granted to the destination page is determined by the access
   specified  in  the  PMAP  call.   If  the  destination  page  is  in a
   nonexistant section, the  monitor  generates  an  illegal  instruction
   trap.

   Case IV Unmapping Pages In a Process

   As stated previously, a file cannot be closed if any of its pages  are
   mapped in any process.

   ACCEPTS IN AC1:  -1

              AC2:  process handle in the  left  half,  and  page  number
                    within the process in the right half

              AC3:  B0(PM%CNT)  Repeat  count.   Only  the  process  page
                                numbers are incremented.

                    B18-35     Number of pages to remove from process

   This format of the PMAP call removes the pages indicated in  AC2  from
   the process.

   A page that was locked with the PLOCK call may be unmapped.  Doing  so
   will  unlock  the  process'  page and return the now unlocked physical
   page to its previous state.

   Case V Deleting One or More Pages from a File

   Deletes one or more pages from a file on disk and does not affect  the
   address space of any process.

   ACCEPTS IN AC1:  -1

              AC2:  JFN of the file in the  left  half  and  page  number
                    within the file in the right half.

              AC3n: B0(PM%CNT)  Indicates that the  right  half  contains
                    the number of pages to delete.

                    B18-35      Number of pages to delete from file

   Illegal PMAP calls

   The PMAP call is illegal if:

        1.  Both AC1 and AC2 designate files.

        2.  Both AC1 and AC2 are 0.

        3.  The PMAP call designates a file with write-only access.

        4.  The PMAP call designates a file with append-only access.

        5.  The source and/or the destination designates an  execute-only
            process and the process is not self (.FHSLF).

   Can cause several software interrupts on certain file conditions.

   Generates an illegal instruction interrupt on error conditions below.

   PMAP ERROR MNEMONICS:

   ARGX06:   Invalid page number
   CFRKX3:   Insufficient system resources
   DESX1:    Invalid source/destination designator
   DESX3:    JFN is not assigned
   DESX5:    File is not open
   DESX7:    Illegal use of parse-only JFN or output wildcard-designators
   FRKHX1:   Invalid process handle
   FRKHX2:   Illegal to manipulate a superior process
   FRKHX3:   Invalid use of multiple process handle
   FRKHX7:   Process page cannot exceed 777
   FRKHX8:   Illegal to manipulate an execute-only process
   IOX11:    Quota exceeded
   IOX34:    Disk full
   IOX35:    Unable to allocate disk - structure damaged
   LNGFX1:   Page table does not exist and file not open for write
   PMAPX1:   Invalid access requested
   PMAPX2:   Invalid use of PMAP
   PMAPX3:   Illegal to move shared page into file
   PMAPX4:   Illegal to move file page into process
   PMAPX5:   Illegal to move special page into file
   PMAPX6:   Disk quota exceeded
   PMAPX7:   Illegal to map file on dismounted structure
   PMAPX8:   Indirect page map loop detected
 _____     ____ ---+---   /-\   Mark Crispin           Atheist & Proud
 _|_|_  _|_ ||  ___|__   /  /   6158 Lariat Loop NE    R90/6 pilot
|_|_|_| /|\-++- |=====| /  /    Bainbridge Island, WA  "Gaijin! Gaijin!"
 --|--   | |||| |_____|   / \   USA  98110-2098        "Gaijin ha doko ka?"
  /|\    | |/\| _______  /   \  +1 (206) 842-2385      "Niichan ha gaijin."
 / | \   | |__| /     \ /     \ mrc@CAC.Washington.EDU "Chigau. Gaijin ja nai.
kisha no kisha ga kisha de kisha-shita                  Omae ha gaijin darou."
sumomo mo momo, momo mo momo, momo ni mo iroiro aru    "Iie, boku ha nihonjin."
uraniwa ni wa niwa, niwa ni wa niwa niwatori ga iru    "Souka. Yappari gaijin!"

terry@uts.amdahl.com (Lewis T. Flynn) (02/11/90)

In article <5684@blake.acs.washington.edu> mrc@Tomobiki-Cho.CAC.Washington.EDU (Mark Crispin) writes:
>
>Furthermore, I hope that no one would implement file/memory mapping
>that only mapped the entire file in.  You should be able to map n
>"pages" or "segments" from "page"/"segment" i of source to
>"page"/"segment" j of destination.

[ and a further discussion and detailed example.]

Another example is KeyKOS where the maximum segment is 2**47 pages (2**59
bytes) and the user could map into his address space any portion at any
location. This in an implementation on a harware architecture which only
allowed physical segments and address spaces of 2**24 bytes.

Terry

disclaimer: I have no idea what Amdahl's views are.

peter@ficc.uu.net (Peter da Silva) (02/12/90)

In article <5180@crdgw1.crd.ge.com> hammondr@sunroof.crd.ge.com (Richard A Hammond) writes:
> Everybody seems to be missing the crucial fact about memory mapped files!

> They ONLY work for cases where the file size is < virtual address space!!!

Why? Nobody said you had to map the file in from the beginning. Even on a
PDP-11, there's no problem with seeking to location 2^20 and starting the
mapping from there (or using whatever mechanism you want).

Nobody is denying that both techniques have advantages in certain domains: for
example, it's hard to memory map a serial port. But this isn't one of them.

> If I recall properly, Multics hardware couldn't address more than 2^18
> words(?) per segment.  While that was huge at the time, it isn't all
> that interesting now as an upper limit.  What, if anything, did the
> programmer do to handle files > 1 segment in length?

They used multisegment files, which was probably a pain.

> This is not to say that memory mapped files are a "BAD IDEA", just
> that they have limits that must be considered by the programmer.

As do stream files.
-- 
 _--_|\  Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
/      \
\_.--._/ Xenix Support -- it's not just a job, it's an adventure!
      v  "Have you hugged your wolf today?" `-_-'

pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi) (02/12/90)

In article <5180@crdgw1.crd.ge.com> hammondr@sunroof.crd.ge.com (Richard A Hammond) writes:

   Everybody seems to be missing the crucial fact about memory mapped files!
   They ONLY work for cases where the file size is < virtual address space!!!

Not really. You can work around it elegantly.

Unfortunately there are OTHER problems with memory mapped
entities, that are not being really addressed in the mapped
memory systems that are emerging now and that clone mindlessly
the Multics approach.

Still memory mapped is a *huge* win over the Unix way of doing
things.

The general approach of doing memory mapped things is to assume
that they exist independently from the process address space, and
that you can map sections of the entity in sections of the
address space; in this way an entity may be much larger than an
address space (see how MUSS does it, SP&E August 1979).

You separate address space from data space entirely; a job may
have several data space segments that are not mapped in any
address space window.

If you allow a user program the ability to manipulate its address
space map, this becomes very easy to do; you can even (like in
Mach) have virtual data segments, where the address space fault
handler fakes data instead of mapping in data space entity.

Once you have this, you discover all the problems with memory mapped
entities. One can be easily solved, the other not so easily.

The first is data space aliasing. You have portions of data space
visible thru different ranges of address space, possibly multiply
in the same address space, or multiply in different address
spaces (shared memory). This is bad. The cure is to allow it only
for irrevocably read only segments; the others can only be mapped
in one place at a time; address spaces take turns at mapping a
segment (this is the MUSS approach -- MUSS has convenient
'messages' that pass around permission to map a segment). This
makes for safe interprocess communication, and need not (on a
suitable HW VM architecture) be inefficient at all.

In particular, abolishing shared memory makes it possible to use
reverse map MMUs (like the ATLAS, the MU6, an as yet unpublished
design of mine, and the ROMP), which are a big win because they
efficiently support very large, sparse address spaces.


The second problem is address space aliasing. This is that you
may map the same segment at different times in different portions
of the address space. This means that you cannot use absolute
addresses in a segment (as well as the obvious semantic hazards).
The *only* solution is to have a single address space for all
processes, i.e. a capability machine (if you want protection
:->).

There are palliatives; the early binding (MULTICS) palliative is
to have an impure relocation table for the segment, that gets
copied and absolutized whenever the segment is mapped (static
early binding) or addresses in it are used (dynamic early
binding); the late binding palliative (used in MUSS/MUPL, and in
PL/1) is to have relative pointers as a language feature.

Which of the palliatives you prefer depends strongly on the type
of data segment, and its usage pattern. For example the early
binding approach is commonly used with code segments, as the late
binding one is the same as position independent code, which is
not always optimal. Many data structures can be easily approached
with relative pointers, and they become more compact as well.

Intersegment pointers are especially difficult, and they usually
require the early (which may be static, but more often dynamic)
binding approach.

A very large database can be built of multiple segments, and if
they are properly implemented there is really no limit of size,
as you slide multiple windows over multiple segments. A suitably
written library can make this virtually painless. Note that something
similar is always needed, except on single very large address space
machines.
--
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

terry@uts.amdahl.com (Lewis T. Flynn) (02/13/90)

In article <PCG.90Feb11205739@rupert.cs.aber.ac.uk> pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi) writes:
>
>The general approach of doing memory mapped things is to assume
>that they exist independently from the process address space, and
>that you can map sections of the entity in sections of the
>address space; in this way an entity may be much larger than an
>address space (see how MUSS does it, SP&E August 1979).
>
>You separate address space from data space entirely; a job may
>have several data space segments that are not mapped in any
>address space window.
>
>If you allow a user program the ability to manipulate its address
>space map, this becomes very easy to do; you can even (like in
>Mach) have virtual data segments, where the address space fault
>handler fakes data instead of mapping in data space entity.

True.

>Once you have this, you discover all the problems with memory mapped
>entities. One can be easily solved, the other not so easily.
>
>The first is data space aliasing. You have portions of data space
>visible thru different ranges of address space, possibly multiply
>in the same address space, or multiply in different address
>spaces (shared memory). This is bad. The cure is to allow it only
>for irrevocably read only segments; the others can only be mapped
>in one place at a time; address spaces take turns at mapping a
>segment (this is the MUSS approach -- MUSS has convenient
>'messages' that pass around permission to map a segment). This
>makes for safe interprocess communication, and need not (on a
>suitable HW VM architecture) be inefficient at all.

I don't understand why this is bad. In the implementation I am familiar
with, users mapped in according to their needs and priveleges (if you
only had read access, that's all you could map in; if you had read/write,
you could do either). If more than one application mapped in read/write
they had to coordinate, but that wasn't too different to do. Perhaps my
confusion is due to an invalid comparison. KeyKOS segments only loosely
correspond to files and usually shared files were more convenient to
access using a file paradigm (like read/write/lseek) so that multiple
read/write access was managed transparently.
 
>The second problem is address space aliasing. This is that you
>may map the same segment at different times in different portions
>of the address space. This means that you cannot use absolute
>addresses in a segment (as well as the obvious semantic hazards).
>The *only* solution is to have a single address space for all
>processes, i.e. a capability machine (if you want protection
>:->).

If you mean a single level store that is used to build all other address
spaces, then I agree. That's the most successful way I've heard of (my
own experience in this area is limited, but I was fortunate enough to
work with exceptional people who had been studying this particular 
problem for a long time). Capabilities and objects sure make life simpler
here.

[other discussion]
 
>A very large database can be built of multiple segments, and if
>they are properly implemented there is really no limit of size,
>as you slide multiple windows over multiple segments. A suitably
>written library can make this virtually painless. Note that something
>similar is always needed, except on single very large address space
>machines.

An alternative is to use a segment definition that is independent of the
hardware limitation. This doesn't remove the multiple window requirement,
but, for most practical cases, does remove the need for multiple segments
for size reasons. In the case with which I am most familiar, the implemenation
allowed a segment size of 2**59 bytes on a machine whose physical segment
was limited to 2**24 bytes. You mapped in the part you needed, and the VMM
worried about the rest.

>--
>Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
>Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
>Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

Terry

Disclaimer: I have no idea what Amdahl's views on these matters are.

seanf@sco.COM (Sean Fagan) (02/13/90)

In article <2115@crdos1.crd.ge.COM> davidsen@crdos1.crd.ge.com (bill davidsen) writes:
>  You're right, but in general it doesn't matter. I looked over files on
>about 200 Suns for large files, and the largest single file was under
>100MB. Therefore for most applications there isn't a problem.

Except, of course, that Sun's MMUs don't work with very large virtual
memories, either.  I think the Sun-2 had a limit of 16Mb, of course (68010),
and the early Sun-3's, at least, had a limit of 64 or 128Mb per process.

I could be wrong, of course, but I don't believe they supported all 32
virtual address bits.

-- 
Sean Eric Fagan  | "Time has little to do with infinity and jelly donuts."
seanf@sco.COM    |    -- Thomas Magnum (Tom Selleck), _Magnum, P.I._
(408) 458-1422   | Any opinions expressed are my own, not my employers'.

aglew@oberon.csg.uiuc.edu (Andy Glew) (02/13/90)

>Everybody seems to be missing the crucial fact about memory mapped files!
>
>They ONLY work for cases where the file size is < virtual address space!!!
>
>They are not a a generally useful solution which works over all possible
>implementations.  UNIX file I/O does work over all situations!

Anecdote: 
    The BSD kernel used to check the "seek pointer" of a file before
access, even on sequential files and special devices.  If the seek
pointer were negative, an error was returned.
    Gould built a device called an HS[CXD] (I can't remember the exact
name - similar to the so-called "Cray-Channel" (in fact, a modified
system was used for Cray connectivity).  Reasonably mongo I/O
throughput (even now).  Only took a few seconds for the seek pointer
to reach 2^(31) and turn negative -- at which point the device stopped
working.

Moral: UNIX file I/O may not work in all situations.

--
Andy Glew, aglew@uiuc.edu

pkr@maddog.sgi.com (Phil Ronzone) (02/13/90)

In article <2115@crdos1.crd.ge.COM> davidsen@crdos1.crd.ge.com (bill davidsen) writes:
>In article <5180@crdgw1.crd.ge.com> hammondr@sunroof.crd.ge.com (Richard A Hammond) writes:
>| Everybody seems to be missing the crucial fact about memory mapped files!
>| They ONLY work for cases where the file size is < virtual address space!!!
>
>  You're right, but in general it doesn't matter. I looked over files on
>about 200 Suns for large files, and the largest single file was under
>100MB. Therefore for most applications there isn't a problem.
>
>  I'm not disagreeing that a problem is not impossible, but it's really
>uncommon. You have to support really large text and database files, but
>the average application never get a large file by 32 bit standards.


Yes, but in most MMU software/hardware designs, the user address space
is NOT 32 bits, but 32 bits - N, where N has been as high as 8.


------Me and my dyslexic keyboard----------------------------------------------
Phil Ronzone   Manager Secure UNIX           pkr@sgi.COM   {decwrl,sun}!sgi!pkr
Silicon Graphics, Inc.               "I never vote, it only encourages 'em ..."
-----In honor of Minas, no spell checker was run on this posting---------------

tihor@acf4.NYU.EDU (Stephen Tihor) (02/13/90)

Even fixing the file pointer to be unsigned you need an integer type 
large enough to contains someting from { your address space, your dataspace}
or if you are really agressive {all know data}.  As seek dies a well desrved
death fpos* will help some since the opaque objects can get bigger.
But until C is replaced by C++ or ADa or Multla-3 or some language that 
permits definitions of things such as + on opauqe types people will have
problems doing real work.  I know poeple with real, production system that
exceed 32 bits of addressible bytes casually and are pushing 48 bits.  

You can dismiss such things as unlikely.  Then you must explain to them
how "UNIX is the FUTURE" when it makes them do painful things to work.
Frankly we need additional clean primitives, new concepts, which frankly
have not been being added to the UNIX at any reasonable rate.

[Example: the ELXSI unix-like but designed rom scratch OS EMBOS unified
the procedurable namespace with the file name space so object libraries 
were the same as directories in may senses.  A perfect "UNIX style" idea.
Ain't in Research 9 or AT&T SV.4 or on any up and coming lists I have seen.]

desnoyer@apple.com (Peter Desnoyers) (02/14/90)

If I remember correctly from my computer architecture class several years 
back, there is a substantial penalty in kernel complexity to implement a 
paging scheme which can page from arbitrary files instead of a 
pre-allocated contiguous chunk of disk. (The comparison was between 
Multics and some other system of the same vintage - the Multics code was 
about 10X longer.) You also end up with a much larger body of code that 
must be protected from paging.

It is quite possible to design a VM system that will not allow 
memory-mapped file access. The problem is that this system may end up 
being faster, simpler,  and more robust than one which is able to map user 
files into its memory space.


                                             Peter Desnoyers
                                             Apple ATG
                                             desnoyer@apple.com

mrc@Tomobiki-Cho.CAC.Washington.EDU (Mark Crispin) (02/14/90)

In article <6662@internal.Apple.COM> desnoyer@apple.com (Peter Desnoyers) writes:
>If I remember correctly from my computer architecture class several years 
>back, there is a substantial penalty in kernel complexity to implement a 
>paging scheme which can page from arbitrary files instead of a 
>pre-allocated contiguous chunk of disk.

Is this true in all cases?  Suppose the only difference between the
"swap space" and the "file space" is that the file space has a
directory and naming structure associated with it.  The swap pointers
are the same in both cases (disk addresses), so the only difference is
in how the swap pointer was set up.

 _____     ____ ---+---   /-\   Mark Crispin           Atheist & Proud
 _|_|_  _|_ ||  ___|__   /  /   6158 Lariat Loop NE    R90/6 pilot
|_|_|_| /|\-++- |=====| /  /    Bainbridge Island, WA  "Gaijin! Gaijin!"
 --|--   | |||| |_____|   / \   USA  98110-2098        "Gaijin ha doko ka?"
  /|\    | |/\| _______  /   \  +1 (206) 842-2385      "Niichan ha gaijin."
 / | \   | |__| /     \ /     \ mrc@CAC.Washington.EDU "Chigau. Gaijin ja nai.
kisha no kisha ga kisha de kisha-shita                  Omae ha gaijin darou."
sumomo mo momo, momo mo momo, momo ni mo iroiro aru    "Iie, boku ha nihonjin."
uraniwa ni wa niwa, niwa ni wa niwa niwatori ga iru    "Souka. Yappari gaijin!"