OSTEP Chapter 4: The Abstraction - The Process Review
Table of Contents
Question: How to provide the illusion of many CPUs?
Before answering this question, let’s first understand a few things
Program #
What is a Program? #
A Program is the code we write.
Process #
What is a Process? #
A Process is a running Program.
From a programming perspective, you can also see it as an object that can be created and used.
// the registers xv6 will save and restore
// to stop and subsequently restart a process
struct context {
int eip;
int esp;
int ebx;
int ecx;
int edx;
int esi;
int edi;
int ebp;
};
// the different states a process can be in
enum proc_state { UNUSED, EMBRYO, SLEEPING,
RUNNABLE, RUNNING, ZOMBIE };
// the information xv6 tracks about each process
// including its register context and state
struct proc {
char *mem; // Start of process memory
uint sz; // Size of process memory
char *kstack; // Bottom of kernel stack
// for this process
enum proc_state state; // Process state
int pid; // Process ID
struct proc *parent; // Parent process
void *chan; // If non-zero, sleeping on chan
int killed; // If non-zero, have been killed
struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory
struct context context; // Switch here to run process
struct trapframe *tf; // Trap frame for the
// current interrupt
};
Process API #
The operating system abstracts a Running program as a Process and also provides some useful APIs for us to manipulate them.
- Create
- Destory
- Wait
- Miscellaneous Control
- e.g., suspend or resume
- Status
Subsequent chapters will discuss some real Process APIs
Process States #
In the real world, Processes can be in many states, here are just a few examples:
- Running
- Ready
- Blocked
The state of a Process can switch due to various events.
How does a Program become a process? #
- The operating system reads the Program (code, static data) from the hard disk and loads it into memory.
- Initialize the stack (e.g., local variables, function parameter, return address, etc…)
- Initialize the heap
- Initialize related I/O (if needed)
- CPU executes instructions
Time-Sharing Mechanism #
The basic concept of time-sharing is that Process A runs briefly, pauses, and then Process B runs. Then repeats until both process are finished.
Because the CPU runs too fast (1 ms), it makes the user think that many tasks are being executed simultaneously.
Challenges #
Context switch #
When switching between different Processes, the OS needs to save and load some information so the CPU knows which Process to run.
There is also a significant overhead involved, and finding a balance between multitasking and efficiency is crucial.
Control #
When the CPU is running a Process, it means the operating system is not being run (the operating system can also be understood as a running program), so how to timely return control to the operating system while running other programs?