7. UNIX PROCESS CONTROL ▷ fork : 새로운 프로세스 생성 ▷ exit : 프로세스 실행을 종료

Slides:



Advertisements
Similar presentations
Term Project Hints Topics Keep-alive CGI Multi-thread Multi-process Event-based.
Advertisements

Signal Handling ( 금 ) 한 민 규
YES C 제 1 장 C 언어의 개요 1/34 제 1 장 C 언어의 개요 문봉근. YES C 제 1 장 C 언어의 개요 2/34 제 1 장 C 언어의 개요 1.1 프로그램과 C 언어의 특징 1.2 C 언어의 프로그램 구성 1.3 비주얼 C++ 통합 환경 들어가기.
Linux System Programming
C++ Tutorial 1 서강대학교 데이터베이스 연구실.
Basic of Buffer Over Flow
Project #2-2. Pintos User Program
Linux/UNIX Programming APUE (The Environment of a UNIX Process)
Activation Records & Recursion
Oracle Embedded SQL Pro*C : Chap 5 Copyright by SunYoung Kim
Linux/UNIX Programming APUE (Process Control)
22 장 프로세스간 전달 : UDP와 TCP 22.1 프로세스간 전달 22.2 사용자 데이터그램 프로토콜
C 프로그래밍 소개 숙명여대 창병모 2011 가을.
Linux System Programming
Department of Computer Engineering
System Call Linux Kernel 수업 3번째.
인공지능실험실 석사 2학기 김승겸 TCP/IP Socket Programming… 제 10장 멀티태스킹 기반의 서버구현 인공지능실험실 석사 2학기 김승겸
Signal & Inter-Process Communication
FUSING.
Department of Computer Engineering
공학기초설계 Youn-Hee Han 강의 소개 & MinGW & gcc 공학기초설계 Youn-Hee Han
리눅스 커널의 이해 중에서 1장. 소개 이원구 네트워크 실험실.
6 프로세스 생성과 실행.
6 프로세스 생성과 실행.
Linux System Programming
Embedded System Porting (2)
Department of Computer Engineering
2장 운영 체제의 개요 운영체제의 개념 운영체제의 유형 운영체제의 발전 과정 운영체제의 구성 운영체제 서비스 시스템 구조
Department of Computer Engineering
fork로 생성한 자식 프로세스에서 exec 함수군을 호출
Linux System Programming
멀티쓰레드 기반의 서버구현 School of Electronics and Information.
파일 및 디렉토리(1) 여러 함수들 chdir(“category”) || die “cannot cd to temp”;
Computer Architecture
Term Project Team Member
프로세스 생성[1] 프로그램 실행 : system(3) #include <stdlib.h>
Lecture #3 프로세스(Process).
Department of Computer Engineering
Chapter 10. 파일 시스템 인터페이스(File System Interface)
파일 시스템 인터페이스(File System Interface)
5 프로세스 정보.
제2장 프로세스 이나현.
12. 시스템 프로그래밍 (System Programming)
Signal & Inter-Process Communication
제10장 파일 시스템 인터페이스(File System Interface)
제4장 유닉스 쉘 숙명여대 창병모 2011 가을.
Memory & Data Management.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
CGI (Common Gateway Interface)
운영체제 (Operating Systems) (Memory Management Strategies)
네트워크 프로그래밍의 이해 School of Electronics and Information.
Transmission Control Protocol (TCP)
CGI (Common Gateway Interface)
User Datagram Protocol (UDP)
Operating System 10주차 - IPC(InterProcess Communication) -
Linux/UNIX Programming
Stepper Motor 디바이스 드라이버
Chapter 12 Memory Organization
Fflush 사용이유 및 방법 [이유] 키보드에서 입력된 내용은 입력버퍼에 저장되었다가 Enter 키가 들어오면 프로그램으로 전달됨 이 때 입력버퍼에 있는 Enter 키도 프로그램으로 전달됨 그러므로 아래와 같은 프로그램에서 문자 하나를 입력해도 Enter키도 입력된 것으로.
23. Unix 시스템 커널. 개요 커널의 기본 서비스 커널의 특징 참고서적 프로세스 관리 장치 관리 파일 관리 가상 메모리
Department of Computer Engineering
8. 리눅스의 내부 군자삼락 [君子三樂] 청출어람이청어람 [ 靑出於藍而靑於藍 ] Why Linux ?
Execution with Unnecessary Privileges
제4장 유닉스 쉘 숙명여대 창병모
Signal & Inter-Process Communication
Linux/UNIX Programming
3장 파일 다루기 한빛미디어(주).
Lecture 7 7-Segment LED controller using u-controller
한국 휴렛팩커드/고객지원사업본부/IT 기술사업부 박기영
가상 기억장치 (Virtual Memory)
Presentation transcript:

7. UNIX PROCESS CONTROL ▷ fork : 새로운 프로세스 생성 ▷ exit : 프로세스 실행을 종료 ○ 프로세스 문맥(context)을 제어하는 시스템 호출의 사용 및 구현 방식 소개 ▷ fork : 새로운 프로세스 생성 ▷ exit : 프로세스 실행을 종료 ▷ wait : parent 프로세스의 실행을 child 프로세스의 exit와 동기화 ▷ brk : 프로세스에게 메모리를 동적으로 할당 ▷ signal : 프로세스들에게 asynchronous하게 이벤트 발생을 알림 ▷ exec : - 그림 7.1 참조

Objectives The Use and Implementation of System Calls Process Creation Process Execution process Signaling Process Termination System Booting Progress System Boot and Init Process Process System Calls

7.1 프로세스 생성 Fork system call pid = fork(); Only a process can create another process. Process 0 is only process not created via fork. Only one way to create process The swappable image of the created process (child) is almost an exact copy for the following: The child process has unique process ID The child process has a different parent ID The child process share a common file pointer with the correspond file descriptor of the parent The child process’s utime, stime, cutime, cstime are set to 0

Fork return 0 to the child process Fork returns the PID of child process to the parent Implementation of the ‘fork’ system call Check to see if enough swap memory is available Allocate process table entry and create copy of the swappable image of the parent (newproc()) Initialize accounting parameters in the user structure of the child Return zero : process ID of child to parent ▷ fork의 동작 순서 1. 새로운 프로세스를 위해 프로세스 테이블에 슬롯을 할당 2. 자식 프로세스에게 유일한 프로세스 ID no.를 할당 3. 부모 프로세스의 context 복사 4. 파일 및 inode 테이블의 카운트 증가 5. 부모 프로세스는 자식 프로세스의 ID no.를 리턴, 자식 프로세스에게는 0을 리턴

알고리즘 fork 입력: 없음, 출력: 부모 프로세스에게는 자식의 pid 번호, 자식 프로세스에게는 0 { 커널 자원이 이용 가능한지 검사한다; 빈 프로세스 테이블항과 고유한 pid 번호를 얻는다; 사용자가 너무 많은 프로세스를 실행중이 아닌 지 검사한다; 자식의 상태를 “생성중”으로 기록한다; 부모 프로세스 테이블 항으로부터 데이터를 새로운 자식의 항에 복사한다; 현행 디렉토리 inode와 변경된 루트(해당될 경우)의 계수를 증가시킨다; 부모 문맥(u area, 텍스트, 데이터, 스택)을 메모리에 복사한다; 자식 시스템 수준 문맥에 모조의 시스템 수준 문맥 층을 push; 모조 문맥은 자식 프로세스가 자신을 인식하도록 하는 데이터를 포함하며 스케쥴되었을 때 여기서부터 실행을 시작한다; if (실행 프로세스가 부모 프로세스이면) { 자식의 상태를 “수행 대기”로 바꾼다; return(자식 id); /* 시스템에서 사용자로 복귀 */ } else /* 실행 프로세스가 자식 프로세스이다 */ { u area의 시간 필드를 초기화한다; return(0); /* 사용자로 복귀 */ 그림 7.2 fork 알고리즘

#include <stdio.h> #define MSGSIZE 16 char *msg1 = “hello, world #1”; char *msg2 = “hello, world #2”; char *msg3 = “hello, world #3”; main() { char inbuf[MSGSIZE]; int p[2], j, pid; if (pipe(p) < 0 ) { printf(“pipe call error\n”); exit(1); } if ((pid = fork() ) < 0 ) { printf(“fork error\n”); exit(1); if (pid > 0 ) { close(p[0]); write(p[1], msg1, MSGSIZE); write(p[1], msg2, MSGSIZE); write(p[1], msg3, MSGSIZE); wait((int *) 0 );

read(p[0], inbuf, MSGSIZE); printf(“%s\n”, inbuf); } if (pid ==0 ) { close(p[1]); for ( j = 0; j < 3 ; j ++ ) read(p[0], inbuf, MSGSIZE); printf(“%s\n”, inbuf); } exit(0); * Pipe를 이용한 fork 사용 example

#include <fcntl.h> main() { int fd; /* file descriptor */ int pid; /* process id */ char buf[10]; /* buffer to hold file data */ if ( (fd = open(“sample.txt”, O_RDONLY) ) < 0 ) { printf(“file open error\n”); exit(1); } read(fd, buf, 10); printpos(“Before fork”, fd); if ( (pid = fork() ) < 0 ) { printf(“fork error\n”); exit(1) ; } else if ( pid == 0 ) /* child */ { printpos(“Child before read”, fd); printpos(“Child after read”, fd);

else /* parent */ { wait( (int *)0 ); printpos(“Parent after wait”, fd); } printpos(string, filedes) char *string; int filedes; { long pos, lseek(); if ( (pos = lseek(filedes, 0L, 1)) < 0L) printf(“error: lseek failed\n”); printf(“%s: %ld\n”, string, pos);

7.2 Signals How/When a signal is posted Posted Signals kill() system call int kill(pid, sig) int pid, sig; Interrupt or quit from terminal Death of child System call error Trap Posted Signals Recorded in p_sig of receiving process nth rightmost bit corresponds to signal n Not queued

Signal Processing : 2 phase Posting Phase : Post signal for process Posting by kernel routine psignal() Receive Phase : Signal processing #include (signal.h) oldfunc = signal (signum, function); int sig; int (*func)(); return value 0: 커널에서 exit 수행, core image 덤프 1: 앞으로의 신호를 무시 - 그림 7.7 신호인식 알고리즘

Performs action related to signal when: Process is switched in After system call or user mode trap Default : Terminate process Ignore : Ignore signal Catch : Use u_signal [i] as the address of a function to be executed

알고리즘 psig /* 신호의 존재를 인식후 신호를 처리 */ 입력 : 없음 출력 : 없음 { 프로세스 테이블 항에 설정된 신호 번호를 얻음; 프로세스 테이블 항의 신호 번호를 지움; if(사용자가 이 신호를 무시하도록 signal 시스템 호출을 호출했다면) return; /* 완료 */ if(신호를 처리하도록 사용자가 함수를 지정했음) { u area에 저장된 신호 캐쳐(처리함수)의 사용자 가상주소를 얻음; /* 다음 문장은 바람직하지 않은 부수 효과(side effect)를 갖는다. */ 신호 캐쳐의 주소를 지정한 u area의 항을 지운다; 사용자 수준 문맥을 수정; 신호 캐쳐 함수에 대한 호출을 흉내내도록 사용자 스택 프레임을 인공적으로 생성; return; } if(시스템이 프로세스의 코어 이미지를 덤프해야 하는 신호 타입이면) { 현행 디렉토리에 “core”란 이름의 파일을 생성; 사용자 수준 문맥의 내용을 “core”에 기록; } exit 알고리즘을 즉시 호출; } 그림 7.8 신호를 처리하는 알고리즘

#include <signal.h> sigcatcher( ) { printf(“PID %d caught one\n”, getpid( ) ); /*프로세스 id를 인쇄 */ signal(SIGINT, sigcatcher); } main( ) { int ppid; signal(SIGINT, sigcatcher); if(fork( ) == 0 ) { /* 두 프로세스가 준비하는 데 충분한 시간을 준다. */ sleep(5); /* 5초간 지연시키는 라이브러리 함수 */ ppid=getppid( ); /* 부모의 id를 얻음 */ for( ; ; ) if(kill(ppid, SIGINT) == -1) exit( ); } /* 우선순위가 낮을수록 경쟁을 보일 가능성이 증대 */ nice(10); for( ; ; ) ; } 그림 7.12 신호를 포착할때 경쟁 상황을 보이는 프로그램

#include <signal.h> main() { register int i; setpgrp(); for(i=0; i<10; i++) { if(fork()==0) { /* 자식 프로세스 */ if(i & 1) printf(“pid=%d pgrp=%d\n”, getpid(), getpgrp()); pause(); /* 실행을 중단하는 시스템 호출 */ } } kill(0, SIGINT); } 그림 7.13 setpgrp의 사용 예

Process Termination How/When is a process terminted? Normal – ‘exit’ sytem exit(status) int status; abnormal – Receipt of a signal with an action that is set to default Termination Processing : 2 Phase Process turns itself into a zombie process(exit()) Parent or stepparent lays the zombie to rest(wait())

알고리즘 exit 입력 : 부모 프로세스를 위한 복귀 코드 출력 : 없음 { 모든 신호를 무시하라; if(연관된 제어 터미널을 갖는 프로세스 그룹 리더) 프로세스 그룹의 모든 구성원에게 hangup 신호를 보냄; 모든 구성원의 프로세스 그룹을 0으로 재설정; } 모든 열린 파일을 닫음(알고리즘 close의 내부 버전); 현행 디렉토리를 반납(알고리즘 iput); 현행 (변경된) 루트가 존재하면 그것을 반납(알고리즘 iput); 프로세스와 연관된 영역과 메모리를 반납(알고리즘 freereg); 계정(accounting) 레코드를 기록; 그림 7.14 Exit 알고리즘

모든 자식 프로세스의 부모 프로세스 ID를 init 프로세스(1)로 지정; 프로세스를 시체(zombie) 상태로 만듬; 모든 자식 프로세스의 부모 프로세스 ID를 init 프로세스(1)로 지정; 만약 어떤 자식 프로세스가 시체 상태(zombie)이면 자식의 죽음(death of child) 신호를 init에 보냄; 부모 프로세스에 자식의 죽음(death of child) 신호를 보냄; 문맥 교환; } 그림 7.14 Exit 알고리즘

Implementation Set action of all signals to ignore Close open files Deallocate swappable image p_stat = SZOMB Notify parent(send SIGCLD signal) Disown children(ppids =1) Notify process 1 if zombie children Switch to a new process

main() { int child; if ((child=fork())==0) { printf(“child PID %d\n”, getpid()); pause(); } /* 부모 */ printf(“child PID %d\n”, child); exit(child); 그림 7.15 Exit 사용의 예

Awaiting Process Termination wait system call pid = wait(stat_loc); int *stat_loc; Synchronized with ‘exit’ system call Parent decides whether child process stopped or termintated from 16 bits of information called ‘status’ If child process stopped, the high order 8 bits is 0 and low 8 bits is 0177 If child process terminated due to exit call, the high order byte contain the low byte of data passed via exit call and the low order 8 bits is 0 If child byte is 0 and low order byte contain the number of signal which cause the termination

알고리즘 wait 입력 : 종료하는 프로세스의 상태를 저장할 변수의 주소 출력 : 자식 ID, 자식의 exit 코드 { if(기다리는 (waiting) 프로세스가 자식 프로세스를 갖고 있지 않음) return(error); for( ; ; ) /* 내부 루프로부터 복귀할 때까지 루프 수행 */ if(기다리는 프로세스가 시체(zombie) 상태의 자식 프로세스를 가짐) 임의의 시체 상태인 자식 프로세스를 선택; 부모 프로세스에 자식 프로세스의 CPU 사용량을 더함; 자식의 프로세스 테이블 항을 자유롭게 함; return(자식 ID, 자식의 exit코드); } if(프로세스가 자식 프로세스를 갖지 않음) 인터럽트 가능 우선순위로 수면(sleep)(사건:자식 프로세스가 exit); 그림 7.16 Wait 알고리즘

#include <signal.h> main(argc, argv) int argc; char *argv[ ]; { int i, ret_val, ret_code; if(argc > 1) signal(SIGCLD, SIG_IGN); /* 자식들의 죽음을 무시하라 */ for(i=0; i<15; i++) if(fork()==0) /* 자식 프로세스 */ printf(“child proc %x\n”, getpid( )); exit(i); } ret_val=wait(&ret_code); printf(“wait ret_val %x ret_code %x\”, ret_val, ret_code); 그림 7.17 Wait와 자식의 죽음 신호를 무시하는 예

#include <signal.h> main(argc, argv) { char buf[256]; if (argc!=1) signal(SIGCLD,SIG_IGN); while(read(0, buf, 256)) if (fork()==0) { /* 자식 프로세스가 이 부분에서 buf를 가지고 작업을 수행 */ exit(0); } 그림 7.18 자식의 죽음 신호의 이유를 설명하는 예

Program Execution Exec system call int execl(path, arg0, arg1……., argn, 0) char *path, *arg0….. ; int execv(path, argv) char *path, *argv[]; int execle(path, arg0, …. , argn, 0, envp) char *path, *arg0, …. , *argn, *envp[]); int execve(path, argv, envp) char *path, *argv[], *envp[]; Overlay text and data area with that of the new program

Implementation of the ‘exec’ system call Translation name into inode pointer Check execute permission for the executable file Check the size of the program Collect and check the size of the argument list, storing it on swap device Set up memory for execute file Read text segment handling case of shared text Read data segment Copy argument list back into stack segment and deallocate swap space for argument Set all caught signal actions to deault Reset register

알고리즘 exec 입력 : (1)화일이름 (2)인수 리스트 (3) 환경(environment)변수 리스트 출력 : 없음 { inode를 얻는다(알고리즘 namei); 파일이 수행 가능 화일인지 사용자가 수행 허가(permission)를 가졌는지 확인; 파일 헤더(header)를 일고 그것이 로드 모듈인지 검사; 구 주소 공간으로부터 시스템 공간으로 exec의 인수를 복사; for(프로세스에 부착된 모든영역) 모든 구 영역을 분리함(알고리즘(detach); } for(로드 모듈에 지정된 각 영역) 새로운 영역을 할당(알고리즘 allocreg);

적절하다면 영역을 메모리로 적재(알고리즘 loadreg); } 새로운 사용자 스택 영역으로 exec의 인수를 복사; 그영역을 부착함(알고리즘 attachreg); 적절하다면 영역을 메모리로 적재(알고리즘 loadreg); } 새로운 사용자 스택 영역으로 exec의 인수를 복사; setuid 프로그램과 트레이싱(tracing)을 위한 특별한 처리; 사용자 모드로 복귀를 위해 사용자 레지스터 저장 지역(area)을 초기화; 파일의 inode를 방출함(알고리즘 iput); 그림 7.19 Exec 알고리즘

#include <signal.h> main() { int i, *p; extern f(), sigcatch(); ip=(int *)f; for(i=0; i<20;; i++) signal(i, sigcatch); *ip=1; printf(“after assign to ip\n”); f(); } f() { } sigcatch(n) int n; { printf(“caught sig %d\n”, n); exit(1); } 그림 7.22 자신의 텍스트에 겹쳐쓰려는 프로그램 예

알고리즘 xalloc /* 텍스트 영역을 할당하고 초기화한다*/ 입력 : 실행가능 파일의 inode 출력 : 없음 { if(실행가능 파일이 분리된 텍스트 영역을 가지지 않는다) return; if(활성 영역 리스트의 inode와 실행가능 파일의 inode가 일치) /* 텍스트 영역이 이미 존재 … 그곳에 부착한다 */ 영역을 잠근다(lock); while(영역의 내용이 아직 준비 완료되지 않음) /* 참조계수의 조작은 영역의 완전 제거를 막아준다 */ 영역의 참조계수를 증가; 영역을 풀어준다(unlock); sleep(영역 내용이 준비 완료되는 시간); 영역 참조계수를 감소; }

영역을 프로세스에 부착(알고리즘 attachreg); 영역을 풀어준다(unlock); return; } /* 그러한 텍스트 영역이 존재하지 않는다… 한 영역을 생성 */ 텍스트 영역을 할당(알고리즘 allocreg); /* 영역이 잠겨(lock)짐 */ if(inode 모드의 sticky 비트가 세트되어 있다) 영역 sticky 플래그를 켠다; 영역을 inode 파일 헤더에 있는 가상주소에 부착(알고리즘 attachreg); if(파일이 페이징 시스템용으로 특별히 포멧됨) /* 이 경우는 9장에서 다룬다 */ else /* 페이징 시스템이 아닌 경우 */ 파일 텍스트를 영역으로 읽어들인다(알고리즘 loadreg); 프로세스당(per process)영역테이블의 영역 보호를 읽기 전용으로 바꾼다; 영역을 풀어준다 (unlock); 그림 7.23 텍스트 영역 할당을 위한 알고리즘

#include <fcntl.h> main() { int uid, euid, fdmjb, fdmaury; uid = getuid(); /* 실제(real) UID를 얻음 */ euid = geteuid(); /* 유효(effective) UID를 얻음 */ printf(“uid %d euid %d\n”, uid, euid); fdmjb = open(“mjb”, O_RDONLY); fdmaury = open(“maury”, O_RDONLY); printf(“fdmjb” %d fdmaury %d\n”, fdmjb, fdmaury); setuid(uid); printf(“after setuid(%d):uid %d euid %d\n”, uid, getuid(), geteuid()); fdmjb = open((“mjb”, O_RDONLY); setuid(euid); printf(“after setuid(%d):uid %d euid %d\n”, euid, getuid(), geteuid()); } 그림 7. 25 Setuid 프로그램의 수행 예

알고리즘brk 입력:새로운 break 값 출력:구 break 값 { 프로세스의 데이터 영역을 잠근다(lock); if(영역의 크기가 증가) if(영역의 새 크기가 불법) 데이터 영역을 풀어준다(unlolck); return(에러); } 영역의 크기를 변경(알고리즘 growreg); 새 데이터 공간의 내용을 0 으로 만듬; 프로세스의 데이터 영역을 풀어준다(unlock); 그림 7.26 brk 알고리즘

#include<signal.h> char *cp; int callno; main() { char *sbrk(); extern catcher(); signal(SIGSEGV,catcher); cp=sbrk(0); printf(“original brk value %u\n”,cp); for(;;) *cp++=1; } catcher(signo) int signo callno++; printf(“caught sig %d %dth call at addr %u\n”,signo,callno,cp); sbrk (256); 그림 7.27 brk 사용 및 출력 예

Original brk value 140924 Caught sig 11 1th call at addr 141312 Caught sig 11 2th call at addr 141312 Caught sig 11 3th call at addr 143360 …(10번째호출까지 동일한 주소가 프린트됨) Caught sig 11 10th call at addr 143360 Caught sig 11 11th call at addr 145408 …(18번째 호출까지 동일한 주소가 프린트됨) Caught sig 11 18h call at addr 145408 Caught sig 11 19th call at addr 147456 :

/* ”파일의 끝(end of file)” 까지 명령행을 읽어라 */ While(read(stdin,buffer,numchars)) { /*명령행을 파스(parse)한다 */ if(/* 명령행이 & 을 포함 */) amper=1; else amper=0; /*쉘 명령언어의 일부가 아닌 명령일 경우 */ if(fork()==0) /*입출력의 재지정? */ if(/*출력을 재지정 */) fd=create(newfile,fmask); close(stdout); dup(fd); close(fd); } if(/* 파이핑 */) pipe(fiees);

execlp(command1,command1,0); } /* 명령행의 두번째 구성 요소*/ if(fork()==0) { /*명령 행의 첫 번째 구성 요소 */ close(stdout); dup(fildes[1]); close(fildes[1]); close(fildes[0]); /*표준 출력은 이제 파이프로 가게 됨*/ execlp(command1,command1,0); } /* 명령행의 두번째 구성 요소*/ close(stdin); dup(fildes[0]); close(fildes[0]); close(fildes[1]); /*표준 입력이 이제 파이프로부터 오게 됨 */ execve(command2,command2,0); /* 부모가 이 위치에서 계속됨… *필요한 경우 자식이 exit하기를 기다림 */ If(amper==0) retid = wait(&status); 그림 7.28 shell으 메인 루프(계속)

System Boot and Init Process Bootstrap Procedure Load a bootstrap program from system’s microcode Read the boot block (block 0) of disk Loads it into memory and execute Its executions loads the kernel from root file system Transfers control to the start address of the kerner The kernel starts running (start function)

Process 0 (Primary Swapper) Responsible for scheduling memory It is a process (not a program) Always in kernel mode. Executes sched() Highest priority (PSWP = 0) Cannot be swapped out When active, it will swap in as many runnable process as it can Process 1 (Init Process) Child of process 0 Ancestor of all other process Stepparent of all orphan process Wait for its (step) children to termniate

Process 2 (Auxiliary Swapper) Activate when a process needs to be swapped out: Memory expansion Process creation Process not program Execute from xsched() Only swaps out Potentially activates the primary swapper Init Process (Process 1)