Operating Systems Flash Cards

¡Supera tus tareas y exámenes ahora con Quizwiz!

UNIX

An operating system originally conceived in 1969 by Ken Thompson and Dennis Ritchie of AT&T's Bell Labs. In 1974, the UNIX code was rewritten in the standard programming language C. Today there are various commercial versions of UNIX. Open source, multi-user, multi-tasking.

File Descriptor

Before a file can be read or written, it must be opened, at which time the permissions are checked. If the access is permitted, the system returns a small integer called a file descriptor to use in subsequent operations. If the access is prohibited, an error code is returned.

6 OS Designs

1. Monolithic 2. Layered 3. Microkernels 4. Client-server 5. Virtual machines 6. Exokernels

Child Process

A process (parent) can create one or more other processes (referred to as child processes) and these processes in turn can create child processes.

Disabling Interrupts

A way to avoid two processes being in a critical section at the same time. Not a good solution.

Process Table

All the information about each process, other than the contents of its own address space, is stored in an operating system table called the process table, which is an array of structures, one for each process currently in existence.

Shared Bus Architecture

Multiple devices use the same wires to transfer data. Thus, when multiple devices have data to send, you need an arbiter to determine who can use the bus.

Multiplexing

Sharing resources in two different ways - in time and space. Time multiplexing is used for the CPU, space multiplexing is used for memory.

Memory Hierarchy

A structure that uses multiple levels of memories; as the distance from the processor increases, the size of the memories and the access time both increase. Fast memory close to CPU is more expensive.

PSW

Program Status Word. Register condition variable that indicates to the CPU what mode (kernel or user) instructions need to be carried out in.

Device Drivers

Utility software used by the operating system to communicate with peripheral devices. Written by hardware manufacturers. Provides function for OS to call to access device.

Process vs Thread

A process is an executing instance of an application. A thread is a path of execution within a process.

Degree of Multiprogramming

Number of processes in memory.

Running State

Once the processor becomes available, the process is going to move from the ready state into the running state and then it will actually be running on the processor and doing some real work. This is called a dispatch operation. Once the processor either times out, or the process makes a blocking system call, or the process ends altogether, the process is going to stay in the running state until one of those three things happens and then it's going to move to the ready state, the block state, or the exit state accordingly.

Preemption

The operating system will be responsible for stopping and restarting running programs and this is what we call preemption.

Kernel Mode

The operating system, the most fundamental piece of software, runs in kernel mode (also called supervisor mode). In this mode it has complete access to all the hardware and can execute any instruction the machine is capable of executing.

5 Generations of OS's

1. Vaccuum Tubes (1945-1955) 2. Transistors and Batch Systems (1955-1965) 3. ICs and Multiprogramming (1965-1980) 4. Personal Computers (1980-Present) 5. Mobile Computers (1990-Present)

Graphical Processing Unit (GPU)

A GPU is a processor with, literally, thousands of tiny cores. They are very good for many small computations done in parallel, like rendering polygons in graphics applications. They are not so good at serial tasks. They are also hard to program. While GPUs can be useful for operating systems (e.g., encryption or processing of network traffic), it is not likely that much of the operating system itself will run on the GPUs.

State

A condition that a program might be in and the process is going to spend quite a significant amount of time in each state. So each state has to be recognized and has to be recorded by the operating system.

User Level Threads

A leftover of a bygone era although that still very much in use today. The biggest downside of a user level thread is that the OS doesn't recognize that the threads are in use. There is a library of code inside our program, which creates or simulates creating of threads and switching between these threads. So, what would be required would be some scheduling algorithms and some ability to create new threads and destroy threads, inside a user's program. But all of this is a simulation and the OS doesn't really know that multiple threads, if you want to call them that, are being created here. Instead what it does is recognize that one process is being created. And the biggest downside to that is that if any of those threads, and I use quotations, those threads cause a blocking system call then all of those threads are going to be blocked because the OS just sees it as a single process. The advantage of a user level thread is that you can choose to do whatever scheduling algorithm you want; you're not at the behest of the OS. In a kernel level thread the operating system decides when your threads are going to run, but in a user level thread you, the programmer, decide when that thread is going to run and how often it's going to be run. So, you could have three threads and give priority to one of the three threads to run more frequently than the other two, and you can't do that with kernel level threads easily.

Hardware Abstraction Layer (HAL)

A low-level system driver in Windows OS that controls communication between Windows and the computer hardware. A set of functions that the kernel could call on to perform tasks on different, on the various hardware. So, rather than directly programming the timer in the system to say: let this process run for twenty milliseconds. The hardware abstraction, the operating system would call a function inside the hardware abstraction layer to say program the timer to let this process run for twenty milliseconds. And the reason that that's essential is because Microsoft can change out the HAL and produce an operating system that can now run on a completely different hardware. Without making any other changes to the operating system, it can change just the functions inside the HAL and those functions will, those features will take effect on the new hardware.

Process & Address Space

A process is basically a program in execution. The most central concept in any operating system is the process: an abstraction of a running program. Everything else hinges on this concept, and the operating system designer (and student) should have a thorough understanding of what a process is as early as possible. Processes are one of the oldest and most important abstractions that operating systems provide. They support the ability to have (pseudo) concurrent operation ev en when there is only one CPU available. They turn a single CPU into multiple virtual CPUs. Without the process abstraction, modern computing could not exist. A process is just an instance of an executing program, including the current values of the program counter, registers, and variables. Associated with each process is its address space, a list of memory locations from 0 to some maximum, which the process can read and write. The address space contains the executable program, the program's data, and its stack. Also associated with each process is a set of resources, commonly including registers (including the program counter and stack pointer), a list of open files, outstanding alarms, lists of related processes, and all the other information needed to run the program. A process is fundamentally a container that holds all the information needed to run a program.

Daemon

A process that performs some useful tasks in the background.

Operating System (OS)

A program that controls execution of user programs and acts as an interface between applications and computer hardware. OS have two purposes: to provide abstractions for otherwise difficult to deal with hardware; and to manage hardware resources for applications.

Program Counter

A register that contains the memory address of the next instruction to be fetched. After that instruction has been fetched, the program counter is updated to point to its successor.

Stack Pointer

A register that points to the top of the current stack in memory. The stack contains one frame for each procedure that has been entered but not yet exited. A procedure's stack frame holds those input parameters, local variables, and temporary variables that are not kept in registers.

System Call

A request to the OS - a request for an OS service. To obtain services from the operating system, a user program must make a system call, which traps into the kernel and invokes the operating system. The TRAP instruction switches from user mode to kernel mode and starts the operating system. When the work has been completed, control is returned to the user program at the instruction following the system call.

Virtual Memory

A scheme that makes it possible to run programs larger than physical memory by placing them on the disk and using main memory as a kind of cache for the most heavily executed parts. This scheme requires remapping memory addresses on the fly to convert the address the program generated to the physical address in RAM where the word is located. This mapping is done by a part of the CPU called the MMU (Memory Management Unit). If we're using a paging or segmentation system, we have to recognize that the process is only going to be making one memory reference at any given time. Now I know that's an overly simplistic view of things, it's actually going to be making a lot of memory references. But one of the things that you can see is that the memory references are all going to be pretty much clustered together. If we, for example, start a process and the process throws a splash screen up on the screen. You know starting Word or PowerPoint, that splash screen will never appear again during that run of the program. But that splash screen takes a memory, there's code that tells it how to display that splash screen, and there's the splash screen itself probably an image. So, that memory is loaded into main memory and it's never going to be used again. So the question then becomes: why should still be loaded in main memory, which is a finite quantity very much in demand, why can't we take it out of main memory and put it on the hard drive? Somewhere that we can bring it back if we ever need to, if the process never needs it again then it can just be deleted off the hard drive and never recovered. But what if the the process was never going to use that splash screen for that run of the process again. And what if we just took it out of main memory and left it on a hard drive. And if we did that we would free up some main memory a

Client-Server OS Design

A slight variation of the microkernel idea is to distinguish two classes of processes, the servers, each of which provides some service, and the clients, which use these services. This model is known as the client-server model. Often the lowest layer is a microkernel, but that is not required. The essence is the presence of client processes and server processes. Communication between clients and servers is often by message passing. To obtain a service, a client process constructs a message saying what it wants and sends it to the appropriate service. The service then does the work and sends back the answer. If the client and server happen to run on the same machine, certain optimizations are possible, but conceptually, we are still talking about message passing here. An obvious generalization of this idea is to have the clients and servers run on different computers, connected by a local or wide-area network. Since clients communicate with servers by sending messages, the clients need not know whether the messages are handled locally on their own machines, or whether they are sent across a network to servers on a remote machine. As far as the client is concerned, the same thing happens in both cases: requests are sent and replies come back. Thus the client-server model is an abstraction that can be used for a single machine or for a network of machines.

Pipe

A sort of pseudofile that can be used to connect two processes. If processes A and B wish to talk using a pipe, they must set it up in advance. When process A wants to send data to process B, it writes on the pipe as though it were an output file. In fact, the implementation of a pipe is very much like that of a file. Process B can read the data by reading from the pipe as though it were an input file. Thus, communication between processes in UNIX looks very much like ordinary file reads and writes. Stronger yet, the only way a process can discover that the output file it is writing on is not really a file, but a pipe, is by making a special system call.

Sensor-Node OS

Each sensor node is a real computer, with a CPU, RAM, ROM, and one or more environmental sensors. It runs a small, but real operating system, usually one that is event driven, responding to external events or making measurements periodically based on an internal clock. The operating system has to be small and simple because the nodes have little RAM and battery lifetime is a major issue. Also, as with embedded systems, all the programs are loaded in advance; users do not suddenly start programs they downloaded from the Internet, which makes the design much simpler. TinyOS is a well-known operating system for a sensor node.

Embedded OS

Embedded systems run on the computers that control devices that are not generally thought of as computers and which do not accept user-installed software. Typical examples are microwave ovens, TV sets, cars, DVD recorders, traditional phones, and MP3 players. The main property which distinguishes embedded systems from handhelds is the certainty that no untrusted software will ever run on it. You cannot download new applications to your microwave oven—all the software is in ROM. This means that there is no need for protection between applications, leading to design simplification. Systems such as Embedded Linux, QNX and VxWorks are popular in this domain.

Supplier-Demander Problem

Aka Producer-Consumer, aka Bounded-Buffer Problem. problem). Two processes share a common, fixed-size buffer. One of them, the producer, puts information into the buffer, and the other one, the consumer, takes it out. (It is also possible to generalize the problem to have m producers and n consumers. Multiple threads running of either a supplier thread or demander thread. Think about a factory for example where things are coming off the production line there's a lot of people producing things, there's a lot of people taking those things and moving them on to the next stage in the production. This has a critical section because there are shared variables: the buffer and the buffer count. The buffer count tells us how many items there really are in the buffer. The buffer can store five hundred items. The buffer count let's say it's initialized at zero there's nothing in the buffer. When the morning starts the suppliers come in and they start producing things that go into the buffer. Now the supplier just has a simple piece of code that says as long as I'm not finished then I'll put something in the buffer. Now the reason that we have that while not done is because it's possible that the buffer is full and if the buffer is full we want this thread to just kind of pause, pause for maybe half a second and let one of the demanders take something out of the buffer so it makes space and then we can put this thing in the buffer. We can update the buffer count and then we can be finished. So the suppliers a very simple piece of code the demander is almost the same thing except it checks to see that there's actually something in the buffer. As long as there is something in the buffer we'll decrement the buffer count and return the item that was in the buffer at the position. So that's the supplier demander idea. Now we do have mu

New State

All processes start out in a new state. Now we have to recognize that the process is going to spend quite a significant amount of time in each of these states. So, why would a process spend a significant amount of time in the new state. We have to think about the process being created and the procedure that we would go through to create a process inside the operating system. And the new state is when that process is being executed by the operating system. Now one thing that we need to recognize is that a state is an atomic element. And if the operating system can complete everything atomically, then there's really no reason to have a state. So, the new state happens because the process is being created and the code for that process, one of the reasons is the code for that process will have to be loaded from a secondary storage device into main memory. And that's an IO operation and I operate generally take an enormous amount of time, and we'll see this in a later model, but for now we just say that an IO operation takes a really long time. And the operating system doesn't want to sit in wait for the IO operation to complete; it wants to go on to do other things. But it needs to keep track of where this process is in the act of creation and the way to do that is the new state. So all processes in the new state are in the act of being created and their code being loaded into main memory.

Kernel Level Threads

All the work of thread management is done by the kernel. The OS recognizes that a thread has been created and the OS will create a TCB for that thread and the OS can choose to run that thread or can choose to block that thread and all the states that go along with that thread.

Multiprocessor OS

An increasingly common way to get major-league computing power is to connect multiple CPUs into a single system. Depending on precisely how they are connected and what is shared, these systems are called parallel computers, multicomputers, or multiprocessors. They need special operating systems, but often these are variations on the server operating systems, with special features for communication, connectivity, and consistency. With the recent advent of multicore chips for personal computers, even conventional desktop and notebook operating systems are starting to deal with at least small-scale multiprocessors and the number of cores is likely to grow over time. Luckily, quite a bit is known about multiprocessor operating systems from years of previous research, so using this knowledge in multicore systems should not be hard. The hard part will be having applications make use of all this computing power. Many popular operating systems, including Windows and Linux, run on multiprocessors.

Exit State

And when it's done the process moves to the exit state. And in the exit state the process is just waiting to be cleaned up and terminated. And there's one key element that has to be returned back to the parent process, which we'll talk about later and linkages, and that is the return value. Remember return zero from int main, well that has to be given back to the parent process. And a process that in the exit state has not yet returned back its element, its return value, to the parent process and that's why we have the five states that we have.

Mounted File System

Another important concept in UNIX is the mounted file system. To provide an elegant way to deal with removable media UNIX allows the file system on the disk to be attached to the main tree. UNIX does not allow path names to be prefixed by a drive name or number; that would be precisely the kind of device dependence that operating systems ought to eliminate. Instead, the mount system call allows the file system on the disk to be attached to the root file system wherever the program wants it to be.

Trap

Any single-CPU computer can execute only one instruction at a time. If a process is running a user program in user mode and needs a system service, such as reading data from a file, it has to execute a trap instruction to transfer control to the operating system. The OS then figures out what the calling process wants by inspecting the parameters. Then it carries out the system call and returns control to the instruction following the system call. In a sense, making a system call is like making a special kind of procedure call, only system calls enter the kernel and procedure calls do not. This is a situation where the process has done something that causes it to need the OS, even though it doesn't know it needs the OS. And we can also have a blocking system call; these are obvious like the program is trying to open up a file. If the program is trying to open up a file, it's going to need to invoke components of the OS and so the responsibility switches. The process will switch to running the OS and when it does that the OS will take care of opening up the file and reading in the data. Now a process which involves quite a lot of steps, most importantly, we need to save the context of that process. We're gonna save that in the PCB. And then we need to move that PCB into the appropriate queue whether it's the blocked queue or the ready queue to indicate what we're going to next do with this process, and then we need to service whatever was requested; deal with the interrupt, deal with the blocking system call or deal with the trap. And then choose another process that's ready to run so we're going to look to the ready queue and choose one of the processes on the ready queue to move into the running state. And then we're going to actually run that new process by restoring its context.

Working Directory

At every instant, each process has a current working directory, in which path names not beginning with a slash are looked for. Processes can change their working directory by issuing a system call specifying the new working directory.

BIOS

BIOS (Basic Input Output System). The BIOS contains low-level I/O software, including procedures to read the keyboard, write to the screen, and do disk I/O, among other things. Nowadays, it is held in a flash RAM, which is nonvolatile but which can be updated by the operating system when bugs are found in the BIOS. When the computer is booted, the BIOS is started.started. It first checks to see how much RAM is installed and whether the keyboard and other basic devices are installed and responding correctly. It starts out by scanning the PCIe and PCI buses to detect all the devices attached to them. If the devices present are different from when the system was last booted, the new devices are configured. The BIOS then determines the boot device by trying a list of devices stored in the CMOS memory. The user can change this list by entering a BIOS configuration program just after booting. Typically, an attempt is made to boot from a CD-ROM (or sometimes USB) drive, if one is present. If that fails, the system boots from the hard disk. The first sector from the boot device is read into memory and executed. This sector contains a program that normally examines the partition table at the end of the boot sector to determine which partition is active. Then a secondary boot loader is read in from that partition. This loader reads in the operating system from the active partition and starts it. The operating system then queries the BIOS to get the configuration information. For each device, it checks to see if it has the device driver. If not, it asks the user to insert a CD-ROM containing the driver (supplied by the device's manufacturer) or to download it from the Internet. Once it has all the device drivers, the operating system loads them into the kernel. Then it initializes its tables, creates whatever background processes

Register

Because accessing memory to get an instruction or data word takes much longer than executing an instruction, all CPUs contain some registers inside to hold key variables and temporary results. Thus the instruction set generally contains instructions to load a word from memory into a register, and store a word from a register into memory. Other instructions combine two operands from registers, memory, or both into a result, such as adding two words and storing the result in a register or in memory.

Path Name & Root Directory

Every file within the directory hierarchy can be specified by giving its path name from the top of the directory hierarchy, the root directory. Such absolute path names consist of the list of directories that must be traversed from the root directory to get to the file, with slashes separating the components.

I/O Subsystem

Every operating system has an I/O subsystem for managing its I/O devices. Some of the I/O software is device independent, that is, applies to many or all I/O devices equally well. Other parts of it, such as device drivers, are specific to particular I/O devices.

Hardware Solutions - Mutual Exclusion

Built into the CPU. First is the disabling interrupts. Not a great idea because interrupts are a necessity. If an interrupt does occurs it means a piece of hardware needs immediate servicing. Imagine a situation where a thread disables interrupts and then crashes; the whole system is stuck you can't get out except with a big power switch. So, disabling interrupts is something that we use very sparingly. The other options are built into the instruction set on the processor. So, the first one is called a test and set where we check a memory location and change its value as a Boolean flag variable, which says that somebody is in the critical section. This is an atomic machine level instruction. So, the CPU takes control of the system bus, goes and checks the location in memory, and then if it is the zero, goes resets that value to one in one atomic instruction; nobody else will be allowed to access that memory location. So, even if we have another processor it will not be allowed access to the memory location during a test and set because it has to happen atomically. A process is allowed to go into the critical section when the variable has been tested to make sure nobody's in their critical section, and then it's set it to indicate the critical section is now occupied. If we have a failure, the thread has to pause and delay and try it again. The test and set actually works fairly well. The other option is very similar. It's called exchange. It is a very common one that we use today, in which we have a swapping of a location in main memory with that of a register. So, we can again use this is a Boolean flag variable, except now we can put a one in a particular register, call exchange for the memory location and we literally get a swap of the value in the register with the value in the memory location. So, if the memo

Monolithic OS Design

By far the most common organization, in the monolithic approach the entire OS runs as a single program in kernel mode. The OS is written as a collection of procedures, linked together into a single large executable binary program. When this technique is used, each procedure in the system is free to call any other one, if the latter provides some useful computation that the former needs. Being able to call any procedure you want is very efficient, but having thousands of procedures that can call each other without restriction may also lead to a system that is unwieldy and difficult to understand. Also, a crash in any of these procedures will take down the entire OS. To construct the actual object program of the operating system when this approach is used, one first compiles all the individual procedures (or the files containing the procedures) and then binds them all together into a single executable file using the system linker. In terms of information hiding, there is essentially none—every procedure is visible to every other procedure. Even in monolithic systems, however, it is possible to have some structure. The services (system calls) provided by the operating system are requested by putting the parameters in a well-defined place (e.g., on the stack) and then executing a trap instruction. This instruction switches the machine from user mode to kernel mode and transfers control to the operating system, shown as step 6 in Fig. 1-17. The operating system then fetches the parameters and determines which system call is to be carried out. After that, it indexes into a table that contains in slot k a pointer to the procedure that carries out system call k.

Interprocess Communication

Communication between related processes that are cooperating to get some job done to synchronize their activities with one another.

Multiprogramming

Conceptually, each process has its own virtual CPU. In reality, of course, the real CPU switches back and forth from process to process, but to understand the system, it is much easier to think about a collection of processes running in (pseudo) parallel than to try to keep track of how the CPU switches from program to program. This rapid switching back and forth is called multiprogramming.

Suspended Process

Consists of its address space, usually called the core image (in honor of the magnetic core memories used in days of yore), and its process table entry, which contains the contents of its registers and many other items needed to restart the process later.

EEPROM

EEPROM (Electrically Erasable Programmable Read-Only Memory) and flash memory are also nonvolatile, but in contrast to ROM can be erased and rewritten. However, writing them takes orders of magnitude more time than writing RAM, so they are used in the same way ROM is, only with the additional feature that it is now possible to correct bugs in programs they hold by rewriting them in the field. Flash memory is also commonly used as the storage medium in portable electronic devices. It serves as film in digital cameras and as the disk in portable music players, to name just two uses. Flash memory is intermediate in speed between RAM and disk. Also, unlike disk memory, if it is erased too many times, it wears out.

Levels - Microkernel vs. Macrokernel

Each layer provides services to the layers above. The levels above use the services of the levels below. Microkernel are the 3 needed parts for an OS: primitive processes, secondary storage, virtual memory. Primitive processes are very low level pieces of code mostly scheduling and resource management. Secondary storage used to access all the other code and components of the operating system not in main memory. Virtual memory or memory management to control what's in main memory. Macrokernel has everything else: systems communication, subsystems for getting information into and out of the computer, the file systems, etc.

Process Creation

Four principal events cause processes to be created: 1. System initialization. 2. Execution of a process-creation system call by a running process. 3. A user request to create a new process. 4. Initiation of a batch job.

Process Hierarchies

In UNIX, a process and all of its children and further descendants together form a process group. When a user sends a signal from the keyboard, the signal is delivered to all members of the process group currently associated with the keyboard (usually all active processes that were created in the current window). Individually, each process can catch the signal, ignore the signal, or take the default action, which is to be killed by the signal. In UNIX, all the processes in the whole system belong to a single tree, with init at the root. In contrast, Windows has no concept of a process hierarchy. All processes are equal. The only hint of a process hierarchy is that when a process is created, the parent is given a special token (called a handle) that it can use to control the child. However, it is free to pass this token to some other process, thus invalidating the hierarchy. Processes in UNIX cannot disinherit their children.

ROM

In addition to the main memory, many computers have a small amount of nonvolatile random-access memory. Unlike RAM, nonvolatile memory does not lose its contents when the power is switched off. ROM (Read Only Memory) is programmed at the factory and cannot be changed afterward. It is fast and inexpensive. On some computers, the bootstrap loader used to start the computer is contained in ROM. Also, some I/O cards come with ROM for handling low-level device control.

Machine Architecture

Instruction set, memory organization, I/O, and bus structure. The machine-language level is primitive and awkward to program, especially for input/output.

Atomic Instructions

Instructions that run from start to end without interruption. If there is a need for a section of code to run atomically, then that section is also a critical section, and should be protected using a mutual exclusion method.

RAM

Main memory is usually called RAM (Random Access Memory). Old-timers sometimes call it core memory, because computers in the 1950s and 1960s used tiny magnetizable ferrite cores for main memory. They hav e been gone for decades but the name persists. Currently, memories are hundreds of megabytes to several gigabytes and growing rapidly. All CPU requests that cannot be satisfied out of the cache go to main memory.

Win32 API

Microsoft has defined a set of procedures called the Win32 API (Application Programming Interface) that programmers are expected to use to get operating system services. This interface is (partially) supported on all versions of Windows since Windows 95. By decoupling the API interface from the actual system calls, Microsoft retains the ability to change the actual system calls in time (even from release to release) without invalidating existing programs.

OS as Client and Resource Manager

Most of the time the OS services client applications, but since the OS needs to run some processes for itself, it can also be its own client. Either way the OS has to manage all available hardware resources between itself and applications. Modern OS have modular designs.

Layered OS Design

OS is a hierarchy of layers, each one constructed upon the one below it.

Ready State

Once the process finishes loading and can be run, then the process moves not to the running state, unfortunately, but to the ready state. And the ready state is that point where the operating system has all the processes which actually have all their parts ready to go. These are only waiting for a processor to become available so that we can load the process onto the processor and actually let it run. Remember from our hardware discussion, that the processor is the only location where code can actually be run in the system. So, the processes that are on the ready state have everything that they need in order to run but they're not quite running yet because there's no processor available.

Program Status Word (PSW)

PSW register contains the condition code bits, which are set by comparison instructions, the CPU priority, the mode (user or kernel), and various other control bits. User programs may normally read the entire PSW but typically may write only some of its fields. The PSW plays an important role in system calls and I/O.

Process Image - PCB

Process Control Blocks. This entry contains important information about the process' state, including its program counter, stack pointer, memory allocation, the status of its open files, its accounting and scheduling information, and everything else about the process that must be saved when the process is switched from running to ready or blocked state so that it can be restarted later as if it had never been stopped. The PCB is a really critical component of the operating system; it's usually implemented as a simple struct with quite a bit of information.

PID

Process Identifier. Sixteen bits large and has to be unique for all the processes. The maximum number of processes in the system is 65,535 because that's the maximum number of process identifiers that we have.

Process Segments

Processes in UNIX have their memory divided up into three segments: the text segment (i.e., the program code), the data segment (i.e., the variables), and the stack segment. The data segment grows upward and the stack grows downward. Between them is a gap of unused address space. The stack grows into the gap automatically.

Peterson's Algorithm

Protects two threads from accessing the same resource at the same time using a Boolean flag variable. There's an array of Boolean flag variables for each of the threads and each thread sets its Boolean to true if it wanted to access its critical section. Now, unfortunately that's not enough because we're going to have to go and check the other threads flag to make sure it's not in its critical section. And we run the risk if we set our flag and then go check the other thread, that the other thread is doing exactly the same thing at the same time, and now we have both threads have their flags up and both threads think that the other thread is in it's critical section and in fact, nobody is in a critical section. So, what Peterson did to solve that problem specifically was introduce another variable he called the turn variable. So what the threads do is they offer the turn to the other thread so thread zero would offer the turn to thread one and thread one would offer the turn to thread zero. So, in that very rare situation where both threads want to access the critical section, both would raise up their flags and one would offer the turn to the other and the second one would win. So, either thread zero or thread one would be allowed access into its critical section, and then of course eventually it would unset its flag and allow the other thread to access its critical section because it no longer has its flag up. If we have more than that we have a bit of a problem, but Peterson's algorithm allows us to deal with the situation where we have two threads and we can provide mutual exclusion for those two threads using only software solutions.

Exokernal OS Design

Rather than cloning the actual machine, as is done with virtual machines, another strategy is partitioning it, in other words, giving each user a subset of the resources. Thus one virtual machine might get disk blocks 0 to 1023, the next one might get blocks 1024 to 2047, and so on. At the bottom layer, running in kernel mode, is a program called the exokernel (Engler et al., 1995). Its job is to allocate resources to virtual machines and then check attempts to use them to make sure no machine is trying to use somebody else's resources. Each user-level virtual machine can run its own operating system, as on VM/370 and the Pentium virtual 8086s, except that each one is restricted to using only the resources it has asked for and been allocated. The advantage of the exokernel scheme is that it saves a layer of mapping. In the other designs, each virtual machine thinks it has its own disk, with blocks running from 0 to some maximum, so the virtual machine monitor must maintain tables to remap disk addresses (and all other resources). With the exokernel, this remapping is not needed. The exokernel need only keep track of which virtual machine has been assigned which resource. This method still has the advantage of separating the multiprogramming (in the exokernel) from the user operating system code (in user space), but with less overhead, since all the exokernel has to do is keep the virtual machines out of each other's hair.

Server OS

Run on servers, which are either very large personal computers, workstations, or even mainframes. They serve multiple users at once over a network and allow the users to share hardware and software resources. Servers can provide print service, file service, or Web service. Internet providers run many server machines to support their customers and Websites use servers to store the Web pages and handle the incoming requests. Typical server operating systems are Solaris, FreeBSD, Linux and Windows Server 201x.

Time Sharing & Multitasking

So the operating system does this (preemption - stopping and restarting processes) very, very quickly and it really does this hundreds or even sometimes thousands of times per second inside the system, and in doing so it creates an environment that we call a time sharing system - processes take turns running so they share time on the CPU. And it allows us to run very many applications, which is multitasking.

Mutual Exclusion

Some way of making sure that if one process is using a shared variable or file, the other processes will be excluded from doing the same thing. A difficulty occurred because process B started using one of the shared variables before process A was finished with it. The choice of appropriate primitive operations for achieving mutual exclusion is a major design issue in any OS.

Critical Section

Sometimes a process has to access shared memory or files, or do other critical things that can lead to races. That part of the program where the shared memory is accessed is called the critical region or critical section. If we could arrange matters such that no two processes were ever in their critical regions at the same time, we could avoid races. We can select what code needs to run atomically, i.e. those pieces of code that once started can't be interrupted. Now unfortunately we can never say that we can't be interrupted! So the better solution is to say that we if we are interrupted that no other thread is allowed to go into that piece of code that could conflict with us. The critical section is a piece of code that once entered prohibits all other threads from entering the critical section on the same resource. If thread two wants to enter it's critical section it has to be blocked it has to be paused. The critical section should be as small as is possible because we don't want to spend a lot of time blocking all the other processes from accessing sections of code. We want this these pieces of code to be absolutely as small as possible.

Special File

Special files in UNIX are provided in order to make I/O devices look like files. That way, they can be read and written using the same system calls as are used for reading and writing files. Two kinds of special files exist: block special files and character special files. Block special files are used to model devices that consist of a collection of randomly addressable blocks, such as disks. By opening a block special file and reading, say, block 4, a program can directly access the fourth block on the device, without regard to the structure of the file system contained on it. Similarly, character special files are used to model printers, modems, and other devices that accept or output a character stream.

Hybrid Threading

Takes benefits from Kernel and User Level Threading. First implemented by Solaris OS, which created both kernel level threads and they created a user level thread, and tied the two together by means of what was known as a lightweight process, and the lightweight process is simply a container. So, we can put a number of user level threads inside of a lightweight process and we can choose to run that lightweight process on one kernel level thread, so when a kernel of a thread becomes available the lightweight process runs. And all of the user level threads in that process are run according to the scheduling library of that lightweight process. So, you as the programmer would create a lightweight process; you'd creates a number of user level threads. You'd assign the user level threads that you wanted to run to the lightweight process, but you can create any combination of user level threads and lightweight processes. So, if you had a very important user level thread, you would create one lightweight process for that one user level thread and any time that lightweight process ran that one user level thread would be the only one running. Then you could take three other user level threads, that are not critical, and put them on one lightweight process. So that when that lightweight process runs any of the user level threads inside could run. Of course, the same downside occurs as with user level threads, if one of the user level threads in the lightweight process blocks; all of the threads in the lightweight process will be blocked. As far as thread scheduling is concerned, there's both a global scheduling algorithm that chooses to run the kernel level threads and then there's a local scheduling algorithm, which you can implement you can manage yourself as the programmer, that would choose which of the user level threads as

Fundamental Mutual Exclusion

The built-in hardware mutual exclusion protection mechanism via the system bus, since it can only be used by one processor at any given time. So, even in a scenario where there is symmetric multiprocessing, with multi processors in the system, we it's impossible for two processors to change the same memory location at the same time, because one of those processors will gain access to the system bus to change that memory location and then the other will have to wait. Having that fundamental hardware mechanism is very useful, is helpful, but ultimately we need something a lot easier to deal with on a high level.

Context Switch

The exchange of register information that occurs when one process is removed from the CPU and another takes its place

Virtual Machine OS Design

The heart of the system, known as the virtual machine monitor, runs on the bare hardware and does the multiprogramming, providing not one, but several virtual machines to the next layer up. However, unlike all other operating systems, these virtual machines are not extended machines, with files and other nice features. Instead, they are exact copies of the bare hardware, including kernel/user mode, I/O, interrupts, and everything else the real machine has. In practice, the real distinction between a type 1 hypervisor and a type 2 hypervisor is that a type 2 makes uses of a host operating system and its file system to create processes, store files, and so on. A type 1 hypervisor has no underlying support and must perform all these functions itself. After a type 2 hypervisor is started, it reads the installation CD-ROM (or CDROM image file) for the chosen guest operating system and installs the guest OS on a virtual disk, which is just a big file in the host operating system's file system. Type 1 hypervisors cannot do this because there is no host operating system to store files on. They must manage their own storage on a raw disk partition. When the guest operating system is booted, it does the same thing it does on the actual hardware, typically starting up some background processes and then a GUI. To the user, the guest operating system behaves the same way it does when running on the bare metal even though that is not the case here.

Mainframe OS

The operating systems for mainframes are heavily oriented toward processing many jobs at once, most of which need prodigious amounts of I/O. They typically offer three kinds of services: batch, transaction processing, and timesharing. A batch system is one that processes routine jobs without any interactive user present. Claims processing in an insurance company or sales reporting for a chain of stores is typically done in batch mode. Transaction-processing systems handle large numbers of small requests, for example, check processing at a bank or airline reservations. Each unit of work is small, but the system must handle hundreds or thousands per second. Timesharing systems allow multiple remote users to run jobs on the computer at once, such as querying a big database. These functions are closely related; mainframe operating systems often perform all of them.

Suspended State

The process is sort of still ready to run but it isn't actually running or runnable yet. In suspension, the process will be completely removed from main memory; so, obviously its code can't run because this code isn't loaded in main memory. So, in suspension we completely take the process out of main memory and move it to a secondary storage device. Done to free up main memory. If we get to the point where main memory is starting to fill up, with so many processes or with such large processes, that we no longer have a lot of processes that are ready to run we might get into a condition where the process list has nothing on the ready state; everything is in the block state and there's no more memory available to allocate to new processes. So, we aim to free up that memory by suspending one or more processes and this is done by what's known as the medium term scheduling algorithm. And the medium term scheduling algorithm will choose which process to suspend, and then it will take that process and put it on the secondary storage device. Now, this doesn't mean that the process is terminated because we can certainly reload all the code data and context from the secondary storage device back into main memory at a later time and then run that process, just as if nothing ever happened. So it's very possible for any of your programs your 'Hello World' style programs from previous modules, that could have been suspended at some point. We might have suspended the process just simply for debugging purposes; we might have suspended the proper process at the request of the user doing a control Z on a Unix system. But the point is that we need to add States to our five state process model to recognize the possibility that the process is suspended. And we actually need to add two different suspended states, because we need to recogniz

Interrupt

The second I/O method is for the driver to start the device and ask it to give an interrupt when it is finished. At that point the driver returns. The operating system then blocks the caller if need be and looks for other work to do. When the controller detects the end of the transfer, it generates an interrupt to signal completion. Once the CPU has decided to take the interrupt, the program counter and PSW are typically then pushed onto the current stack and the CPU switched into kernel mode. The device number may be used as an index into part of memory to find the address of the interrupt handler for this device. This part of memory is called the interrupt vector. Once the interrupt handler (part of the driver for the interrupting device) has started, it removes the stacked program counter and PSW and saves them, then queries the device to learn its status. When the handler is all finished, it returns to the previously running user program to the first instruction that was not yet executed. During an interrupt, some piece of hardware has indicated that it needs immediate servicing, and so the operating system must be invoked in order to take care of that hardware. And what happens in an interrupt is the CPU will finish executing the instruction that it's running, and then it will switch to running the OS. And the OS has a specific point that it uses, it's called the Interrupt Service Routine (ISR). The ISR runs whenever an interrupt occurs; the processor knows to switch to the OS's ISR, and of course since it's switching from a running program to the kernel; it switches from user mode to kernel mode and it runs the ISR.

Busy Waiting

The simplest I/O method. A user program issues a system call, which the kernel then translates into a procedure call to the appropriate driver. The driver then starts the I/O and sits in a tight loop continuously polling the device to see if it is done (usually there is some bit that indicates that the device is still busy). When the I/O has completed, the driver puts the data (if any) where they are needed and returns. The operating system then returns control to the caller. This method has the disadvantage of tying up the CPU polling the device until it is finished.

Smart Card OS

The smallest operating systems run on smart cards, which are credit-card-sized devices containing a CPU chip. They have very severe processing power and memory constraints. Some are powered by contacts in the reader into which they are inserted, but contactless smart cards are inductively powered, which greatly limits what they can do. Some of them can handle only a single function, such as electronic payments, but others can handle multiple functions. Often these are proprietary systems.

DMA

The third I/O method makes use of special hardware: a DMA (Direct Memory Access) chip that can control the flow of bits between memory and some controller without constant CPU intervention. The CPU sets up the DMA chip, telling it how many bytes to transfer, the device and memory addresses involved, and the direction, and lets it go. When the DMA chip is done, it causes an interrupt.

Real-Time OS

These systems are characterized by having time as a key parameter. If the action absolutely must occur at a certain moment (or within a certain range), we have a hard real-time system. Many of these are found in industrial process control, avionics, military, and similar application areas. These systems must provide absolute guarantees that a certain action will occur by a certain time. A soft real-time system, is one where missing an occasional deadline, while not desirable, is acceptable and does not cause any permanent damage. Digital audio or multimedia systems fall in this category. Smartphones are also soft realtime systems. Since meeting deadlines is crucial in (hard) real-time systems, sometimes the operating system is simply a library linked in with the application programs, with everything tightly coupled and no protection between parts of the system. An example of this type of real-time system is eCos.

Blocked State

Well what happens if the process makes some sort of request which is going to take a really significant amount of time. The operating system doesn't want to stand and wait, waiting for that process to do what it's asking to do. And so it moves the process into the block state to indicate that this process is no longer ready to run; it is not running but it's not quite done yet. And the process is going to wait in the block state until whatever action it's requested finishes, and then it's going to move from the block state instead back into the ready state.

Thread States vs. Process States

Thread only has three states: ready, running, and blocked. Threads don't have a new and an exit state, because we don't need to load code. For example, our old example of loading the code and that was why we needed the new state, we don't have that anymore because the thread already has all of its code loaded in main memory. We're just creating a new thread and how does a new thread get created? Well the operating system creates a Thread Control Block (TCB) to recognize this thread, initializes the linkages initializes the TCB, and then it starts to run. So, it's really an atomic element creating a new thread can be done atomically, and the thread just begins running inside the context of the process. So, we don't need a new state and likewise, we don't even exit state because when a thread completes there's nothing returned back to the running process; the thread just records that it's done. Likewise, the idea of suspension is really a process level concept; if we've removed all of the main memory the none of the threads are able to run. So in suspension, we have to recognize that all of the threads have been blocked or all the threads have been stopped altogether. But at the same time, there's no real recognition of the suspended state inside of a thread; that's more of a process level concept.

POSIX

To make it possible to write programs that could run on any UNIX system, IEEE developed a standard for UNIX, called POSIX, that most versions of UNIX now support. POSIX defines a minimal system-call interface that conformant UNIX systems must support. In fact, some other operating systems now also support the POSIX interface.

Race Condition

Two or more processes are reading or writing some shared data and the final result depends on who runs precisely when. Debugging programs containing race conditions is no fun at all. The results of most test runs are fine, but once in a blue moon something weird and unexplained happens. Unfortunately, with increasing parallelism due to increasing numbers of cores, race condition are becoming more common.

Double Update Problem

Two pieces of code: a deposit function and a withdraw function. Imagine a situation where you have two ATM cards for the exact same bank account and you go to the bank, at exactly the same microsecond in time, and one person is doing a deposit and the other person is doing withdrawal. And when we do that, we have two transactions that are happening at the same time on different processors. So, now we have the possibility of asynchrony because we're dealing with this with separate processors and symmetric multiprocessing. We're going to assume that the bank has a good enough system that we have more than one CPU, so we can expect that this these pieces of code are running on two separate processors at exactly the same time. The biggest issue is that they share a balance, and the balance starts out at $100 and the first transaction is the deposit which is $50 and the second transaction is the withdrawal of $100. Ultimately, we should see is the bank balance is $50. What we start off with is the deposit function which is going to put in $50. The new balance is $150. This new balance variable is local to the deposit function, because it made a copy of the balance which was $100 and it adds the $50, so we have $150. Unfortunately, we get an interrupt or we're running on a separate CPU, so we go to the other CPU and we check out what's happening there. Now we look at the withdrawal function now and it's running on the other CPU, and in that function the new balance is $0. We return to the deposit function, which updates the balance to $150 and the deposit thread exits. But when we go back and finish out the withdraw thread, we get into trouble because we're going to update the balance to $0. So, our $50 deposit disappeared, because of asynchrony between the deposit and withdrawal functions/threads. We're going to take care

Parallel Bus Architecture

Used in traditional PCI means that you send each word of data over multiple wires. For instance, in regular PCI buses, a single 32-bit number is sent over 32 parallel wires.

Batching

Used on mainframes that ran jobs. One program had complete access to all of the system resources; it had access to all of system memory, save for a small little area for the operating system. It had access to all of the CPU time. This one program was started, processed all of its data, ran through to completion, and when it ended another program was started. In order to do that you require some Job Control Language, which tells the operating system what facilities: what printers, what files, what network connections, anything the program needed, before even the program started.

UID

User Identifier of the person who started that process. The UID is important because it leads to the security perimeter restrictions that are placed onto that program. What can this program do is based on who activated this process.

Layers of Interaction

Users interact with applications, applications interact with the OS, OS interacts with hardware

Cache Hit

When the program needs to read a memory word, the cache hardware checks to see if the line needed is in the cache. If it is, called a cache hit, the request is satisfied from the cache and no memory request is sent over the bus to the main memory. Cache hits normally take about two clock cycles. Cache misses have to go to memory, with a substantial time penalty.

Thread Table

When threads are managed in user space, each process needs its own private thread table to keep track of the threads in that process. This table is analogous to the kernel's process table, except that it keeps track only of the per-thread properties, such as each thread's program counter, stack pointer, registers, state, and so forth. The thread table is managed by the run-time system. When a thread is moved to ready state or blocked state, the information needed to restart it is stored in the thread table, exactly the same way as the kernel stores information about processes in the process table.

Asynchrony

When two threads are running seemingly at the same time. We might have a running thread that is interrupted due to some hardware considerations and a different thread is chosen to run. We have one thread that's running on the CPU and it stops running and then when we come back we're choosing a different thread to run. We could also have a thread that runs out of time. Remember we're in a preemptive system. So we're not allowing threads to run until they're finished. We're allowing them to run only for a certain period of time and when that period of time runs out whether or not the thread is finished we have to pause the thread we have to bring the thread out of the running state bring it back into the ready state and then we can go on to running either this thread or we can choose a different thread to run. If we have multiple CPUs we can have two of these threads running on the CPU all at the same time. The work that the threads are doing it is not an atomic instruction. We don't do one function call and finish the function call and then pause to run another thread. We could be in the very middle of an instruction or in the very middle of a line of code and we could stop and run a different thread altogether so we always have to keep that in the back of our minds when working with threads that we never really know when the thread is going to be stopped and when a different thread and possibly a conflict thread would be run.

WHQL

Windows Hardware Quality Labs. A service provided by Microsoft to hardware developers and vendors to test their hardware and device drivers with Windows. Bad device drivers were common cause of "Blue screen of death."

Microkernel OS Design

With the layered approach, the designers have a choice where to draw the kernel-user boundary. Traditionally, all the layers went in the kernel, but that is not necessary. In fact, a strong case can be made for putting as little as possible in kernel mode because bugs in the kernel can bring down the system instantly. In contrast, user processes can be set up to have less power so that a bug there may not be fatal. The basic idea behind the microkernel design is to achieve high reliability by splitting the operating system up into small, well-defined modules, only one of which—the microkernel—runs in kernel mode and the rest run as relatively powerless ordinary user processes. In particular, by running each device driver and file system as a separate user process, a bug in one of these can crash that component, but cannot crash the entire system. Thus a bug in the audio driver will cause the sound to be garbled or stop, but will not crash the computer. In contrast, in a monolithic system with all the drivers in the kernel, a buggy audio driver can easily reference an invalid memory address and bring the system to a grinding halt instantly.

Threads

With threading, a process now no longer means an execution path, we're now talking about a unit of resource ownership. The process becomes the unit of resource ownership but the thread becomes the unit of execution. And we might have multiple threads that run inside a single process and each thread has its own code. Although the code is memory and the memory is owned by the process. So, there might be multiple threads that are running the same code, or the threads might be running different code. All the threads inside a process share all the resources of the process and that includes all the memory, so threads can share the same memory unlike processes; processes can't share memory they're restricted because they're in user mode. But threads all exist inside of a process and the operating system is going to recognize that multiple threads are running inside a process, and it's going to be able to execute any one of the individual threads inside the process. Synchronous processing. Multiple threads run separately but at the same time. If there's a very large data set and we'd like to process portions of it separately, we can process those portions separately using multiple threads. And a block that happens in one thread will not obscure the other thread from running. Asynchronous processing. The threads need to do some sort of work cohesively so that when one thread ends the next thread begins, or infrequent tasks, where one thread doesn't run very often. Advantages of Threading: 1. The ability for the parallel entities to share an address space and all of its data among themselves. This ability is essential for certain applications, which is why having multiple processes (with their separate address spaces) will not work. 2. Since they are lighter weight than processes, they are easier (i.e., faster) to create an


Conjuntos de estudio relacionados

Delmars Unit 24 Resistive-Inductive-Capacitive Parallel Circuits

View Set

Underwriting Basics, 4th Edition Course

View Set

Course 5: Sec 2: Search and Display Marketing

View Set