From: Theodore Ts'o (tytso@ATHENA.MIT.EDU)
Date: 11/16/91


Subject: Re: demand paging: proposal
Date: Sat, 16 Nov 1991 22:47:00 -0500
From: tytso@ATHENA.MIT.EDU (Theodore Ts'o)

From: pmacdona@sol.UVic.CA (Peter MacDonald)

> - Attempt to implement the stickey bit, to pin an executable
> in memory once loaded.

Everyone should note that this is not the original meaning of the sticky
bit, in the BSD 4.3 sense. In the BSD sense, what the sticky bit means
is that after the program exits, its entry in the text table is not
purged and its swap space is not reclaimed. The program was _not_
locked into memory, and would get swapped out if demands were placed on
the VM system. The rationale behind this is that in a time-sharing
environment, programs like GNU emacs are almost in use by *someone*, and
in the case where the last person finishes running emacs, the program
should not be flushed from the text cache, swap space, and ram, in the
hope that another user would be starting an emacs before the unused
program got swapped out to disk. In that case, the user would win since
no disk I/O would be needed. However, in a single-user environment,
the value of the sticky bit is rather dubious, and Project Athena
workstations don't even bother using it for this reason.

That being said, I'm not too sure that pinning an executable into memory
is a good idea. Unless you have gobs and gobs of memory, you wouldn't
be able to "sticky bit" more than one or two programs before you run out
of physical memory, and in the meantime, locking down large amounts of
memory would increase the amount of VM thrashing when other programs
are running.

A better idea might be to not flush the text table entry once its ref
count goes to zero, but to rather wait until the last of its text pages
are paged out (which will happen sooner rather or later because there is
no program using the text). However, if the text is used by a process
before the last pages are reclaimed then you will win because some
number of pages won't need to be brought back in from disk. Thus, this
system will do the right thing for someone who has enough memory to keep
gcc, make, etc. in core at the same time during a build. The advantage
that this scheme has is that it will automatically adapt to whatever
text image is being repeatedly used --- you don't need to sticky bit a
limited number of processes. For this reason, it is also a much fairer
system.

------------------------------------

>9k : size of minix executable of diff
>36k : size of gcc compiled executable of diff
>4k : size of gcc compiled diff.o

>It won't be to long before my disk flow'th over. Not to mention
>ram requirments.

The culprit here is the floating point library (i.e., the soft floats);
even if your program isn't using floats, printf() drags large portions
of it in. The bottom line is that every integer-only executable will be
roughly 10-20k bigger than it has to be. That's most of the problem,
anyway; the most of the rest of it is due to things like gmalloc.o,
which is 4979 bytes. (malloc.o on the vax is 1176 bytes).

There are a couple of hack solutions, which I perhaps shouldn't mention
because they might actually get implemented :-) One way to do it would
be to include the soft-float library in the kernel, and map those pages
read-only at the top of the address space for every process. This has
the advantage that you don't need to run a linker at run-time, since the
addresses for the soft-float library would be well-known constants.
(you'd probably put a jump table at the tippy-top, and make all the
rum-time routines reference the jump table).

This is very ugly, and it is only (barely) justifiable because (1) every
single program is going to need the floating point library and (2) it is
unlikely that the FP library will be changing often, so requiring that
you recompile the kernel to replace the FP library isn't quite as nasty
as it first seems. It is definitely not something that you would want
to use for sharing copies of the dbm library or the X toolkit. The only
reason why I mention it is that doing shared libraries for real would
probably entail a lot more work. :-)

-----------------------------------

I've noticed that there is a bug in the system call waitpid() --- the
parent process gets told that exit code for the child process is always
zero. I've already sent a patch to Linus privately, but if anyone else
is interested in the batch, it is available on TSX-11.MIT.EDU, in
/pub/linux/patches/exit.c.patch .

I've also uploaded tar files containg the binaries and libraries of
Bison and Flex to TSX-11, nic.funet.fi, and tupac-amaru. Bison and
Flex are yacc and lex replacements from the GNU project. Flex passes
all but the COMPRESSION=-Cf and COMPRESSION=-CF regressions tests ---
however, it looks like it's not a fault of flex, but rather of GCC. It
looks like gcc is not compiling the resulting (very large) scan.c files
correctly. For normal usage, however, flex (and gcc) should work just
fine.

Enjoy!

                                                - Ted