Mercurial > hg > Members > kono > nitros9-code
annotate docs/nitros9guide/chap5.chapter @ 2112:cfb3a637a000
Fixed lack of H6309 flag
author | boisy |
---|---|
date | Tue, 21 Aug 2007 17:05:14 +0000 |
parents | b00cf13c9f61 |
children |
rev | line source |
---|---|
145 | 1 <chapter> |
2 <title>Multiprogramming and Memory Management</title> | |
3 <para> | |
1500 | 4 One of NitrOS-9's most extraordinary abilities is multiprogramming, |
145 | 5 which is sometimes called timesharing or multitasking. Simply |
1500 | 6 states, NitrOS-9 lets you computer run more than one program at the same |
145 | 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> | |
1500 | 14 NitrOS-9 uses this capability all the time for internal functions. |
145 | 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 | |
1500 | 21 an insight into how NitrOS-9 performs this amazing feat. You certainly |
145 | 22 don't have to know every detail of how multiprogramming works in |
1500 | 23 order to use NitrOS-9, but a basic working knowledge can help you |
145 | 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 | |
1500 | 28 without interference, NitrOS-9 must perform many coordination and |
145 | 29 resource allocation functions. The major system resources managed |
1500 | 30 by NitrOS-9 are: |
145 | 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. | |
1500 | 40 Therefore, NitrOS-9 uses many techniques and strategies to optimize |
145 | 41 system throughput and capacity. |
42 </para> | |
43 | |
1093 | 44 <section id="sec5.1"> |
145 | 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 | |
1500 | 56 operating system such as NitrOS-9 automatically assigns CPU time to only |
145 | 57 those programs that can effectively use the, time. |
58 </para> | |
59 <para> | |
1500 | 60 NitrOS-9 uses a technique called <emphasis>timeslicing</emphasis> which allows processes |
145 | 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 | |
1500 | 72 than they ordinarily do. At any occurrence of a tick, NitrOS-9 can suspend |
145 | 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 | |
1093 | 95 <section id="sec5.2"> |
145 | 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 | |
1093 | 136 <section id="sec5.3"> |
145 | 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 | |
1500 | 142 automatically performed by NitrOS-9's "fork" function. If for any |
145 | 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 | |
1500 | 162 NitrOS-9's multiprogramming operations. |
145 | 163 </para> |
164 <para> | |
1500 | 165 When the parent issues a fork request to NitrOS-9, it must specify |
145 | 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 | |
1500 | 172 in memory, or NitrOS-9 may load it from a mass storage file having |
1011 | 173 the same name. |
145 | 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. | |
1011 | 180 The shell, passes command line parameters this way. |
145 | 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 | |
1011 | 194 always is user number zero. |
145 | 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 | |
1011 | 200 two or more processes. The two current working |
145 | 201 directories are also inherited. |
202 </para></listitem> | |
203 <listitem><para> | |
204 PROCESS PRIORITY which determines what proportion of CPU | |
1011 | 205 time the process receives with respect to others. |
145 | 206 </para></listitem> |
207 </itemizedlist> | |
208 <para> | |
1500 | 209 As part of the fork operation, NitrOS-9 automatically assigns: |
145 | 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 | |
1011 | 215 ID number. |
145 | 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 | |
1011 | 224 program (primary module) if it is not resident in memory. |
145 | 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 | |
1093 | 258 <section id="sec5.4"> |
145 | 259 <title>Basic Memory Management Functions</title> |
260 <para> | |
1500 | 261 An important NitrOS-9 function is memory management. NitrOS-9 automatically allocates |
145 | 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> | |
1093 | 291 <section id="sec5.4.1"> |
145 | 292 <title>Loading Program Modules Into Memory</title> |
293 | |
294 <para> | |
1500 | 295 When performing a fork operation, NitrOS-9's first step is to attempt |
145 | 296 to locate the requested program module by searching the "module |
297 directory", which has the address of every module present in memory. | |
1014
d9ed9d44b70c
Some character entities had missing semicolons. It's &CPU;
roug
parents:
1011
diff
changeset
|
298 The &CPU; instruction set supports a type of program called |
145 | 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> | |
1500 | 305 Almost all NitrOS-9 family software is reentrant and can make most |
145 | 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 | |
1500 | 311 memory). NitrOS-9 automatically keeps track of how many processes are |
145 | 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 | |
1011 | 318 load the program from mass storage. |
145 | 319 </para> |
320 <para> | |
321 Every program module has a "module header" that describes the | |
1500 | 322 program and its memory requirements. NitrOS-9 uses this to determine |
145 | 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, | |
1500 | 327 and is an essential part of NitrOS-9 operation at the machine language |
145 | 328 level. A detailed description of memory modules and module headers |
1500 | 329 can be found in the "NitrOS-9 System Programmer's Manual". |
145 | 330 </para> |
331 <para> | |
332 Programs can also be explicitly loaded into memory using the | |
1053
b5ff125a1d60
Since this book was only typeset in fixed width, single-font, they used
roug
parents:
1014
diff
changeset
|
333 <command>load</command> command. As with fork, the program will actually be loaded |
145 | 334 only if it is not already in memory. If the module is not in |
1500 | 335 memory, NitrOS-9 will copy a candidate memory module from the file into |
145 | 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 | |
1500 | 340 is encountered. NitrOS-9 always links to the first module read from the |
145 | 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> | |
1053
b5ff125a1d60
Since this book was only typeset in fixed width, single-font, they used
roug
parents:
1014
diff
changeset
|
356 The opposite of <command>load</command> is the <command>unlink</command> command, which decreases a |
145 | 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 | |
1053
b5ff125a1d60
Since this book was only typeset in fixed width, single-font, they used
roug
parents:
1014
diff
changeset
|
360 is removed from the module directory. The <command>unlink</command> command is |
b5ff125a1d60
Since this book was only typeset in fixed width, single-font, they used
roug
parents:
1014
diff
changeset
|
361 generally used in conjunction with the <command>load</command> command (programs |
145 | 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 | |
1053
b5ff125a1d60
Since this book was only typeset in fixed width, single-font, they used
roug
parents:
1014
diff
changeset
|
367 <command>load</command> and <command>unlink</command> to lock a |
b5ff125a1d60
Since this book was only typeset in fixed width, single-font, they used
roug
parents:
1014
diff
changeset
|
368 program in memory. Suppose the <command>copy</command> command will be used five |
145 | 369 times. Normally, the copy command would be loaded each time the |
1053
b5ff125a1d60
Since this book was only typeset in fixed width, single-font, they used
roug
parents:
1014
diff
changeset
|
370 <command>copy</command> command is called. If the <command>load</command> command is used first, |
b5ff125a1d60
Since this book was only typeset in fixed width, single-font, they used
roug
parents:
1014
diff
changeset
|
371 <command>copy</command> will be locked into memory first, for example: |
145 | 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> | |
1053
b5ff125a1d60
Since this book was only typeset in fixed width, single-font, they used
roug
parents:
1014
diff
changeset
|
381 It is important to use the <command>unlink</command> command after the program is no |
145 | 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 | |
1093 | 392 <section id="sec5.4.2"> |
145 | 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 | |
1500 | 398 is possible because all NitrOS-9 program modules are "position-independent |
145 | 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 | |
1014
d9ed9d44b70c
Some character entities had missing semicolons. It's &CPU;
roug
parents:
1011
diff
changeset
|
403 which few computers have. The ability of the &CPU; |
145 | 404 microprocessor to use this type of program is one of its most |
405 powerful features. | |
406 </para> | |
407 <para> | |
1053
b5ff125a1d60
Since this book was only typeset in fixed width, single-font, they used
roug
parents:
1014
diff
changeset
|
408 The <command>load</command> command can therefore be used two or more times (or a |
1011 | 409 single file may contain several memory modules), and each |
145 | 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 | |
1093 | 419 <section id="sec5.4.3"> |
145 | 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> | |
1053
b5ff125a1d60
Since this book was only typeset in fixed width, single-font, they used
roug
parents:
1014
diff
changeset
|
441 The <command>mfree</command> command shows the location and size of each unused |
1500 | 442 memory area and the <command>mdir -e</command> command shows the address, size, and |
145 | 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> |