update 8.md 9.md

This commit is contained in:
2025-11-26 03:47:12 +09:00
parent 17257c2d9f
commit 0a652a3214
2 changed files with 228 additions and 0 deletions

203
notes/9.md Normal file
View File

@@ -0,0 +1,203 @@
# Exception
An Exception is a **transfer of control** to the OS kernel in response to some event(like div by 0, overflow, ctrl+C). that is change in processor state.
**Exception Tables**
Each type of event has an unique exc number `k`: `k` is index into **exception table(interrupt vector table)**
Handler `k` is called each time exception `k` occurs.
## Asyncronous exceptions
It is caused by external events. Handler returns to next instruction.
for example: Timer interrupt, I/O interrupt.
## Syncronous exceptions
It is caused by events that occur as a result of exxecuting an current instruction.
* Traps
* Intentional like procedure calls (e.g. system calls)
* Returns to next instruction
* Faults
* Unintentional but possibly recoverable (e.g. page fault(recoverable), protection fault(not recoverable), floating point exception)
* re-executes by kernel or aborts
* Aborts
* Unintentional and not recoverable (e.g. illegal instruction, parity error, machine check)
* Aborts the program
## System Calls
Each x86-64 system call has a unique syscall number.
| Num | Name | Desc |
| --- | ------ | --------------- |
| 0 | read | read file |
| 1 | write | write file |
| 2 | open | open file |
| 3 | close | close file |
| 4 | stat | get file status |
| 57 | fork | create process |
| 59 | execve | execute program |
| 62 | kill | send signal |
## Fault Example
### Page Fault
```c
int a[1000];
main() {
a[500] = 13;
}
```
In this situation, a page containing `a[500]` is currently on disk, so page fault occurs, CPU cannot find the data in physical RAM. So kernel copy page from disk to memory, and return and re-executes the instruction `movl`
### Invalid Memory Ref
```c
int a[1000];
main() {
a[5000] = 13;
}
```
In this situation, address `a[5000]` is invalid, so protection fault occurs, kernel terminates the program by sending `SIGSEGV` signal to the user process. Then user process exits with error code `Segmentation Fault`.
## Process
An instance of a running program.
Process provides each program with two key abstractions:
* Logical control flow
* Each program seems to have **exclusive use of the CPU** provided by **context switching** of the kernel
* Private address space
* Each program seems to have **exclusive use of main memory** provided by **virtual memory** of the kernel
But in reality, computer runs multiple processes simultaneously by time-sharing CPU and multiplexing memory.
### Multiprocessing
Single processor executes multiple processes concurrently. process execution interleaved by time-slicing. Address spaces managed by virtual memory system. And register values for non-executing processes saved in memory.
Multicore processor share main memory each can execute a separate process. scheduling of processors onto cores done by kernel.
### Concurrent Processes
Concurrency is **not at the exact same time**.
Two processes are **concurrent** if their flows **overlap in time**. Otherwise, they are **sequential**.
Control flows for concurrent processes are pysically disjoint in time. But user think that they are logically running in parallel.
* Execution time of instruction may vary because of the Nondeterminism of the System: OS scheduling, Interrupts, Cache miss or Page fault, I/O device delays.
### Context Switching
Prcess are managed by a shared chunk of memory-resident OS code called the **kernel**.
What is important is that the kernel is **not a seprate process**. It is invoked by processes when they need OS services, or when exceptions occur. That is Part of the processor.
Control flow passes via a context switching.
## Syscall Error Handling
On error, Linux sys level function typically returns `-1` and sets the global variable `errno` to indicate the specific error.
Hard and fast rule:
* You must check the return status of every system-level function
* Only exception is the handful of functions that return void
Error reporting functions:
```c
void unix_error(char *msg) {
fprintf(stderr, "%s: %s\n", msg, strerror(errno));
exit(0);
}
```
Error handling wrappers:
```c
pid_t Fork(void) {
pid_t pid;
if ((pid = fork()) < 0) unix_error("Fork error");
return pid;
}
```
## Creating and Terminating Processes
* `pid_t getpid(void)` returnes pid of current process
* `pid_t getppid(void)` returns pid of parent process
We can think of a process as being in one of three states:
* Running
* Executing or waiting to be executed
* Stopped
* Process execution is suspended and will not be scheduled until futher notice
* Terminated
* Stopped permanently
### Terminating Processes
1. `return` from `main`
2. call `exit(status)` function
3. Receive a termination signal
```c
void exit(int status);
```
### Creating Process
Parent process can creates a new running child process by calling `fork()` system call.
```c
int fork(void);
```
it returns `0` to the newly created child, and returns **child's pid** to the parent.
Child is almost identical to parent: child get an identical copy of the parent's virtual address space, file descriptors, and process state.
But child has its own unique pid.
```c {cmd=gcc, args=[-O2 -x c $input_file -o 9_1.out]}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
pid_t pid;
int x = 1;
pid = fork();
if (pid == 0) { /* Child */
printf("child: x=%d\n", ++x);
exit(0);
}
printf("parent: x=%d\n", --x);
exit(0);
}
```
```sh {cmd}
while ! [ -r 9_1.out ]; do sleep .1; done; ./9_1.out
```
Concurrent execution of parent and child processes. `fork` duplicates but separates address space.
File descriptors are shared between parent and child like `stdout`, `stderr`.
Modeling fork with Process Graphs
* Each vertex represents a process state
* Directive Edges represent is ordering of execution.
* Edge can be labeled with current value of variables
Any topological sort of the graph corresponds to a feasible total ordering.
### Reaping Child Processes
When a child process terminates, it becomes a **zombie** until its parent calls `wait` to read its exit status.
## execve