Reading
Read Chapters 1-3
Course Introduction
The first half of today's lecture was spent discussing the content of the course syllabus and the course schedule.I think everything we covered is available in those documents, so take a look there for the notes. Please let me , or all of us know if you have any questions, concerns, &c -- we're here to help!
Photographs
On the way out, we photographed each person with a sign showing her/his name. These photos will be posted on a password-protected portion of the course web site. This site will be restricted using Andrew userids and passwords to only those who are enrolled in the course. Please remember that you are not permitted to redistribute those images or any part thereof (except your own picture) without our permission.If you were not able to attend today, please e-mail staff-412@cs to arrange to have your picture taken. Thanks.
What Is An Operating System?
So, why are we here? We're here to study "Operating Systems", but what are they?We chatted about this for a few minutes in class and decided that operating systems are software systems that manage the hardware (and other resources) to provide a convenient, efficient, and safe environment for processes. We also talked a little bit about the need for robustness (although we didn't use that word, specifically).
Perhps the role of operating systems can be best understood by taking a look at their history and evolution over time.
Early Systems (late 1940's - early 1950's)
There were no operating systems. Computers filled an entire room. Scientists would sign up for time. During their scheduled time, they would enter their program into the computer using binary switches. If they needed less time than they reserved, the extra time would be wasted. If they needed more time than they reserved, they had to sign up again. Some time was wasted because it was at undesirable times of the day (or night).
Input to the systems changed and became more efficient: punch cards, tapes, &c were used. Control cards were required to describe the use of hardware by the programs. typically the first control card would tell the system how to read the next cards. The first card was the loader, followed by the program, followed by the data.
But there were still problems with overbooked, underbooked, and unused time slots. And time was wasted shuffling cards. The decks often had to be changed. Consider multi-pass assemblers where the source code had to be reprocessed with the output from prior stages of the assembler. Time was wasted shuffling cards.
One improvement was the professional operator. The operator was more skilled than the scientist in handling the cards. Less time was wasted in handling the cards and time wasn't lost between jobs. When one job ended, the next could be loaded immediately. Some repetative card-reading became unnecessary, because several jobs using the same code could be run as a batch. If three jobs needed to assemble code, the 1st pass could be run on all three jobs, and then the second pass on all three jobs.
Simple Batch Systems (early 1950's - 1960's) -- The Resident Monitor
The resident monitor is a rudimentary and primitive forerunner of modern-day operating systems. It was in some sense a software implementation of the human operator that, after it was loaded, remained in memory and ran jobs. The resident monitor also managed the I/O devices, such as the card reader and card punch and could speed the time between jobs (no human delay).
Multiprogramming (1960's - present)
Multiprogramming allows different users to execute jobs simultaneously.
Why would we we want to run multiple jobs simultaneously? This wastes time switching between processes (context-switch). The answer is that it allows one job to take advantage of the CPU, while another is not using the CPU, becuase it is waiting for an I/O device to store/retrieve data.
But this approach requires that several programs be loaded in memory at a time, as well as the memory manager. It also requires some accouting and better protections.
Timesharing Systems (debut early 1960's, common by 1970's)
The first popular time sharing system was a CMU favorite, UNIX. Before time sharing, separate jobs could run, but they were batched. The user would leave his/her card deck with the operator and wave goodbye. The user could pickup the output, after the job finished.
Timesharing allows the user to interact with the program during execution at the same time it allows multiple jobs to run at the same time. The user can interact and react, control the path of the program, and perform interactive debugging. Windowing systems, &c were developed to improve the look and feel of the interaction.
This is achieved by sharing the resources (like the CPU) among the jobs. Provided the CPU (and other resources) are fast enough, the user can view the entire system as their own. Performance is measured in terms of response time, the length of time between the start of a job and the first output.
Utilization is still a problem. Consider how much fast CPU time a slow user could waste if the CPU waited for she/he to enter information at the keyboard. Other jobs must run during this time. Overhead is also added switching between jobs when it is not mandated by I/O, but is instead required to share the resources among the jobs.
Hardware Overview
I'm sure that many of you have discussed the logical organization of a computer's hardware in previous classes, but I'd like to do a quick overview today -- just to make sure that we're all on the same page.Components
We can think of a computer as a collection of components connected via a collection of wires known as the bus. You can think of the bus as a perfect network -- no errors, no congestion, no failure. The components on this bus might include the following:
- CPU -- One or more of these processors can exist in the same computer. They are ultimately responsible for executing programs. Traditionally CPUs perform arithmetic and logical operations. But some CPUs can perform very complex operations. In any case, it is ultimately the operations performed by the processor that control I/O devices, and other system functions.
- Volatile Random Access Memory (RAM) -- addressable storage that loses its contents when power is lost.
- Memory Controller -- The logic that acts as an interface between the memory and the CPU/devices accessing it. Among other things, the memory controller is necessary to ensure that individual memory accesses remain atomic in the presence of multiple users (multiple CPUs, DMA-based I/O, &c).
- I/O Controllers -- The interface between the CPU/devices and a device. In addition to providing the electronic and logical interface to I/O devices, I/O controllers often perform tasks like buffering, queing, and scheduling. Disk controllers are a common and important type of I/O controller. Others might include the UARTs that drive serial ports, &c.
- I/O devices -- devices like keyboard, disk drives, scanners, mice, &c
- A Timer -- we'll discuss this special device shortly.
![]()
Memory Hierarchy
The next thing I'd like you to remember from a prior class is the storage hierarchy. Computers contain several different types of memory. Faster memory is often more expensive, so less of it is available. Slower memory is often more plentifully available. It is the goal of the system to use faster memory as often as possible. To achieve this goal, the system tries to keep the items that will be used sooner in faster memory. Often times this involves using some policy to estimate what is likely to be used next -- one common policy is to kee the most recently used items in the fastest memory, assuming that they are most likely to be used again soon.
There are several different types of memory in a system. As we move down in this list, we are moving to slower memories that are typically more plentifully available because of a lower cost per unit:
- registers -- very small units of memory built into the CPU itself that operate at the same speed as the CPU
- L1 cache -- memory that is slightly slower than the CPU that is typically separate from the CPU but part of the same package.
- L2 cache -- memory that is slower than the L1 cache, but faster than main memory. It is usually not part of the CPU's package, but it can be.
- Main memory -- The slowest RAM in the system -- but much faster than the next level.
- disk -- once used only for "external" or "offline" storage, the existence of demand paging and demand segmentation has turned disk into a massive, but slow secondary RAM. It is also often used for non-volatile storage in portable devices.
Typically, the program manages the registers through instructions that direct the CPU when to load and store values into/out of RAM. The caches are usually managed by hardware that uses a policy such as LRU with write-back or write-through to decide when to read or write values into main memory. Caches are invisible from the software side of things, except for the impact of misses on performance -- and the possible need to flush them upon context-switch. The operating system is generally responsible for the movement of information between main memory and disk -- consequently, it is this part of the hierarchy that we will study in the greatest depth this semester.
A Special I/O device: The Timer
Consider this: When the CPU is executing a particular program, the PC is moving through that program from one instruction to the next, unless the program, through a branch, instructs it to do something else. In a time sharing environment, for example, the OS might want to regularly switch among tasks in order to appear responsive to all users. But if one program is running, how is the OS to get control?One approach to this is for all programs to regularly invoke the operating system by making a system call. In this way, programs could periodically yield to the OS, allowing the OS to dispatch another program. Windows 3.x used this approach caled non-preemptive multitasking. Programmers would periodically include the yield() call in their code. This would invoke the OS's scheduler, which might schedule another task to run.
But this approach was far from perfect. One problem involves a program that "runs away" executing some loop endlessly -- the OS can never get control to let anything else run. The other problem is that the more frequently a program yielded to the OS, the less cycles it might get. In the competitive environment in which software is written, some programmers might be tempted to yield less frequently (of course, this could be punished by the scheduler when they finally did yield).
Do you remember before when mentioned the timer device? I told you it was special and that we'd talk about it later. Modern computers include hardware timers, becuase they give the OS another way of getting control of the CPU. The timer device is basically a count-back timer, much like one would you might use to measure a cooking time (like an hour-glass egg time), or to enforce a time limit for a sporting event. The timer has a register that is initiallized, usually at boot time, to a particular value. It counts back from this value to 0 at which time it interrupts the CPU. The interval between timer interrupts is known as a time quantum. A typical quantum might be about 10mS.
Using this approach, a particular job is left to run for up to one quantum, at whcih time the timer interrupt goes off and the OS's scheduler is invoked via the timer's ISR. At this time the same job, or another job might be dispatched to the CPU.
It is important to note that jobs don't always execute for an entire quantum without interruption. Sometimes they perform I/O or do something else that temporarily prevents them from making use of the CPU. Often times libraries are written such that the call yields immediately after dispatching such a request, often called a blocking operation. We'll talk about this more soon.
Looking Ahead
We'll pick up next class with Project #2 and then we'll continue the hardware discussion by talking about how devices get the attention of the processor. Specifically, we'll discuss polling and interrupts.