CS 111 Scribe Notes Lecture 4 (Fall 2014)

OS Organization

Prepared by Yanbin Ren, Yijia Liu, Qiuhan Ding, Zhaoxing Bu


Goals


Fundamental Abstractions for Systems

1. Memory API

Memory is the system component that remembers data values for use in computation. All memory devices fit a simple abstract model that has two operations, named WRITE and READ:
e.g.
    *p = v //write
    (*p)   //read

2. Interpreters API

Interpreters are the active elements of a computer system, they perform the actions that constitute computations. Examples: disk controller, Python.
e.g.
       v      =      f          (p)
       |             |           |
    answer     interpreter   program

3. Linked API - Message Passing API

A communication link provides a way for information to move between physically separated components.(e.g. I/O bus)
    send(link_name, buffer of data)
    recv(line_name, buffer of data)

Design OS as an Object-Oriented Program


How Virtual Machine Work

please reload

Layering

We divide OS into layers

please reloadplease reload
Wedding Cake Diagram
Ring Diagram

A wedding cake/ring diagram shows system privilege layer.

Ring 0kernel
Ring 1devices
Ring 2daemons
Ring 3app

In Linux: Ring 0 ~ Ring 2 => Ring 0, Ring 3 = Ring 3

Instructions

Instructions can be divided into two sets:

1. Priviledged instructions

These are dangerous instructions, only kernel can execute them, applications cannot execute priviledged instructions. Applications ask the kernel to execute these intructions through system calls.

2. Unpriviledged instructions

Normal instructions, can be executed by applications.

Operating System & Virtualizable Processor

Let you support a process (namely, program) running in isolation (on a virtual interpreter). The program thinks of it as a standalone program running on a virtual machine.

In Unix-like systems, fork() is an operation whereby a process creates a copy of itself. It is usually a system call, implemented in the kernel. Fork is the primary (and historically, only) method of process creation on Unix-like operating systems.

To create a process:

  pid_t fork(void);       (in c/c++)

fork() clones the current process (registers, stacks, ...) fork() returns 0 in child process, and child process' process id in parent process, or -1 if fork() fails.

To destroy a process: (2 ways)

  (1) _noreturn void exit(int); // no return attribute
  //exit status is a 8-bit integer, 0~255
  //EXIT_SUCCESS = 0; EXIT_FAILURE = 1;
  (2) _exit(int);

They immediately terminates the current process, close all file descriptors belonging to the process, and return the exit status according to the given integer value.

Following is a code that shows how fork() works:

int main(void){
	pid_t p = fork();
	if (p == 0)
		printf("I'm a child\n");
	else
		printf("I'm a parent\n");
}

Suppose we have one physical CPU, and more than one processes. Each of these processes consider itself as the only process running on the system. How can the OS manages those processes at the same time? We use a process table (lives in memory) to store information for a process like: process id, register values (eip, esp, eax, ebx, ...), exit status, and so on. When the OS wants to switch to another process, the values in registers are stored into the process table. And when OS reruns a process, it first load all the register values from the process table and put them back into registers.

please reload

while calling fork() to create a child process:

How process scheduling works

e.g.
    read(fd, buffer, 1000);

How does process access to memory?

Each process has its own view of memory; they may share some part of memory if there is not a collision.

please reload

How exit() works in a program

  pid_t p = fork();
  _exit(2); //SYSCALL
  int main(void){
    return 0;
  } //  => exit(0);
please reload
pid_t waitpid(pid_t p, int *status, int flag); //destructor for process
                    |         |           |
                pid of      location     normally, 0,
                waited-for  to store     WNOHANG
                process     its status
please reload

A fork() process may work in this way...

    fork();          //- parent process
      |
   run_child();      //- child process
      |
    exit();          //- child process
      |
   waitpid();        //- parent process
      |
   run_parent();     //- parent process
      |
    exit();          //- parent process

A fork() BOMB!

linear:

while (fork() == 0)
  continue;
parent -> child -> grandchild ->......

tree:

while(true)
  fork();
parent  -> child   ->  gradchild
                   ->     ...
        ->  child  ->     ...

It will return -1 with an errno(..) once the process table is full.

Pipe

-> Bounded queue of bytes stored in the kernel memory

To invoke the pipe syscall:

int pipe(int fd[2])
              |
           two file descriptors (typically 1 read 1 write)

Last modified: Tue Oct 21 18:38:25 PDT 2014