================ Start Lecture #4 ================

3.1.1: The Process Model

Even though in actuality there are many processes running at once, the OS gives each process the illusion that it is running alone.

Virtual time and virtual memory are examples of abstractions provided by the operating system to the user processes so that the latter ``sees'' a more pleasant virtual machine than actually exists.

Process Hierarchies

Modern general purpose operating systems permit a user to create and destroy processes. In unix this is done by the fork system call, which creates a child process, and the exit system call, which terminates the current process. After a fork both parent and child keep running (indeed they have the same program text) and each can fork off other processes. A process tree results. The root of the tree is a special process created by the OS during startup.

MS-DOS is not multiprogrammed so when one process starts another, the first process is blocked and waits until the second is finished.

Process states and transitions

The above diagram contains a great deal of information.

One can organize an OS around the scheduler.

The above is called the client-server model and is one Tanenbaum likes. His ``Minix'' operating system works this way. Indeed, there was reason to believe that it would dominate. But that hasn't happened. Such an OS is sometimes called server based. Systems like traditional unix or linux would then be called self-service since the user process serves itself. That is, the user process switches to kernel mode and performs the system call. To repeat: the same process changes back and forth from/to user<-->system mode and services itself.

2.1.3: Implementation of Processes

The OS organizes the data about each process in a table naturally called the process table. Each entry in this table is called a process table entry or PTE.

An aside on Interrupts

In a well defined location in memory (specified by the hardware) the OS store an interrupt vector, which contains the address of the (first level) interrupt handler.

Assume a process P is running and a disk interrupt occurs for the completion of a disk read previously issued by process Q, which is currently blocked. Note that interrupts are unlikely to be for the currently running process.

  1. The hardware stacks the program counter etc (possibly some registers)
  2. Hardware loads new program counter from the interrupt vector.
  3. Assembly language routine saves registers
  4. Assembly routine sets up new stack
  5. Assembly routine calls C procedure (tanenbaum forgot this one)
  6. C procedure does the real work
  7. The C procedure (that did the real work in the interrupt processing) continues and returns to the assembly code.
  8. Assembly language restores P's state (e.g., registers) and starts P at the point it was when the interrupt occurred.

2.2: Interprocess Communication (IPC) and Process Coordination and Synchronization

2.2.1: Race Conditions

A race condition occurs when two processes can interact and the outcome depends on the order in which the processes execute.

Homework: 2

2.2.2: Critical sections

We must prevent interleaving sections of code that need to be atomic with respect to each other. That is, the conflicting sections need mutual exclusion. If process A is executing its critical section, it excludes process B from executing its critical section. Conversely if process B is executing is critical section, it excludes process A from executing its critical section.

Goals for a critical section implementation.

  1. No two processes may be simultaneously inside their critical section
  2. No assumption may be made about the speeds or the number of CPUs
  3. No process outside its critical section may block other processes
  4. No process should have to wait forever to enter its critical section

2.2.3 Mutual exclusion with busy waiting

The operating system can choose not to preempt itself. That is, no preemption for system processes (if the OS is client server) or for processes running in system mode (if the OS is self service). Forbidding preemption for system processes would prevent the problem above where x<--x+1 not being atomic crashed the printer spooler if the spooler is part of the OS.

But this is not adequate

Software solutions for two processes

Initially P1wants=P2wants=false

Code for P1                             Code for P2

Loop forever {                          Loop forever {
    P1wants <-- true         ENTRY          P2wants <-- true
    while (P2wants) {}       ENTRY          while (P1wants) {}
    critical-section                        critical-section
    P1wants <-- false        EXIT           P2wants <-- false
    non-critical-section }                  non-critical-section }

Explain why this works.

But it is wrong! Why?