DESIGN ISSUES FOR PAGING SYSTEMS
Two processes sharing the same program sharing its page tables.
made of the offending page so that each process now has its own private copy.
Both copies are now set to READ/WRITE, so subsequent writes to either copy
proceed without trapping. This strategy means that those pages that are never mod-
ified (including all the program pages) need not be copied. Only the data pages that
are actually modified need to be copied.
This approach, called
copy on write
proves performance by reducing copying.
3.5.6 Shared Libraries
Sharing can be done at other granularities than individual pages.
If a program
is started up twice, most operating systems will automatically share all the text
pages so that only one copy is in memory. Text pages are always read only, so there
is no problem here.
Depending on the operating system, each process may get its
own private copy of the data pages, or they may be shared and marked read only.
If any process modifies a data page, a private copy will be made for it, that is, copy
on write will be applied.
In modern systems, there are many large libraries used by many processes, for
example, multiple I/O and graphics libraries. Statically binding all these libraries to
every executable program on the disk would make them even more bloated than
they already are.
Instead, a common technique is to use
(which are called
Dynamic Link Libraries
on Windows). To make the idea of a shared
library clear, first consider traditional linking. When a program is linked, one or
more object files and possibly some libraries are named in the command to the
linker, such as the UNIX command
.o –lc –lm
which links all the
(object) files in the current directory and then scans two li-
Any functions called in the object files
but not present there (e.g.,
) are called
and are sought in
If they are found, they are included in the executable binary.
functions that they call but are not yet present also become undefined externals.
, so if
is not already included, the linker will
look for it and include it when found. When the linker is done, an executable bina-
ry file is written to the disk containing all the functions needed. Functions present
in the libraries but not called are not included.
When the program is loaded into
memory and executed, all the functions it needs are there.
Now suppose common programs use 20–50 MB worth of graphics and user in-
terface functions. Statically linking hundreds of programs with all these libraries
would waste a tremendous amount of space on the disk as well as wasting space in
RAM when they were loaded since the system would have no way of knowing it
could share them. This is where shared libraries come in.
When a program is link-
ed with shared libraries (which are slightly different than static ones), instead of in-
cluding the actual function called, the linker includes a small stub routine that
binds to the called function at run time. Depending on the system and the configu-
ration details, shared libraries are loaded either when the program is loaded or
when functions in them are called for the first time.
Of course, if another program
has already loaded the shared library, there is no need to load it again—that is the
whole point of it. Note that when a shared library is loaded or used, the entire li-
brary is not read into memory in a single blow. It is paged in, page by page, as
needed, so functions that are not called will not be brought into RAM.
In addition to making executable files smaller and also saving space in memo-
ry, shared libraries have another important advantage: if a function in a shared li-
brary is updated to remove a bug, it is not necessary to recompile the programs that
call it. The old binaries continue to work. This feature is especially important for
commercial software, where the source code is not distributed to the customer. For
example, if Microsoft finds and fixes a security error in some standard DLL,
will download the new DLL and replace the old one, and all pro-
grams that use the DLL will automatically use the new version the next time they
Shared libraries come with one little problem, however, that has to be solved,
however. The problem is illustrated in Fig. 3-26. Here we see two processes shar-
ing a library of size 20 KB (assuming each box is 4 KB).
However, the library is
located at a different address in each process, presumably because the programs
themselves are not the same size.
In process 1, the library starts at address 36K; in