Chapter 1
1. Control Flow
Processors는 한 가지의 일만 한다. startup에서 shutdown까지 cpu는 명령(instructions)를 reads, executes를 한 번에 한 개씩 한다.
아래는 processors의 control flow이다.
프로그램은 Instructions들의 집합이다. CPU는 명령어를 순차적으로 실행하게 되고, 이 명령어를 실행하는 과정을 Control flow라고 한다.

CPU 입장에서 명령어를 수행하는 과정은 다음과 같이 나타낼 수 있다.
- CPU가 메모리(DRAM)에서 데이터를 끌어 모으고 Data Bus를 통해 가져온다.
(=fetch)
2.이 데이터를 CPU의 Instruction Register로 저장한다.
- CPU의 PC(program counter)는 그 다음 명령을 가리킨다.
- CPU는 Instruction Register에 저장되어 있는 명령을 읽고, 수행한다.(Decode & execute)
- Clock이 뛰면서 완료되고, PC에 의해 다시 다음 명령을 수행..
Altering the Control Flow
제어 흐름(control flow)를 변경하기 위한 두 가지의 매커니즘
- Jump and branches
- Call and return
Jump and brancehs는 각각 원래 PC의 다음 주소를 저장하고, Jump 후 수행, 다시 돌아옴(다음 주소)
Call and return는 서브루틴을 호출하느 경우임.
위 경우는 program state에 따라 반응하는 것임.
즉 의도적이라는 뜻임, 하지만 Program state가 변화하지 않고 System state가 바뀌는 경우도 많음, 근데 이게 좀 어려움. 아래 4가지의 경우가 System state가 바뀌는 경우이다.
- 디스크 또는 네트워크 어댑터에서 데이터가 도착함
- 명령어가 0으로 나눌 때
- 사용자가 ctrl + c를 누를 때
- 시스템 타이머가 만료될 때
따라서, 시스템은 exceptional control flow의 매커니즘이 필요합니당.
Exceptional Control Flow
- Low Level Mechanisms
- 예외 : 시스템 이벤트에 대한 control flow의 변화(= system state의 변화),
하드웨어와 OS 소프트웨어의 조합을 사용하여 구현한다.
- High Level Mechanisms
- Process context switch : OS 소프트웨어 및 하드웨어 타이머에 의해 구현된다.
- Siganls : OS 소프트웨어에 의해 구현된다.
- Nonlocal jumps: setjump() 및 longjump(), C runtime library에 의해 구현됨.
Exceptions
Exceptions는 일부 이벤트(예를 들어, 프로세서의 상태(processor state)의 변화)에 대한 응답이다. OS Kernel로 제어를 전송하는 것이다.
- Kernel는 OS의 메모리 상주 부분
- 이벤트의 예) 0으로 나누기, arthimetic overflow, page fault, I/O request completes, ctrl + c

- User code에서 Event가 일어난다. 이 Event의 예시는 위에서 설명했다.
- 그러면 Kernel로 Exception을 Kernel로 전송한다. 이때 이 Exception은 위 Event에 해당하는 응답으로, control을 전송하는 것을 일컫는다.
- Exception handler에 의해서 Exception processing 과정을 한다.
- 그 후 3가지 방향으로 제어한다.
Execute Exceptuons via Exception Tables
- 각 이벤트 유형에는 고유한 예외 번호가 있다.
- K = excepton table의 index이다. (= interrupt vector)
- 고유한 번호에 해당하는 핸들러, 즉 K Handler는 exception k가 발생할 때마다 호출된다.

Exceptions(예외)를 Class로 나눌 수 있는데,

Asynchronous(비동기) 예외는 Processor 외부에 있는 I/O 장치의 Event 결과로 발생한다.
Synchronous(동기) 예외는 명령 실행의 직접적인 결과로 발생한다.
Asynchronous Exceptions
위에서 이야기한 것처럼 I/O 장치의 event 결과로 발생한다.
- 프로세서(Processor) 외부의 이벤트로 인해 발생한다
- 프로세서의 interrupt pin을 설정하여 표시된다.
- Handler가 다음(next) 지침으로 돌아간다.

-
Timer interrupt로 발생
몇 ms마다 external 타이머 칩이 interrupt pin을 trigger한다. Kernel이 사용자 프로그램에서 control을 되찾는 데 사용된다.
-
I/O interrupt from external device
네트워크에서 패킷의 도착, 디스크에서 데이터의 도착.
Synchronous Exceptions
명령 실행의 결과로 발생하는 이벤트로 인해 발생한다.
- intentional
- system calls, breakpoint traps, special intructions으로 발생시킬 수 있다.
- Control을 "다음(next)" 명령어로 되돌린다.

System Call Example: Opening File

syscall은 Kernel로 넘기는 instruction이다.

Synchronous Exceptions(Faults)
마찬가지로, 명령 실행의 결과로 발생하는 이벤트로 인해 발생한다.
- Unintentional but possibly recoverable
= 의도하지 않았지만 복구 가능
예, page faults, protection faults(세그멘테이션 오류), floating point exceptions(예, 0으로 나누기)
오류(current) 명령을 다시 실행하거나 중단합니다.

- Fault Example : page fault
- User가 메모리 위치에 쓸 때(write)
- 사용자의 메모리의 해당 부분(page)가 현재 디스크에 있을 때

- Fault Example : Invalid Memory Reference

Synchronous Exceptions(Aborts)
마찬가지로, 명령 실행의 결과로 발생하는 이벤트로 인해 발생한다.
- Unintentional and unrecoverable(의도하지 않고 복구할 수 없음)
- 예) illegal instruction(잘못된 명령), parity error, machine check
- 현재 프로그램을 중단한다.

Processes
정의: 프로세스는 실행 중인 프로그램의 인스턴스이다. (실행 중인 프로그램)
프로세스는 각 프로그램에 두 가지 주요 추상화(key abstractions)를 제공한다.
- 논리적 제어 흐름 (Logical control flow)
- 각 프로그램은 CPU를 독점적으로 사용하는 것 같다.
- 컨텍스트 전환(context switching)이라는 Kernel mechanism에서 제공
▪ 개인 주소 공간 (Private address space)
▪ 각 프로그램은 주 메모리를 독점적으로 사용하는 것 같다.
▪ 가상 메모리(Virtual memory)라는 커널 메커니즘에서 제공
Logical control flow - Context Switch
프로세스는 커널에 의해 관리된다.
- kernel - OS 코드에 상주해 있는 메모리의 공유 chunk
▪ 중요: 커널은 별도의 프로세스가 아니라 일부 기존 프로세스의 일부로 실행된다.
Control flow은 context switch을 통해 한 프로세스에서 다른 프로세스로 전달된다.

Private Address Space - Virtual Memory
메모리의 관리의 도구라고 볼 수 있다. 메모리 할당을 간단하게 한다.
- Virtual/Physical 주소 공간은 Virtual/Physical 페이지로 분할된다.
- 각 가상 페이지는 모든 실제 페이지에 매핑할 수 있다.
- 가상페이지는 서로 다른 시간에 다른 실제 페이지에 저장될 수 있다.
- 가상 페이지를 동일한 실제 페이지에 매핑할 수 있다.

(pg21 ~pg 29) 생략
Obtaining Process IDs
process가 실행될 때 트리 구조로 실행 된다. 예를 들어서, 처음 process의 시작은 "init"이다. 부팅 후, "init" 루트 노드의 자식으로, "shell"이라는 자식이 생긴다. 그 후, 사용자가 a.out을 실행하려고 할 때, "shell"의 자식으로 프로세스가 생기고, process가 완료될 때 없어지게 한다. 이때 이 process들에는 각각의 ID가 있는데 이를 PID라고 일컫는다.

Terminating Processes
프로세스의 종료(삭제)부터 먼저 살펴보자면, 다음 세가지 이유 중 하나로 종료된다.
1. exit() function의 call
2. main routine에서 returning 될 때
3. default 동작이 종료되는 신호를 수신했을 때

위 사진은 exit함수이다. exit 함수의 파라미터로 status라는 값이 존재한다. 무심코, 코드를 짤 때, exit(0) 또는 exit(-1) 등으로 짜게 되는데, statusrk 0일 때 normal return, 0이 아닐 때 error라는 것을 알게 되었다.
- exit함수는 한번 call하지만 return하지 않는다. (NEVER!!)
Creating Processes
위에서 언급했듯이 부모 프로세스는 프로세스의 생성을 fork 함수릍 통해 만든다.
fork 함수는
- 자식프로세스에는 0을 부모 프로세스에는 자식의 PID를 return한다.
- 자식은 부모와 거의 동일하다(복사하며 생성한다)
- 자식은 부모의 Virtual Memory address와 동일하지만 별개의 복사본을 가져온다.
- 자식은 부모의 open file descriptors의 동일한 복사본을 얻는다.
- **자식이 부모와 다른 PID를 가지고 있다.
fork는 한번 호출되지만, 두번 반환된다.
