145
|
1 <chapter>
|
|
2 <title>Multiprogramming and Memory Management</title>
|
|
3 <para>
|
|
4 One of OS-9's most extraordinary abilities is multiprogramming,
|
|
5 which is sometimes called timesharing or multitasking. Simply
|
|
6 states, OS-9 lets you computer run more than one program at the same
|
|
7 time. This can be a tremendous advantage in many situations. For
|
|
8 example, you can be editing one program while another is being
|
|
9 printed. Or you can use your Color Computer to control household
|
|
10 automation and still be able to use it for routine work and
|
|
11 entertainment.
|
|
12 </para>
|
|
13 <para>
|
|
14 OS-9 uses this capability all the time for internal functions.
|
|
15 The simple way for you to do so is by putting a "&" character at the
|
|
16 end of a command line which causes the shell to run your command as
|
|
17 a "background task".
|
|
18 </para>
|
|
19 <para>
|
|
20 The information presented in this chapter is intended to give you
|
|
21 an insight into how OS-9 performs this amazing feat. You certainly
|
|
22 don't have to know every detail of how multiprogramming works in
|
|
23 order to use OS-9, but a basic working knowledge can help you
|
|
24 discover many new ways to use your Color Computer.
|
|
25 </para>
|
|
26 <para>
|
|
27 In order to allow several programs to run simultaneously and
|
|
28 without interference, OS-9 must perform many coordination and
|
|
29 resource allocation functions. The major system resources managed
|
|
30 by OS-9 are:
|
|
31 </para>
|
|
32 <simplelist>
|
|
33 <member>CPU Time</member>
|
|
34 <member>Memory</member>
|
|
35 <member>The input/output system</member>
|
|
36 </simplelist>
|
|
37 <para>
|
|
38 In order for the computer to have reasonable performance, these
|
|
39 resources must be managed in the most efficient manner possible.
|
|
40 Therefore, OS-9 uses many techniques and strategies to optimize
|
|
41 system throughput and capacity.
|
|
42 </para>
|
|
43
|
|
44 <section>
|
|
45 <title>Processor Time Allocation and Timeslicing</title>
|
|
46
|
|
47 <para>
|
|
48 CPU time is a resource that must be allocated wisely to maximize
|
|
49 the computer's throughput. It is characteristic of many programs to
|
|
50 spend much unproductive time waiting for various events, such as an
|
|
51 input/output operation. A good example is an interactive program
|
|
52 which communicates with a person at a terminal on a line-by line
|
|
53 basis. Every time the program has to wait for a line of characters
|
|
54 to be typed or displayed, it (typically) cannot do any useful
|
|
55 processing and would waste CPU time. An efficient multiprogramming
|
|
56 operating system such as OS-9 automatically assigns CPU time to only
|
|
57 those programs that can effectively use the, time.
|
|
58 </para>
|
|
59 <para>
|
|
60 OS-9 uses a technique called <emphasis>timeslicing</emphasis> which allows processes
|
|
61 to share CPU time with all other active processes. Timeslicing is
|
|
62 implemented using both hardware and software functions. The
|
|
63 system's CPU is interrupted by a real time clock many (60 in the
|
|
64 Color Computer) times each second. This basic time interval is
|
|
65 called a "tick", hence, the interval between ticks is a time slice.
|
|
66 This technique is called timeslicing because each second of CPU time
|
|
67 is sliced up to be shared among several processes. This happens so
|
|
68 rapidly that to a human observer all processes appear to execute
|
|
69 continuously, unless the computer becomes overloaded with processing. If this
|
|
70 happens, a noticeable delay in response to terminal
|
|
71 input may occur, or "batch" programs may take much longer to run
|
|
72 than they ordinarily do. At any occurrence of a tick, OS-9 can suspend
|
|
73 execution of one program and begin execution of another. The
|
|
74 starting and stopping of programs is done in a manner that does not
|
|
75 affect the program's execution. How frequently a process is given
|
|
76 time slices depends upon its assigned priority relative to the
|
|
77 assigned priority of other active processes.
|
|
78 </para>
|
|
79 <para>
|
|
80 The percentage of CPU time assigned to any particular process
|
|
81 cannot be exactly computed because there are dynamic variables such
|
|
82 as time the process spends waiting for I/O devices. It can be
|
|
83 roughly approximated by dividing the process's priority by the sum
|
|
84 of the priority numbers of all processes:
|
|
85 </para>
|
|
86 <screen>
|
|
87
|
|
88 Process Priority
|
|
89 Process CPU Share = -------------------
|
|
90 Sum of All Active
|
|
91 Process' Priorities
|
|
92 </screen>
|
|
93 </section>
|
|
94
|
|
95 <section>
|
|
96 <title>Process States</title>
|
|
97
|
|
98 <para>
|
|
99 The CPU time allocation system automatically assigns programs one
|
|
100 of three "states" that describe their current status. Process
|
|
101 states are also important for coordinating process execution. A
|
|
102 process may be in one and only one state at any instant, although
|
|
103 state changes may be frequent. The states are:
|
|
104
|
|
105
|
|
106 </para>
|
|
107 <para>
|
|
108 <emphasis>ACTIVE:</emphasis>
|
|
109 processes which can currently perform useful processing.
|
|
110 These are the only processes assigned CPU time.
|
|
111 </para>
|
|
112 <para>
|
|
113 <emphasis>WAITING:</emphasis>
|
|
114 processes which have been suspended until another process
|
|
115 terminates. This state is used to coordinate execution of
|
|
116 sequential programs. The shell, for example, will be in the waiting
|
|
117 state during the time a command program it has initiated is running.
|
|
118
|
|
119 </para>
|
|
120 <para>
|
|
121 <emphasis>SLEEPING:</emphasis>
|
|
122 processes suspended by self-request for a specified time
|
|
123 interval or until receipt of a "signal". Signals are internal
|
|
124 messages used to coordinate concurrent processes. This is the
|
|
125 typical state of programs which are waiting for input/output
|
|
126 operations.
|
|
127
|
|
128 </para>
|
|
129 <para>
|
|
130
|
|
131 Sleeping and waiting processes are not given CPU time until they
|
|
132 change to the active state.
|
|
133 </para>
|
|
134 </section>
|
|
135
|
|
136 <section>
|
|
137 <title>Creation of New Processes</title>
|
|
138
|
|
139 <para>
|
|
140 The sequence of operations required to create a new process and
|
|
141 initially allocate its resources (especially memory) are
|
|
142 automatically performed by OS-9's "fork" function. If for any
|
|
143 reason any part of the sequence cannot be performed the fork is
|
|
144 aborted and the prospective parent is passed an appropriate error
|
|
145 code. The most frequent reason for failure is unavailablity of
|
|
146 required resources (especially memory) or when the program specified
|
|
147 to be run cannot be found. A process can create many new processes,
|
|
148 subject only to the limitation of the amount of unassigned memory
|
|
149 available.
|
|
150 </para>
|
|
151 <para>
|
|
152 When a process creates a new process, the creator is called the
|
|
153 "parent process", and the newly created process is called the "child
|
|
154 process". The new child can itself become a parent by creating yet
|
|
155 another process. If a parent process creates more than one child
|
|
156 process, the children are called "siblings" with respect to each
|
|
157 other. If the parent/child relationship of all processes in the
|
|
158 system is examined, a hierarchical lineage becomes evident. In
|
|
159 fact, this hierarchy is a tree structure that resembles a family
|
|
160 tree. The "family" concept makes it easy to describe relationships
|
|
161 between processes, and so it is used extensively in descriptions of
|
|
162 OS-9's multiprogramming operations.
|
|
163 </para>
|
|
164 <para>
|
|
165 When the parent issues a fork request to OS-9, it must specify
|
|
166 the following required information:
|
|
167 </para>
|
|
168 <itemizedlist mark="square">
|
|
169 <listitem><para>
|
|
170 A PRIMARY MODULE, which is the name of the program to be
|
|
171 executed by the new process. The program can already be present
|
|
172 in memory, or OS-9 may load it from a mass storage file having
|
|
173 the same name (see 5.4.1).
|
|
174 </para></listitem>
|
|
175 <listitem><para>
|
|
176 PARAMETERS, which is data specified by the parent to be
|
|
177 passed to and used by the new process. This data is copied to
|
|
178 part of the child process' memory area. Parameters are
|
|
179 frequently used to pass file names, initialization values, etc.
|
|
180 The shell, passes command line parameters this way (see 4.1).
|
|
181 </para></listitem>
|
|
182 </itemizedlist>
|
|
183 <para>
|
|
184 The new process also "inherits" copies of certain of its parent's
|
|
185 properties. These are:
|
|
186 </para>
|
|
187 <itemizedlist mark="square">
|
|
188 <listitem><para>
|
|
189 A USER NUMBER which is used by the file security system and
|
|
190 is used to identify all processes belonging to a specific user
|
|
191 (this is not the same as the "process ID", which identifies a
|
|
192 specific process) . This number is usually obtained from the
|
|
193 system password file when a user logs on. The system manager
|
|
194 always is user number zero (see 3.8).
|
|
195 </para></listitem>
|
|
196 <listitem><para>
|
|
197 STANDARD INPUT AND OUTPUT PATHS: the three paths (input,
|
|
198 output, and error/status) used for routine input and output.
|
|
199 Note that most paths (files) may be shared simultaneously by
|
|
200 two or more processes (see 4.2.2). The two current working
|
|
201 directories are also inherited.
|
|
202 </para></listitem>
|
|
203 <listitem><para>
|
|
204 PROCESS PRIORITY which determines what proportion of CPU
|
|
205 time the process receives with respect to others (see 5.1).
|
|
206 </para></listitem>
|
|
207 </itemizedlist>
|
|
208 <para>
|
|
209 As part of the fork operation, OS-9 automatically assigns:
|
|
210 </para>
|
|
211 <itemizedlist mark="square">
|
|
212 <listitem><para>
|
|
213 A PROCESS ID: a number from 1 to 255, which is used to
|
|
214 identify specific processes. Each process has a unique process
|
|
215 ID number (see 4.3.2).
|
|
216 </para></listitem>
|
|
217 <listitem><para>
|
|
218 MEMORY: enough memory required for the new process to run.
|
|
219 Level Two systems give each process a unique "address space".
|
|
220 In Level One systems, all processes share the single address
|
|
221 space. A "data area", used for the program's parameters,
|
|
222 variables, and stack is allocated for the process' exclusive
|
|
223 use. A second memory area may also be required to load the
|
|
224 program (primary module) if it is not resident in memory (see 5.4)..
|
|
225 </para></listitem>
|
|
226 </itemizedlist>
|
|
227 <para>
|
|
228 To summarize, the following items are given to or associated with
|
|
229 new processes:
|
|
230 </para>
|
|
231
|
|
232 <itemizedlist mark="square">
|
|
233 <listitem><para>
|
|
234 Primary Module (program module to be run)
|
|
235 </para></listitem>
|
|
236 <listitem><para>
|
|
237 Parameter(s) passed from parent to child
|
|
238 </para></listitem>
|
|
239 <listitem><para>
|
|
240 User Number
|
|
241 </para></listitem>
|
|
242 <listitem><para>
|
|
243 Standard I/O paths and working directories
|
|
244 </para></listitem>
|
|
245 <listitem><para>
|
|
246 Process Priority
|
|
247 </para></listitem>
|
|
248 <listitem><para>
|
|
249 Process ID
|
|
250 </para></listitem>
|
|
251 <listitem><para>
|
|
252 Memory
|
|
253 </para></listitem>
|
|
254 </itemizedlist>
|
|
255
|
|
256 </section>
|
|
257
|
|
258 <section>
|
|
259 <title>Basic Memory Management Functions</title>
|
|
260 <para>
|
|
261 An important OS-9 function is memory management. OS-9 automatically allocates
|
|
262 all system memory to itself and to processes, and
|
|
263 also keeps track of the logical <emphasis>contents</emphasis>
|
|
264 of memory (meaning which
|
|
265 program modules are resident in memory at any given time). The
|
|
266 result is that you seldom have to be bothered with the actual memory
|
|
267 addresses of programs or data.
|
|
268 </para>
|
|
269 <para>
|
|
270 Within the address space, memory is assigned from higher
|
|
271 addresses downward for program modules, and from lower addresses
|
|
272 upward for data areas, as shown below:
|
|
273 </para>
|
|
274 <screen>
|
|
275 +---------------------------+ highest address
|
|
276 ! program modules !
|
|
277 ! (RAM or ROM) !
|
|
278 ! !
|
|
279 ! - - - - - - - - - - - - - !
|
|
280 ! !
|
|
281 ! unused space !
|
|
282 ! (RAM or empty) !
|
|
283 ! !
|
|
284 ! - - - - - - - - - - - - - !
|
|
285 ! !
|
|
286 ! data areas !
|
|
287 ! (RAM) !
|
|
288 ! !
|
|
289 +---------------------------+ lowest address (0)
|
|
290 </screen>
|
|
291 <section>
|
|
292 <title>Loading Program Modules Into Memory</title>
|
|
293
|
|
294 <para>
|
|
295 When performing a fork operation, OS-9's first step is to attempt
|
|
296 to locate the requested program module by searching the "module
|
|
297 directory", which has the address of every module present in memory.
|
|
298 The 6809 instruction set supports a type of program called
|
|
299 "reentrant code" which means the exact same "copy" of a program can
|
|
300 be shared by two or more different processes simultaneously without
|
|
301 affecting each other, provided that each "incarnation" of the
|
|
302 program has am independent memory area for its variables.
|
|
303 </para>
|
|
304 <para>
|
|
305 Almost all OS-9 family software is reentrant and can make most
|
|
306 efficient use of memory. For example, Basic09 requires 22K bytes of
|
|
307 memory to load into. If a request to run Basic09 is made, but
|
|
308 another user (process) had previously caused it to be loaded into
|
|
309 memory, both processes will share the same copy, instead of causing
|
|
310 another copy to be loaded (which would use an additional 22K of
|
|
311 memory). OS-9 automatically keeps track of how many processes are
|
|
312 using each program module and deletes the module (freeing its memory
|
|
313 for other uses) when all processes using the module have terminated.
|
|
314 </para>
|
|
315 <para>
|
|
316 If the requested program module is not already in memory, the
|
|
317 name is used as a pathlist (file name) and an attempt is made to
|
|
318 load the program from mass storage (see 3.9.4).
|
|
319 </para>
|
|
320 <para>
|
|
321 Every program module has a "module header" that describes the
|
|
322 program and its memory requirements. OS-9 uses this to determine
|
|
323 how much memory for variable storage should be allocated to the
|
|
324 process (it can be given more memory by specifying an optional
|
|
325 parameter on the shell command line). The module header also
|
|
326 includes other important descriptive information about the program,
|
|
327 and is an essential part of OS-9 operation at the machine language
|
|
328 level. A detailed description of memory modules and module headers
|
|
329 can be found in the "OS-9 System Programmer's Manual".
|
|
330 </para>
|
|
331 <para>
|
|
332 Programs can also be explicitly loaded into memory using the
|
|
333 "load" command. As with fork, the program will actually be loaded
|
|
334 only if it is not already in memory. If the module is not in
|
|
335 memory, OS-9 will copy a candidate memory module from the file into
|
|
336 memory, verify the CRC, and then, if the module is not already in
|
|
337 the module directory, add the module to the directory. This process
|
|
338 is repeated until all the modules in the file are loaded, the 64K
|
|
339 memory limit is exceeded, or until a module with an invalid format
|
|
340 is encountered. OS-9 always links to the first module read from the
|
|
341 file.
|
|
342 </para>
|
|
343 <para>
|
|
344 If the program module <emphasis>is</emphasis> already in memory,
|
|
345 the load will proceed
|
|
346 as described above, loading the module from the specified file,
|
|
347 verifying the CRC, and when attempting to add the valid module to
|
|
348 the module directory, noticing that the module is already known, the
|
|
349 load merely increments the known module's link count (the number of
|
|
350 processes using the module.) The load command can be used to "lock
|
|
351 a program into memory. This can be useful if the same program is to
|
|
352 be used frequently because the program will be kept in memory
|
|
353 continuously, instead of being loaded repeatedly.
|
|
354 </para>
|
|
355 <para>
|
|
356 The opposite of "load" is the "unlink" command, which decreases a
|
|
357 program module's link count by one. Recall that when this count becomes zero
|
|
358 (indicating the module in no longer used by any process),
|
|
359 the module is deleted, e.g., its memory is deallocated and its name
|
|
360 is removed from the module directory. The "unlink" command is
|
|
361 generally used in conjunction with the "load" command (programs
|
|
362 loaded by fork are automatically unlinked when the program
|
|
363 terminates).
|
|
364 </para>
|
|
365 <para>
|
|
366 Here is an example of the use of
|
|
367 "load" and "unlink" to lock a
|
|
368 program in memory. Suppose the "copy" command will be used five
|
|
369 times. Normally, the copy command would be loaded each time the
|
|
370 "copy" command is called. If the "load" command is used first,
|
|
371 "copy" will be locked into memory first, for example:
|
|
372 </para>
|
|
373 <screen>
|
|
374 OS9: load copy
|
|
375 OS9: copy file1 file1a
|
|
376 OS9: copy file2 file2a
|
|
377 OS9: copy file3 file3a
|
|
378 OS9: unlink copy
|
|
379 </screen>
|
|
380 <para>
|
|
381 It is important to use the "unlink" command after the program is no
|
|
382 longer needed, or the program will continue to occupy memory which
|
|
383 otherwise could be used for other purposes. Be very careful
|
|
384 <emphasis>not</emphasis> to
|
|
385 completely unlink modules in use by any process! This will cause the
|
|
386 memory used by the module to be deallocated and its contents
|
|
387 destroyed. This will certainly cause all programs using the
|
|
388 unlinked module to crash.
|
|
389 </para>
|
|
390 </section>
|
|
391
|
|
392 <section>
|
|
393 <title>Loading Multiple Programs</title>
|
|
394
|
|
395 <para>
|
|
396 Another important aspect of program loading is the ability to
|
|
397 have two or more programs resident in memory at the same time. This
|
|
398 is possible because all OS-9 program modules are "position-independent
|
|
399 code", or "PIC". PIC programs do not have to be loaded into
|
|
400 specific, predetermined memory addresses to work correctly, and can
|
|
401 therefore be loaded at different memory addresses at different
|
|
402 times. PIC programs require special types of machine language instructions
|
|
403 which few computers have. The ability of the 6809
|
|
404 microprocessor to use this type of program is one of its most
|
|
405 powerful features.
|
|
406 </para>
|
|
407 <para>
|
|
408 The "load" command can therefore be used two or more times (or a
|
|
409 single file may contain several memory modules, see 3.9.4), and each
|
|
410 program module will be automatically loaded at different,
|
|
411 non-overlapping addresses (most other operating systems write over the
|
|
412 previous program's memory whenever a new program is loaded). This
|
|
413 technique also relieves the user from having to be directly concerned with
|
|
414 absolute memory addresses. Any number of program modules
|
|
415 can be loaded until available system memory is full.
|
|
416 </para>
|
|
417 </section>
|
|
418
|
|
419 <section>
|
|
420 <title>Memory Fragmentation</title>
|
|
421
|
|
422 <para>
|
|
423 Even though PIC programs can be initially loaded at any address
|
|
424 where free memory is available, program modules cannot be relocated
|
|
425 dynamically afterwards, e.g., once a program is loaded it must
|
|
426 remain at the address at which it was originally loaded (however
|
|
427 Level Two systems can "load" (map) memory resident programs at
|
|
428 different addresses in each process' address space). This characteristic
|
|
429 can lead to a sometimes troublesome phenomenon called
|
|
430 "memory fragmentation". When programs are loaded, they are assigned
|
|
431 the first sufficiently large block of memory at the highest address
|
|
432 possible in the address space. If a number of program modules are
|
|
433 loaded, and subsequently one or more modules which are located in
|
|
434 between other modules are "unlinked", several fragments of free
|
|
435 memory space will exist. The sum of the sizes of the free memory
|
|
436 space may be quite large, but because they are scattered, not enough
|
|
437 space will exist in a single block to load a program module larger
|
|
438 than the largest free space.
|
|
439 </para>
|
|
440 <para>
|
|
441 The "mfree" command shows the location and size of each unused
|
|
442 memory area and the "mdir e" command shows the address, size, and
|
|
443 link (use) count of each module in the address space. These
|
|
444 commands can be used to detect fragmentation. Memory can usually be
|
|
445 de-fragmemted by unlinking scattered modules and reloading them.
|
|
446 <emphasis>Make certain</emphasis> none are in use before doing so.
|
|
447 </para>
|
|
448 </section>
|
|
449 </section>
|
|
450 </chapter>
|