Operating Systems - Introduction, Processes, Threads
Transcript of Operating Systems - Introduction, Processes, Threads
Operating Systems
Introduction, Processes, Threads
Daniel Gruss
2021-03-02
Table of contents
1. Basics
2. Booting
3. Process and Thread Fundamentals
4. Context Switches
5. Process and Thread Organization
Basics
What is an Operating System
What is an Operating System
What is an Operating System
What is an Operating System
� Run on all sorts of devices:
� Servers, Desktops, Notebooks
� Tablets, Smartphones
� Routers, Switches, Displays
� Door Locks, Washing Machines, Toasters
� Cars, Airplanes
� ....
� We focus on general purpose operating systems
Operating System Roles
� Referee
� Illusionist
� Glue
Operating System Roles: Referee
Referee
� Manage resource allocation among users and applications
� Isolation of different users, applications from each other
� Isolation of applications and operating system
� Communication between users, application
Operating System Roles: Illusionist
Illusionist
� Abstraction of hardware and other things
� Makes application design simpler
� Each application appears to have the entire machine to itself
� Illusion of
� Infinite number of processors
� (near) infinite amount of memory
� reliable storage
� reliable network transport
Operating System Roles: Glue
Glue
� Libraries, user interface widgets, . . .
Example: File Systems
� Referee
� Prevent users from accessing each other’s files without permission
� Even after a file is deleted and its space re-used
� Illusionist
� Files can grow (nearly) arbitrarily large
� Files persist even when the machine crashes in the middle of a save
Example: File Systems
� Glue
� Nam ed directories, printf, . . .
OS Design Patterns I
� OS challenges are not unique - apply to many different computing domains
� many complex software systems
� have multiple users
� run programs written by third-party developers
� need to coordinate simultaneous activities
OS Design Patterns II
Challenges:
� resource allocation
� fault isolation
� communication
� abstraction
� how to provide a set of common services
Design Criteria for OS
Design Criteria for Operating Systems
� Reliability and Availability
� Security
� Portability
� Performance
� Adoption
Design Criteria for OS
Design Criteria for Operating Systems
� Reliability and Availability
� Security
� Portability
� Performance
� Adoption
Design Criteria for OS
Design Criteria for Operating Systems
� Reliability and Availability
� Security
� Portability
� Performance
� Adoption
Design Criteria for OS
Design Criteria for Operating Systems
� Reliability and Availability
� Security
� Portability
� Performance
� Adoption
Design Criteria for OS
Design Criteria for Operating Systems
� Reliability and Availability
� Security
� Portability
� Performance
� Adoption
Design Criteria for OS
Design Criteria for Operating Systems
� Reliability and Availability
� Security
� Portability
� Performance
� Adoption
Reliability and Availability
Reliability
� It does, what it is designed to do
� Application failures can be “ok” - OS provides fault isolation and clean restart after errors
� OS errors are bad, real bad...
Reliability and Availability
Reliability
� It does, what it is designed to do
� Application failures can be “ok” - OS provides fault isolation and clean restart after errors
� OS errors are bad, real bad...
Reliability and Availability
Reliability
� It does, what it is designed to do
� Application failures can be “ok” - OS provides fault isolation and clean restart after errors
� OS errors are bad, real bad...
Reliability
Making an OS reliable is challenging
� hostile environment (viruses, malicious code take control)
� testing helps - but is much more difficult
� extremely rare corner cases can occur regularly
Reliability
Making an OS reliable is challenging
� hostile environment (viruses, malicious code take control)
� testing helps - but is much more difficult
� extremely rare corner cases can occur regularly
Availability
Availability
� Percentage of time the system is usable
� Buggy OS that loses users work is unreliable AND unavailable
� Buggy OS that never loses users work is reliable BUT unavailable
� Buggy OS that has been subverted but continues to run (and e.g. logs keystrokes and
sends them of) is available BUT unreliable
Availability
Availability
� Percentage of time the system is usable
� Buggy OS that loses users work is unreliable AND unavailable
� Buggy OS that never loses users work is reliable BUT unavailable
� Buggy OS that has been subverted but continues to run (and e.g. logs keystrokes and
sends them of) is available BUT unreliable
Availability
Availability
� Percentage of time the system is usable
� Buggy OS that loses users work is unreliable AND unavailable
� Buggy OS that never loses users work is reliable BUT unavailable
� Buggy OS that has been subverted but continues to run (and e.g. logs keystrokes and
sends them of) is available BUT unreliable
Reliability and Availability
� Reliablity and Availability are desireable
� Two factors:
MTTF: mean time to failure
MTTR: mean time to repair
Security
Security: computers operation cannot be compromised by a malicious attacker
Privacy: data stored on the computer is only accessible to authorized users
Security
� Unfortunately: no useful computer is perfectly secure!
� OS is a complex piece of software
� complex software has bugs
� bugs can be exploited
� HW may be tampered with
� Sysadmin may be untrustworthy
� SW-developer may be untrustworthy (backdoors)
Security
� OS should be designed to minimize its vulnerability to attack
� Fault isolation
� But: interaction between users and programs required
Security Policy
Security Policy defines
� who can access what data
� who can perform what operations
Enforcement
Enforcement
� ensures that policy is followed
Policies and Enforcement may possess vulnerabilities...
Enforcement
Enforcement
� ensures that policy is followed
Policies and Enforcement may possess vulnerabilities...
Portability
� OS provides an abstraction of underlying HW
does not change as the hardware changes
� Portability is an important design criteria of the OS
� don’t want to reimplement everything when HW changes
� e.g. iOS was derived from the MacOS X code base
Portability
� OS provides an abstraction of underlying HW
does not change as the hardware changes
� Portability is an important design criteria of the OS
� don’t want to reimplement everything when HW changes
� e.g. iOS was derived from the MacOS X code base
Portability
� OS provides an abstraction of underlying HW
does not change as the hardware changes
� Portability is an important design criteria of the OS
� don’t want to reimplement everything when HW changes
� e.g. iOS was derived from the MacOS X code base
Portability
� OS provides an abstraction of underlying HW
does not change as the hardware changes
� Portability is an important design criteria of the OS
� don’t want to reimplement everything when HW changes
� e.g. iOS was derived from the MacOS X code base
Portability
� OS provides an abstraction of underlying HW
does not change as the hardware changes
� Portability is an important design criteria of the OS
� don’t want to reimplement everything when HW changes
� e.g. iOS was derived from the MacOS X code base
Portability
� Lifetime of successful operating systems measured in decades
� Windows 10 based on Windows NT (started 1988)
� MS/DOS introduced 1981 - phased out ˜2000
� First Linux release 1991
Portability
� Lifetime of successful operating systems measured in decades
� Windows 10 based on Windows NT (started 1988)
� MS/DOS introduced 1981 - phased out ˜2000
� First Linux release 1991
Portability
� Lifetime of successful operating systems measured in decades
� Windows 10 based on Windows NT (started 1988)
� MS/DOS introduced 1981 - phased out ˜2000
� First Linux release 1991
Portability
� Lifetime of successful operating systems measured in decades
� Windows 10 based on Windows NT (started 1988)
� MS/DOS introduced 1981 - phased out ˜2000
� First Linux release 1991
Portability
� An OS must be designed to support
� applications that have not yet been written and
� hardware that has not been developed
� Simple, standard way for applications to interact with OS
� API
� memory access model
� instructions that can be executed
Hardware Abstraction Layer
� in older/more theoretical literature sometimes “Abstract Virtual Machine”
� provides fixed point across which both application and hardware can develop independently
Example for a highly portable OS?
Hardware Abstraction Layer
� in older/more theoretical literature sometimes “Abstract Virtual Machine”
� provides fixed point across which both application and hardware can develop independently
Example for a highly portable OS?
Performance
� Performance associated with application - OS design can affect the percieved performance
� OS decides when app can run how much memory it gets etc.
� Performance can be measured in different ways
Overhead / Efficiency
� Added (lack of) cost of implementing an abstraction presented to applications
Performance aspects
Fairness: resource allocation can impact performance
� divide resources equally - or treat some differently?
� How to decide which task gets priority?
Performance aspects
Response Time
� (delay) how long does it take for a single task to run from the time it starts to the time it
completes
� (move the mouse . . . mouse pointer reflects movement)
Throughput
� Rate at which system completes tasks
Performance aspects
Predictability
� whether systems response time is consistent over time
� can be more important than average performance
Adoption
� Success of an OS depends on adoption
� SWEB may be the best - but if no application providers support it, it remains doomed for
the this exercise
Network Effect
� value of technology does not depend only on its intrinsic capabilities but on the number of
people adopting it
Adoption
� Success of an OS depends on adoption
� SWEB may be the best - but if no application providers support it, it remains doomed for
the this exercise
Network Effect
� value of technology does not depend only on its intrinsic capabilities but on the number of
people adopting it
Adoption
� App and HW-vendors focus on OS with most users
� users favor OS with best applications or cheapest hardware
� Goal for OS: take advantage of network effect
� make it easy to accommodate new hardware
� make it easy for applications to be ported across different versions of the OS
Adoption
� API and OS source code - open? proprietary?
� Windows, MacOS: proprietary
� Linux: open
� All are widely used
Adoption
� API and OS source code - open? proprietary?
� Windows, MacOS: proprietary
� Linux: open
� All are widely used
Adoption
� API and OS source code - open? proprietary?
� Windows, MacOS: proprietary
� Linux: open
� All are widely used
Design Criteria for OS
Design Criteria for Operating Systems
� Reliability and Availability
� Security
� Portability
� Performance
� Adoption
Balance between these goals
� Improving portability can make the system less reliable and less secure
� e.g. preserving legacy interfaces
� Improving performance may add complexity and hurt reliability
Tradeoff
� Research OS in the 1980’s: use type-safe language to reduce programmer errors
� For speed: frequently used routines implemented in assembly
� Optimized sequence of instructions - but which would sometimes break if the OS exceeded
a specific size
� Initially nowhere near this limitation
� After a few years in production: random crashes occured
� Problem search took weeks ....
� Was it worth it?
History
The first computers were so called “mainframes” that had no operating systems.
Multics
� first collection of compatible utility programs (Multics [1])
� assemblers, compilers, debugging tools
� standard routines for input and output
� buffers to “spool” printer and tape output
� utilities designed to load sequence (or “batch”) of programs into memory
� automate some of the reconfiguration performed by human operators
Multics
� first collection of compatible utility programs (Multics [1])
� assemblers, compilers, debugging tools
� standard routines for input and output
� buffers to “spool” printer and tape output
� utilities designed to load sequence (or “batch”) of programs into memory
� automate some of the reconfiguration performed by human operators
Multics
� first collection of compatible utility programs (Multics [1])
� assemblers, compilers, debugging tools
� standard routines for input and output
� buffers to “spool” printer and tape output
� utilities designed to load sequence (or “batch”) of programs into memory
� automate some of the reconfiguration performed by human operators
Multics
� first collection of compatible utility programs (Multics [1])
� assemblers, compilers, debugging tools
� standard routines for input and output
� buffers to “spool” printer and tape output
� utilities designed to load sequence (or “batch”) of programs into memory
� automate some of the reconfiguration performed by human operators
Multics
� first collection of compatible utility programs (Multics [1])
� assemblers, compilers, debugging tools
� standard routines for input and output
� buffers to “spool” printer and tape output
� utilities designed to load sequence (or “batch”) of programs into memory
� automate some of the reconfiguration performed by human operators
Multics
� first collection of compatible utility programs (Multics [1])
� assemblers, compilers, debugging tools
� standard routines for input and output
� buffers to “spool” printer and tape output
� utilities designed to load sequence (or “batch”) of programs into memory
� automate some of the reconfiguration performed by human operators
Multics Concepts
still valid today in modern operating systems
� paged and segmented memory
� hierarchical file systems
� multiple processor support
� shared memory
� modularized structure
� written in a high level programming language
� and no longer in assembly.
Multics Concepts
still valid today in modern operating systems
� paged and segmented memory
� hierarchical file systems
� multiple processor support
� shared memory
� modularized structure
� written in a high level programming language
� and no longer in assembly.
Multics Concepts
still valid today in modern operating systems
� paged and segmented memory
� hierarchical file systems
� multiple processor support
� shared memory
� modularized structure
� written in a high level programming language
� and no longer in assembly.
Multics Concepts
still valid today in modern operating systems
� paged and segmented memory
� hierarchical file systems
� multiple processor support
� shared memory
� modularized structure
� written in a high level programming language
� and no longer in assembly.
Multics Concepts
still valid today in modern operating systems
� paged and segmented memory
� hierarchical file systems
� multiple processor support
� shared memory
� modularized structure
� written in a high level programming language
� and no longer in assembly.
Multics Concepts
still valid today in modern operating systems
� paged and segmented memory
� hierarchical file systems
� multiple processor support
� shared memory
� modularized structure
� written in a high level programming language
� and no longer in assembly.
Multics Concepts
still valid today in modern operating systems
� paged and segmented memory
� hierarchical file systems
� multiple processor support
� shared memory
� modularized structure
� written in a high level programming language
� and no longer in assembly.
UNIX et al.
� Multics never gained critical mass in the market place
� Ken Thompson and Dennis Ritchie started working on an OS for microcomputers: UNIX
� by programmers - for programmers
� originally in assembly language
� rewritten in C
� portable operating system!
UNIX et al.
� Multics never gained critical mass in the market place
� Ken Thompson and Dennis Ritchie started working on an OS for microcomputers: UNIX
� by programmers - for programmers
� originally in assembly language
� rewritten in C
� portable operating system!
UNIX et al.
� Multics never gained critical mass in the market place
� Ken Thompson and Dennis Ritchie started working on an OS for microcomputers: UNIX
� by programmers - for programmers
� originally in assembly language
� rewritten in C
� portable operating system!
UNIX et al.
� Multics never gained critical mass in the market place
� Ken Thompson and Dennis Ritchie started working on an OS for microcomputers: UNIX
� by programmers - for programmers
� originally in assembly language
� rewritten in C
� portable operating system!
UNIX et al.
� Multics never gained critical mass in the market place
� Ken Thompson and Dennis Ritchie started working on an OS for microcomputers: UNIX
� by programmers - for programmers
� originally in assembly language
� rewritten in C
� portable operating system!
UNIX et al.
� Multics never gained critical mass in the market place
� Ken Thompson and Dennis Ritchie started working on an OS for microcomputers: UNIX
� by programmers - for programmers
� originally in assembly language
� rewritten in C
� portable operating system!
IBM’s OS/360
Pugh et al. [2]
� concept that the OS keeps track of all of the system resources that are used, including
� program and data space allocation in main memory
� file space in secondary storage
� file locking during update
Evolution of Operating Systems
Phase Idea
Open shop operating systems
Batch processing tape batching, first-in/first -out scheduling
Multiprogramming processor multiplexing, atomic operations, demand paging, I/O
spooling, priority scheduling, remote job entry
Timesharing simultaneous user interactions, on-line file systems
Concurrent programming hierarchical systems, extensible kernels, parallel programming
Personal Computing graphical user interface
Distributed Systems remote servers
Personal Computing
1968: First devices named “personal computer” (actually a calculator)
PCs
1973: Xerox Alto, first computer with mouse, desktop, and GUI
PC Operating Systems
� Different requirements: only one user
� CP/M, DOS, Apple-DOS
� Windows
� OS-2, Windows-XP, OS-X, Linux....
Booting
Starting in Real Mode
� 16 bit mode
� Address space: 1 MB
� How is that possible?
� CS register has a 20-bit base address
� actually only 4 bit, but shifted by 16 bits to the left
→ 4 bits (base/prefix) + 16 bits (address/offset) = 20 bit address
Starting in Real Mode
� 16 bit mode
� Address space: 1 MB
� How is that possible?
� CS register has a 20-bit base address
� actually only 4 bit, but shifted by 16 bits to the left
→ 4 bits (base/prefix) + 16 bits (address/offset) = 20 bit address
Starting in Real Mode
� 16 bit mode
� Address space: 1 MB
� How is that possible?
� CS register has a 20-bit base address
� actually only 4 bit, but shifted by 16 bits to the left
→ 4 bits (base/prefix) + 16 bits (address/offset) = 20 bit address
Starting in Real Mode
� 16 bit mode
� Address space: 1 MB
� How is that possible?
� CS register has a 20-bit base address
� actually only 4 bit, but shifted by 16 bits to the left
→ 4 bits (base/prefix) + 16 bits (address/offset) = 20 bit address
Starting in Real Mode
� 16 bit mode
� Address space: 1 MB
� How is that possible?
� CS register has a 20-bit base address
� actually only 4 bit, but shifted by 16 bits to the left
→ 4 bits (base/prefix) + 16 bits (address/offset) = 20 bit address
Starting in Real Mode
� 16 bit mode
� Address space: 1 MB
� How is that possible?
� CS register has a 20-bit base address
� actually only 4 bit, but shifted by 16 bits to the left
→ 4 bits (base/prefix) + 16 bits (address/offset) = 20 bit address
Booting x86 Intel
Booting in Real Mode
� Address: 0xFFFFFFF0
� How is that possible?
� CS register also has a 32-bit base address (initialized to 0xFFFF0000)
� What if I have < 4GB RAM?
� physical address space 6= RAM directly mapped
Booting in Real Mode
� Address: 0xFFFFFFF0
� How is that possible?
� CS register also has a 32-bit base address (initialized to 0xFFFF0000)
� What if I have < 4GB RAM?
� physical address space 6= RAM directly mapped
Booting in Real Mode
� Address: 0xFFFFFFF0
� How is that possible?
� CS register also has a 32-bit base address (initialized to 0xFFFF0000)
� What if I have < 4GB RAM?
� physical address space 6= RAM directly mapped
Booting in Real Mode
� Address: 0xFFFFFFF0
� How is that possible?
� CS register also has a 32-bit base address (initialized to 0xFFFF0000)
� What if I have < 4GB RAM?
� physical address space 6= RAM directly mapped
Booting in Real Mode
� Address: 0xFFFFFFF0
� How is that possible?
� CS register also has a 32-bit base address (initialized to 0xFFFF0000)
� What if I have < 4GB RAM?
� physical address space 6= RAM directly mapped
Physical Address Space
00000000-007fffff (prio 0, RW): alias ram-below-4g (this is our RAM)
000a0000-000bffff (prio 1, RW): vga-lowmem (remember for later)
000c0000-000dffff (prio 1, RW): pc.rom
000e0000-000fffff (prio 1, R-): alias isa-bios
fd000000-fdffffff (prio 1, RW): vga.vram
febc0000-febdffff (prio 1, RW): e1000-mmio
febf0400-febf041f (prio 0, RW): vga ioports remapped
febf0500-febf0515 (prio 0, RW): bochs dispi interface
febf0600-febf0607 (prio 0, RW): qemu extended regs
fffc0000-ffffffff (prio 0, R-): pc.bios (ahhh!)
...
BIOS
� BIOS initializes hardware platform
� Switch to protected mode (32 bit)
� Select a device to boot from
� Load MBR from device into memory
� Execute code from MBR
BIOS
� BIOS initializes hardware platform
� Switch to protected mode (32 bit)
� Select a device to boot from
� Load MBR from device into memory
� Execute code from MBR
BIOS
� BIOS initializes hardware platform
� Switch to protected mode (32 bit)
� Select a device to boot from
� Load MBR from device into memory
� Execute code from MBR
BIOS
� BIOS initializes hardware platform
� Switch to protected mode (32 bit)
� Select a device to boot from
� Load MBR from device into memory
� Execute code from MBR
BIOS
� BIOS initializes hardware platform
� Switch to protected mode (32 bit)
� Select a device to boot from
� Load MBR from device into memory
� Execute code from MBR
Booting x86 Intel (Illustration)
GRUB
� Boot loader for Linux, SWEB, . . .
� Loads the OS image from disk and starts OS
GRUBOne of the important features in GRUB is flexibility; GRUB understands file-systems and kernel
executable formats, so you can load an arbitrary operating system the way you like, without
recording the physical position of your kernel on the disk. Thus you can load the kernel just by
specifying its file name and the drive and partition where the kernel resides.
Booting
Booting the OS
� Prepare hardware
� Start device drivers and initialize devices
� Start initial processes (e.g. init-process)
Booting the OS
� Prepare hardware
� Start device drivers and initialize devices
� Start initial processes (e.g. init-process)
Booting the OS
� Prepare hardware
� Start device drivers and initialize devices
� Start initial processes (e.g. init-process)
Booting the OS (SWEB)
Kernel is a compiled binary (e.g. an ELF binary)
% readelf -a kernel.x | grep Entry
Entry point address: 0x801001ba
% objdump -S kernel.x | less
801001ba <entry>:
801001ba: 55 push %ebp
801001bb: 89 e5 mov %esp,%ebp
801001bd: 83 ec 10 sub $0x10,%esp
801001c0: 89 1d 00 90 14 00 mov %ebx,0x149000
Wait, that’s C-Code!
Booting the OS (SWEB)
Kernel is a compiled binary (e.g. an ELF binary)
% readelf -a kernel.x | grep Entry
Entry point address: 0x801001ba
% objdump -S kernel.x | less
801001ba <entry>:
801001ba: 55 push %ebp
801001bb: 89 e5 mov %esp,%ebp
801001bd: 83 ec 10 sub $0x10,%esp
801001c0: 89 1d 00 90 14 00 mov %ebx,0x149000
Wait, that’s C-Code!
Booting the OS (SWEB)
Kernel is a compiled binary (e.g. an ELF binary)
% readelf -a kernel.x | grep Entry
Entry point address: 0x801001ba
% objdump -S kernel.x | less
801001ba <entry>:
801001ba: 55 push %ebp
801001bb: 89 e5 mov %esp,%ebp
801001bd: 83 ec 10 sub $0x10,%esp
801001c0: 89 1d 00 90 14 00 mov %ebx,0x149000
Wait, that’s C-Code!
Booting the OS (SWEB)
Kernel is a compiled binary (e.g. an ELF binary)
% readelf -a kernel.x | grep Entry
Entry point address: 0x801001ba
% objdump -S kernel.x | less
801001ba <entry>:
801001ba: 55 push %ebp
801001bb: 89 e5 mov %esp,%ebp
801001bd: 83 ec 10 sub $0x10,%esp
801001c0: 89 1d 00 90 14 00 mov %ebx,0x149000
Wait, that’s C-Code!
Booting the OS (SWEB)
extern "C" void entry()
{
asm("mov %ebx,multi_boot_structure_pointer - BASE");
PRINT("Booting...\n");
Booting the OS (SWEB)
PRINT("Clearing Framebuffer...\n");
memset((char*) 0xB8000, 0, 80 * 25 * 2);
PRINT("Clearing BSS...\n");
char* bss_start = TRUNCATE(&bss_start_address);
memset(bss_start, 0, TRUNCATE(&bss_end_address) - bss_start);
PRINT("Initializing Kernel Paging Structures...\n");
//...
Booting the OS (SWEB)
PRINT("Enable PSE and PAE...\n");
asm("mov %cr4,%eax\n"
"or $0x20, %eax\n"
"mov %eax,%cr4\n");
PRINT("Setting CR3 Register...\n");
asm("mov %[pd],%%cr3" : : [pd]"r"(TRUNCATE(kernel_page_map_level_4)));
PRINT("Enable EFER.LME and EFER.NXE...\n");
asm("mov $0xC0000080,%ecx\n"
"rdmsr\n"
"or $0x900,%eax\n"
"wrmsr\n");
//...
PRINT("Enable Paging...\n");
asm("mov %cr0,%eax\n"
"or $0x80000001,%eax\n"
"mov %eax,%cr0\n");
Booting the OS (SWEB)
PRINT("Setup TSS...\n");
TSS* g_tss_p = (TSS*) TRUNCATE(&g_tss);
g_tss_p->ist0_h = -1U;
g_tss_p->ist0_l = (uint32) TRUNCATE(boot_stack) | 0x80004000;
g_tss_p->rsp0_h = -1U;
g_tss_p->rsp0_l = (uint32) TRUNCATE(boot_stack) | 0x80004000;
Booting the OS (SWEB)
Booting the OS (SWEB)
Booting the OS (SWEB)
static void setSegmentDescriptor(uint32 index, uint32 baseH, uint32 baseL, uint32
limit, uint8 dpl, uint8 code, uint8 tss);
PRINT("Setup Segments...\n");
setSegmentDescriptor(1, 0, 0, 0, 0, 1, 0);
setSegmentDescriptor(2, 0, 0, 0, 0, 0, 0);
setSegmentDescriptor(3, 0, 0, 0, 3, 1, 0);
setSegmentDescriptor(4, 0, 0, 0, 3, 0, 0);
setSegmentDescriptor(5, -1U, (uint32) TRUNCATE(&g_tss) | 0x80000000,
sizeof(TSS) - 1, 0, 0, 1);
PRINT("Loading Long Mode GDT...\n");
struct GDT32Ptr gdt32_ptr;
gdt32_ptr.limit = sizeof(gdt) - 1;
gdt32_ptr.addr = (uint32) TRUNCATE(gdt);
asm("lgdt %[gdt_ptr]" : : [gdt_ptr]"m"(gdt32_ptr));
// ...
Booting the OS (SWEB)
PRINT("Setting Long Mode Segment Selectors...\n");
asm("mov %%ax, %%ds\n"
"mov %%ax, %%es\n"
"mov %%ax, %%ss\n"
"mov %%ax, %%fs\n"
"mov %%ax, %%gs\n"
: : "a"(KERNEL_DS));
PRINT("Calling entry64()...\n");
asm("ljmp %[cs],$entry64-BASE\n" : : [cs]"i"(KERNEL_CS));
PRINT("Returned from entry64()? This should never happen.\n");
asm("hlt");}
Booting the OS (SWEB)
PRINT("Setting Long Mode Segment Selectors...\n");
asm("mov %%ax, %%ds\n"
"mov %%ax, %%es\n"
"mov %%ax, %%ss\n"
"mov %%ax, %%fs\n"
"mov %%ax, %%gs\n"
: : "a"(KERNEL_DS));
PRINT("Calling entry64()...\n");
asm("ljmp %[cs],$entry64-BASE\n" : : [cs]"i"(KERNEL_CS));
PRINT("Returned from entry64()? This should never happen.\n");
asm("hlt");}
Booting the OS (SWEB)
extern "C" void entry64()
{
PRINT("Parsing Multiboot Header...\n");
parseMultibootHeader();
PRINT("Initializing Kernel Paging Structures...\n");
initialisePaging();
PRINT("Setting CR3 Register...\n");
asm("mov %%rax, %%cr3" : : "a"(VIRTUAL_TO_PHYSICAL_BOOT(ArchMemory::
getRootOfKernelPagingStructure())));
PRINT("Switch to our own stack...\n");
asm("mov %[stack], %%rsp\n"
"mov %[stack], %%rbp\n" : : [stack]"i"(boot_stack + 0x4000));
Booting the OS (SWEB)
PRINT("Loading Long Mode Segments...\n");
gdt_ptr.limit = sizeof(gdt) - 1;
gdt_ptr.addr = (uint64)gdt;
asm("lgdt (%%rax)" : : "a"(&gdt_ptr));
asm("mov %%ax, %%ds\n"
"mov %%ax, %%es\n"
"mov %%ax, %%ss\n"
"mov %%ax, %%fs\n"
"mov %%ax, %%gs\n"
: : "a"(KERNEL_DS));
asm("ltr %%ax" : : "a"(KERNEL_TSS));
PRINT("Calling startup()...\n");
asm("jmp *%[startup]" : : [startup]"r"(startup));
while (1);
}
Booting the OS (SWEB)
extern "C" void startup()
{
writeLine2Bochs("Removing Boot Time Ident Mapping...\n");
removeBootTimeIdentMapping();
system_state = BOOTING;
PageManager::instance();
writeLine2Bochs("PageManager and KernelMemoryManager created \n");
main_console = ArchCommon::createConsole(1);
writeLine2Bochs("Console created \n");
// ...
Booting the OS (SWEB)
Scheduler::instance();
//needs to be done after scheduler and terminal, but prior to enableInterrupts
kprintf_init();
debug(MAIN, "Threads init\n");
ArchThreads::initialise();
debug(MAIN, "Interupts init\n");
ArchInterrupts::initialise();
ArchInterrupts::setTimerFrequency(IRQ0_TIMER_FREQUENCY);
Booting the OS (SWEB)
ArchCommon::initDebug();
vfs.initialize();
debug(MAIN, "Mounting DeviceFS under /dev/\n");
DeviceFSType *devfs = new DeviceFSType();
vfs.registerFileSystem(devfs);
default_working_dir = vfs.root_mount("devicefs", 0);
debug(MAIN, "Block Device creation\n");
BDManager::getInstance()->doDeviceDetection();
debug(MAIN, "Block Device done\n");
for (BDVirtualDevice* bdvd : BDManager::getInstance()->device_list_)
{
debug(MAIN, "Detected Device: %s :: %d\n", bdvd->getName(), bdvd->
getDeviceNumber());
}
Booting the OS (SWEB)
// initialise global and static objects
extern ustl::list<FileDescriptor*> global_fd;
new (&global_fd) ustl::list<FileDescriptor*>();
extern Mutex global_fd_lock;
new (&global_fd_lock) Mutex("global_fd_lock");
// ...
debug(MAIN, "Timer enable\n");
ArchInterrupts::enableTimer();
KeyboardManager::instance();
ArchInterrupts::enableKBD();
Booting the OS (SWEB)
debug(MAIN, "Adding Kernel threads\n");
Scheduler::instance()->addNewThread(main_console);
Scheduler::instance()->addNewThread(new ProcessRegistry(new FileSystemInfo(*default_working_dir), user_progs /*see user_progs.h*/));
Scheduler::instance()->printThreadList();
kprintf("Now enabling Interrupts...\n");
system_state = RUNNING;
ArchInterrupts::enableInterrupts();
Scheduler::instance()->yield();
//not reached
assert(false);}
Booting
Process and Thread
Fundamentals
Program, Process, Thread
� A program: a binary file containing code and data
� actions: write, compile, install, load
� resources: file
� A thread: an execution context
� actions: run, interrupt, stop
� resources: CPU time, stack, registers
� A process: a container for threads and memory contents of a program
� actions: create, start, terminate
� resources: threads, memory, program
Program, Process, Thread
� A program: a binary file containing code and data
� actions: write, compile, install, load
� resources: file
� A thread: an execution context
� actions: run, interrupt, stop
� resources: CPU time, stack, registers
� A process: a container for threads and memory contents of a program
� actions: create, start, terminate
� resources: threads, memory, program
Program, Process, Thread
� A program: a binary file containing code and data
� actions: write, compile, install, load
� resources: file
� A thread: an execution context
� actions: run, interrupt, stop
� resources: CPU time, stack, registers
� A process: a container for threads and memory contents of a program
� actions: create, start, terminate
� resources: threads, memory, program
Program, Process, Thread
� A program: a binary file containing code and data
� actions: write, compile, install, load
� resources: file
� A thread: an execution context
� actions: run, interrupt, stop
� resources: CPU time, stack, registers
� A process: a container for threads and memory contents of a program
� actions: create, start, terminate
� resources: threads, memory, program
Program, Process, Thread
� A program: a binary file containing code and data
� actions: write, compile, install, load
� resources: file
� A thread: an execution context
� actions: run, interrupt, stop
� resources: CPU time, stack, registers
� A process: a container for threads and memory contents of a program
� actions: create, start, terminate
� resources: threads, memory, program
Program, Process, Thread
� A program: a binary file containing code and data
� actions: write, compile, install, load
� resources: file
� A thread: an execution context
� actions: run, interrupt, stop
� resources: CPU time, stack, registers
� A process: a container for threads and memory contents of a program
� actions: create, start, terminate
� resources: threads, memory, program
Program, Process, Thread
� A program: a binary file containing code and data
� actions: write, compile, install, load
� resources: file
� A thread: an execution context
� actions: run, interrupt, stop
� resources: CPU time, stack, registers
� A process: a container for threads and memory contents of a program
� actions: create, start, terminate
� resources: threads, memory, program
Program, Process, Thread
� A program: a binary file containing code and data
� actions: write, compile, install, load
� resources: file
� A thread: an execution context
� actions: run, interrupt, stop
� resources: CPU time, stack, registers
� A process: a container for threads and memory contents of a program
� actions: create, start, terminate
� resources: threads, memory, program
Program, Process, Thread
� A program: a binary file containing code and data
� actions: write, compile, install, load
� resources: file
� A thread: an execution context
� actions: run, interrupt, stop
� resources: CPU time, stack, registers
� A process: a container for threads and memory contents of a program
� actions: create, start, terminate
� resources: threads, memory, program
Abstractions
� Process: abstraction of a computer
� File: abstraction of a disk or a device
� Socket: abstraction of a network connection
� Window: abstraction of a display
→ Abstractions hide many details but provide the required capabilities
Abstractions
� Process: abstraction of a computer
� File: abstraction of a disk or a device
� Socket: abstraction of a network connection
� Window: abstraction of a display
→ Abstractions hide many details but provide the required capabilities
Abstractions
� Process: abstraction of a computer
� File: abstraction of a disk or a device
� Socket: abstraction of a network connection
� Window: abstraction of a display
→ Abstractions hide many details but provide the required capabilities
Abstractions
� Process: abstraction of a computer
� File: abstraction of a disk or a device
� Socket: abstraction of a network connection
� Window: abstraction of a display
→ Abstractions hide many details but provide the required capabilities
Abstractions
� Process: abstraction of a computer
� File: abstraction of a disk or a device
� Socket: abstraction of a network connection
� Window: abstraction of a display
→ Abstractions hide many details but provide the required capabilities
Abstractions
� Process: abstraction of a computer
� File: abstraction of a disk or a device
� Socket: abstraction of a network connection
� Window: abstraction of a display
→ Abstractions hide many details but provide the required capabilities
CPU vs. Process
CPU vs. Process
Processes
Implemented by the kernel
Implementation?
� We have “one hardware”
� We have many “processes”
� How do we solve this?
The Process Abstraction
Program, Process, Thread
� Once a program is loaded in memory, OS can start it(s first thread) by
� setting up a stack and setting the stack pointer and
� setting the instruction pointer (of the first thread) to the programs first instruction
� Process is an instance of a program
� Kernel must organize running code of multiple processes
� Must be able to switch from one process to another
� OS keeps a list of process data structure (aka the “PCB”)
Program, Process, Thread
� Once a program is loaded in memory, OS can start it(s first thread) by
� setting up a stack and setting the stack pointer and
� setting the instruction pointer (of the first thread) to the programs first instruction
� Process is an instance of a program
� Kernel must organize running code of multiple processes
� Must be able to switch from one process to another
� OS keeps a list of process data structure (aka the “PCB”)
Program, Process, Thread
� Once a program is loaded in memory, OS can start it(s first thread) by
� setting up a stack and setting the stack pointer and
� setting the instruction pointer (of the first thread) to the programs first instruction
� Process is an instance of a program
� Kernel must organize running code of multiple processes
� Must be able to switch from one process to another
� OS keeps a list of process data structure (aka the “PCB”)
Program, Process, Thread
� Once a program is loaded in memory, OS can start it(s first thread) by
� setting up a stack and setting the stack pointer and
� setting the instruction pointer (of the first thread) to the programs first instruction
� Process is an instance of a program
� Kernel must organize running code of multiple processes
� Must be able to switch from one process to another
� OS keeps a list of process data structure (aka the “PCB”)
Program, Process, Thread
� Once a program is loaded in memory, OS can start it(s first thread) by
� setting up a stack and setting the stack pointer and
� setting the instruction pointer (of the first thread) to the programs first instruction
� Process is an instance of a program
� Kernel must organize running code of multiple processes
� Must be able to switch from one process to another
� OS keeps a list of process data structure (aka the “PCB”)
Program, Process, Thread
� Once a program is loaded in memory, OS can start it(s first thread) by
� setting up a stack and setting the stack pointer and
� setting the instruction pointer (of the first thread) to the programs first instruction
� Process is an instance of a program
� Kernel must organize running code of multiple processes
� Must be able to switch from one process to another
� OS keeps a list of process data structure (aka the “PCB”)
Program, Process, Thread
� Once a program is loaded in memory, OS can start it(s first thread) by
� setting up a stack and setting the stack pointer and
� setting the instruction pointer (of the first thread) to the programs first instruction
� Process is an instance of a program
� Kernel must organize running code of multiple processes
� Must be able to switch from one process to another
� OS keeps a list of process data structure (aka the “PCB”)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process List (aka PCB)
Process list stores
� where program is loaded in memory
� where image is on disk
� which user asked to execute
� what privileges the process has
� etc.
� Process ID
� User ID
� Process status
� Scheduling information
� I/O resources
Process can have multiple threads
� same program code and data
� own stack
� own registers (including instruction pointer)
Process Protection Mechanisms
How can it be safe to run untrusted software on your hardware?
Challenges:
� Threads of a process run code
� What code?
� Do we trust that code?
� Maybe buggy?
Malicious?
� We want to give the program restricted privileges
� How can we do that?
How can it be safe to run untrusted software on your hardware?
Challenges:
� Threads of a process run code
� What code?
� Do we trust that code?
� Maybe buggy?
Malicious?
� We want to give the program restricted privileges
� How can we do that?
How can it be safe to run untrusted software on your hardware?
Challenges:
� Threads of a process run code
� What code?
� Do we trust that code?
� Maybe buggy?
Malicious?
� We want to give the program restricted privileges
� How can we do that?
How can it be safe to run untrusted software on your hardware?
Challenges:
� Threads of a process run code
� What code?
� Do we trust that code?
� Maybe buggy?
Malicious?
� We want to give the program restricted privileges
� How can we do that?
How can it be safe to run untrusted software on your hardware?
Challenges:
� Threads of a process run code
� What code?
� Do we trust that code?
� Maybe buggy?
Malicious?
� We want to give the program restricted privileges
� How can we do that?
How can it be safe to run untrusted software on your hardware?
Challenges:
� Threads of a process run code
� What code?
� Do we trust that code?
� Maybe buggy? Malicious?
� We want to give the program restricted privileges
� How can we do that?
How can it be safe to run untrusted software on your hardware?
Challenges:
� Threads of a process run code
� What code?
� Do we trust that code?
� Maybe buggy? Malicious?
� We want to give the program restricted privileges
� How can we do that?
Privileged and unprivileged instructions
� Most instructions cannot do any harm
� Some instructions can
asm("cli");asm("hlt");
Privileged and unprivileged instructions
� Most instructions cannot do any harm
� Some instructions can
asm("cli");asm("hlt");
Privileged and unprivileged instructions
� Most instructions cannot do any harm
� Some instructions can
asm("cli");asm("hlt");
Examples for Privileged Instructions (Intel)
� LGDT: Load GDT register
� LLDT: Load LDT register
� LTR: Load task register
� LIDT: Load IDT register
� MOV (control registers): Load and store control registers
� LMSW: Load machine status word
� CLTS: Clear task-switched flag in register CR0
� MOV (debug registers): Load and store debug registers
� INVD: Invalidate cache, without writeback
� WBINVD: Invalidate cache, with writeback
� INVLPG: Invalidate TLB entry
� HLT: Halt processor
� RDMSR: Read Model-Specific Registers
� WRMSR: Write Model-Specific Registers
Dual-mode operation
� User-mode: limited privileges
� Kernel-mode: complete privileges
Recall: DPL defined in segment descriptor
� User-mode: DPL = 3
� Kernel-mode: DPL = 0
→ hardware-assisted control mechanisms
Dual-mode operation
� User-mode: limited privileges
� Kernel-mode: complete privileges
Recall: DPL defined in segment descriptor
� User-mode: DPL = 3
� Kernel-mode: DPL = 0
→ hardware-assisted control mechanisms
Dual-mode operation
� User-mode: limited privileges
� Kernel-mode: complete privileges
Recall: DPL defined in segment descriptor
� User-mode: DPL = 3
� Kernel-mode: DPL = 0
→ hardware-assisted control mechanisms
Hardware Support: Dual-Mode
Kernel Mode: User Mode:
Hardware Support: Dual-Mode
Kernel Mode:
� OS runs in kernel modeUser Mode:
� User programs run in user mode
Hardware Support: Dual-Mode
Kernel Mode:
� OS runs in kernel mode
� Full privileges for hardware accesses
User Mode:
� User programs run in user mode
� Limited privileges
Hardware Support: Dual-Mode
Kernel Mode:
� OS runs in kernel mode
� Full privileges for hardware accesses
� Read/write to any memory
User Mode:
� User programs run in user mode
� Limited privileges
� Some instructions and memory regions are not
accessible
Hardware Support: Dual-Mode
Kernel Mode:
� OS runs in kernel mode
� Full privileges for hardware accesses
� Read/write to any memory
� Access to any I/O-device
User Mode:
� User programs run in user mode
� Limited privileges
� Some instructions and memory regions are not
accessible
� If tried anyway: exception is raised by the CPU.
Hardware Support: Dual-Mode
Kernel Mode:
� OS runs in kernel mode
� Full privileges for hardware accesses
� Read/write to any memory
� Access to any I/O-device
� Access to all disk content
User Mode:
� User programs run in user mode
� Limited privileges
� Some instructions and memory regions are not
accessible
� If tried anyway: exception is raised by the CPU.
� Need something user mode can’t do?
Hardware Support: Dual-Mode
Kernel Mode:
� OS runs in kernel mode
� Full privileges for hardware accesses
� Read/write to any memory
� Access to any I/O-device
� Access to all disk content
� Access to all network traffic
User Mode:
� User programs run in user mode
� Limited privileges
� Some instructions and memory regions are not
accessible
� If tried anyway: exception is raised by the CPU.
� Need something user mode can’t do?
→ ask operating system for help
Hardware Support: Dual-Mode
Kernel Mode:
� OS runs in kernel mode
� Full privileges for hardware accesses
� Read/write to any memory
� Access to any I/O-device
� Access to all disk content
� Access to all network traffic
User Mode:
� User programs run in user mode
� Limited privileges
� Some instructions and memory regions are not
accessible
� If tried anyway: exception is raised by the CPU.
� Need something user mode can’t do?
→ “call” operating system for help
Hardware Support: Dual-Mode
Kernel Mode:
� OS runs in kernel mode
� Full privileges for hardware accesses
� Read/write to any memory
� Access to any I/O-device
� Access to all disk content
� Access to all network traffic
User Mode:
� User programs run in user mode
� Limited privileges
� Some instructions and memory regions are not
accessible
� If tried anyway: exception is raised by the CPU.
� Need something user mode can’t do?
→ “call” operating system for help
→ system call
Hardware Support: Dual-Mode Implementation
� mode stored in EFLAGS register
� segment descriptors
� paging structures
� . . .
IA-32 Ring Structure
How to change from ring to ring . . .
� change from kernel mode (lower level ring) to user mode (higher level ring) not a problem
How to change from ring to ring . . .
� change from kernel mode (lower level ring) to user mode (higher level ring) not a problem
� change from user mode (higher level ring) to kernel mode (lower level ring) must be a
controlled procedure
How to change from ring to ring . . .
� change from kernel mode (lower level ring) to user mode (higher level ring) not a problem
� change from user mode (higher level ring) to kernel mode (lower level ring) must be a
controlled procedure
→ Otherwise there would be no protection
How to change from ring to ring . . .
� change from ring 0 to ring 3 not a problem
� change from user mode (higher level ring) to kernel mode (lower level ring) must be a
controlled procedure
→ Otherwise there would be no protection
How to change from ring to ring . . .
� change from ring 0 to ring 3 not a problem
� change from ring 3 to ring 0 through controlled procedure
→ Otherwise there would be no protection
How to change from ring to ring . . .
� change from ring 0 to ring 3 through special return instruction (iret)
� change from ring 3 to ring 0 through controlled procedure
→ Otherwise there would be no protection
How to change from ring to ring . . .
� change from ring 0 to ring 3 through special return instruction (iret)
� change from ring 3 to ring 0 through int 0x80, sysenter, or syscall
→ Otherwise there would be no protection
Interrupts
� either generated by the software (e.g. syscall)
� or by the hardware
� timer
� I/O-devices
� exceptions (divide-by-zero, page fault, etc.)
Interrupts
� either generated by the software (e.g. syscall)
� or by the hardware
� timer
� I/O-devices
� exceptions (divide-by-zero, page fault, etc.)
Interrupts
� either generated by the software (e.g. syscall)
� or by the hardware
� timer
� I/O-devices
� exceptions (divide-by-zero, page fault, etc.)
Interrupts
� either generated by the software (e.g. syscall)
� or by the hardware
� timer
� I/O-devices
� exceptions (divide-by-zero, page fault, etc.)
Interrupts
� either generated by the software (e.g. syscall)
� or by the hardware
� timer
� I/O-devices
� exceptions (divide-by-zero, page fault, etc.)
Interrupts and Stacks
� Interrupts switch stack to a kernel stack
� Why?
� Security and stability
� Who knows where the users SP points
� Maybe SP points to illegal address
� Would raises an page fault exception (in the kernel)
� Some register values are pushed to stack by the CPU during a context switch
� How many stacks do we actually need?
� Do we need multiple stacks for the kernel?
Interrupts and Stacks
� Interrupts switch stack to a kernel stack
� Why?
� Security and stability
� Who knows where the users SP points
� Maybe SP points to illegal address
� Would raises an page fault exception (in the kernel)
� Some register values are pushed to stack by the CPU during a context switch
� How many stacks do we actually need?
� Do we need multiple stacks for the kernel?
Interrupts and Stacks
� Interrupts switch stack to a kernel stack
� Why?
� Security and stability
� Who knows where the users SP points
� Maybe SP points to illegal address
� Would raises an page fault exception (in the kernel)
� Some register values are pushed to stack by the CPU during a context switch
� How many stacks do we actually need?
� Do we need multiple stacks for the kernel?
Interrupts and Stacks
� Interrupts switch stack to a kernel stack
� Why?
� Security and stability
� Who knows where the users SP points
� Maybe SP points to illegal address
� Would raises an page fault exception (in the kernel)
� Some register values are pushed to stack by the CPU during a context switch
� How many stacks do we actually need?
� Do we need multiple stacks for the kernel?
Interrupts and Stacks
� Interrupts switch stack to a kernel stack
� Why?
� Security and stability
� Who knows where the users SP points
� Maybe SP points to illegal address
� Would raises an page fault exception (in the kernel)
� Some register values are pushed to stack by the CPU during a context switch
� How many stacks do we actually need?
� Do we need multiple stacks for the kernel?
Interrupts and Stacks
� Interrupts switch stack to a kernel stack
� Why?
� Security and stability
� Who knows where the users SP points
� Maybe SP points to illegal address
� Would raises an page fault exception (in the kernel)
� Some register values are pushed to stack by the CPU during a context switch
� How many stacks do we actually need?
� Do we need multiple stacks for the kernel?
Interrupts and Stacks
� Interrupts switch stack to a kernel stack
� Why?
� Security and stability
� Who knows where the users SP points
� Maybe SP points to illegal address
� Would raises an page fault exception (in the kernel)
� Some register values are pushed to stack by the CPU during a context switch
� How many stacks do we actually need?
� Do we need multiple stacks for the kernel?
Interrupts and Stacks
� Interrupts switch stack to a kernel stack
� Why?
� Security and stability
� Who knows where the users SP points
� Maybe SP points to illegal address
� Would raises an page fault exception (in the kernel)
� Some register values are pushed to stack by the CPU during a context switch
� How many stacks do we actually need?
� Do we need multiple stacks for the kernel?
Interrupts and Stacks
� Interrupts switch stack to a kernel stack
� Why?
� Security and stability
� Who knows where the users SP points
� Maybe SP points to illegal address
� Would raises an page fault exception (in the kernel)
� Some register values are pushed to stack by the CPU during a context switch
� How many stacks do we actually need?
� Do we need multiple stacks for the kernel?
Stacks
Stacks
Stacks
User
Sta
ck
Kerr
nel Sta
ck
main
procedure 1
procedure 2
main
procedure 1
procedure 2
CPU state
user mode
main
procedure 1
procedure 2
system call
CPU state
user mode
Syscall
handler
I/O-Driver
Running Ready to Run Blocked
Context Switches
Threads. Multiple Threads.
� one CPU / core: one active thread at any point in time
� how to switch between threads?
� how do we let a CPU / core execute a different function?
� change the instruction pointer?
how?
Threads. Multiple Threads.
� one CPU / core: one active thread at any point in time
� how to switch between threads?
� how do we let a CPU / core execute a different function?
� change the instruction pointer?
how?
Threads. Multiple Threads.
� one CPU / core: one active thread at any point in time
� how to switch between threads?
� how do we let a CPU / core execute a different function?
� change the instruction pointer?
how?
Threads. Multiple Threads.
� one CPU / core: one active thread at any point in time
� how to switch between threads?
� how do we let a CPU / core execute a different function?
� change the instruction pointer?
how?
Threads. Multiple Threads.
� one CPU / core: one active thread at any point in time
� how to switch between threads?
� how do we let a CPU / core execute a different function?
� change the instruction pointer?
how?
Threads. Multiple Threads.
� one CPU / core: one active thread at any point in time
� how to switch between threads?
� how do we let a CPU / core execute a different function?
� change the instruction pointer? how?
Threads. Multiple Threads.
Changing the instruction pointer
asm("jmp *%[other_thread_function]"
:
: [other_thread_function]"r"(other_thread_function));
does this work? Yes, but . . .
� what if the thread is in another process?
� scheduling thread slices: how do we later restore the state we came from?
� what if we’re coming from kernelspace?
Threads. Multiple Threads.
Changing the instruction pointer
asm("jmp *%[other_thread_function]"
:
: [other_thread_function]"r"(other_thread_function));
does this work? Yes, but . . .
� what if the thread is in another process?
� scheduling thread slices: how do we later restore the state we came from?
� what if we’re coming from kernelspace?
Threads. Multiple Threads.
Changing the instruction pointer
asm("jmp *%[other_thread_function]"
:
: [other_thread_function]"r"(other_thread_function));
does this work?
Yes, but . . .
� what if the thread is in another process?
� scheduling thread slices: how do we later restore the state we came from?
� what if we’re coming from kernelspace?
Threads. Multiple Threads.
Changing the instruction pointer
asm("jmp *%[other_thread_function]"
:
: [other_thread_function]"r"(other_thread_function));
does this work? Yes, but . . .
� what if the thread is in another process?
� scheduling thread slices: how do we later restore the state we came from?
� what if we’re coming from kernelspace?
Threads. Multiple Threads.
Changing the instruction pointer
asm("jmp *%[other_thread_function]"
:
: [other_thread_function]"r"(other_thread_function));
does this work? Yes, but . . .
� what if the thread is in another process?
� scheduling thread slices: how do we later restore the state we came from?
� what if we’re coming from kernelspace?
Threads. Multiple Threads.
Changing the instruction pointer
asm("jmp *%[other_thread_function]"
:
: [other_thread_function]"r"(other_thread_function));
does this work? Yes, but . . .
� what if the thread is in another process?
� scheduling thread slices:
how do we later restore the state we came from?
� what if we’re coming from kernelspace?
Threads. Multiple Threads.
Changing the instruction pointer
asm("jmp *%[other_thread_function]"
:
: [other_thread_function]"r"(other_thread_function));
does this work? Yes, but . . .
� what if the thread is in another process?
� scheduling thread slices: how do we later restore the state we came from?
� what if we’re coming from kernelspace?
Threads. Multiple Threads.
Changing the instruction pointer
asm("jmp *%[other_thread_function]"
:
: [other_thread_function]"r"(other_thread_function));
does this work? Yes, but . . .
� what if the thread is in another process?
� scheduling thread slices: how do we later restore the state we came from?
� what if we’re coming from kernelspace?
Context Switch: Old Thread → New Thread
� Caused only by an interrupt → privilege level change
� CPU pushes to stack: ss, rsp, rflags, cs, rip
� Store register values (→ next slide)
� Old thread executes Scheduler (code to switch to a new thread)
� Context switch to a new thread
Context Switch: Old Thread → New Thread
� Caused only by an interrupt → privilege level change
� CPU pushes to stack: ss, rsp, rflags, cs, rip
� Store register values (→ next slide)
� Old thread executes Scheduler (code to switch to a new thread)
� Context switch to a new thread
Context Switch: Old Thread → New Thread
� Caused only by an interrupt → privilege level change
� CPU pushes to stack: ss, rsp, rflags, cs, rip
� Store register values (→ next slide)
� Old thread executes Scheduler (code to switch to a new thread)
� Context switch to a new thread
Context Switch: Old Thread → New Thread
� Caused only by an interrupt → privilege level change
� CPU pushes to stack: ss, rsp, rflags, cs, rip
� Store register values (→ next slide)
� Old thread executes Scheduler (code to switch to a new thread)
� Context switch to a new thread
Context Switch: Old Thread → New Thread
� Caused only by an interrupt → privilege level change
� CPU pushes to stack: ss, rsp, rflags, cs, rip
� Store register values (→ next slide)
� Old thread executes Scheduler (code to switch to a new thread)
� Context switch to a new thread
Context Switch: Old Thread → New Thread
� Caused only by an interrupt → privilege level change
� CPU pushes to stack: ss, rsp, rflags, cs, rip
� Store register values (→ next slide)
� Old thread executes Scheduler (code to switch to a new thread)
� Context switch to a new thread
Context Switch: Store register values
1. Push all CPU register values on the stack
� No modification of instruction pointer / stack pointer:
� rip and rsp were already pushed to the stack by CPU
2. Pop all CPU register values into a struct
3. Set currentThreadInfo, etc. to kernel thread
Context Switch: Store register values
1. Push all CPU register values on the stack
� No modification of instruction pointer / stack pointer:
� rip and rsp were already pushed to the stack by CPU
2. Pop all CPU register values into a struct
3. Set currentThreadInfo, etc. to kernel thread
Context Switch: Store register values
1. Push all CPU register values on the stack
� No modification of instruction pointer / stack pointer:
� rip and rsp were already pushed to the stack by CPU
2. Pop all CPU register values into a struct
3. Set currentThreadInfo, etc. to kernel thread
Context Switch: Store register values
1. Push all CPU register values on the stack
� No modification of instruction pointer / stack pointer:
� rip and rsp were already pushed to the stack by CPU
2. Pop all CPU register values into a struct
3. Set currentThreadInfo, etc. to kernel thread
Context Switch: Store register values
1. Push all CPU register values on the stack
� No modification of instruction pointer / stack pointer:
� rip and rsp were already pushed to the stack by CPU
2. Pop all CPU register values into a struct
3. Set currentThreadInfo, etc. to kernel thread
Context Switch: Store register values
1. Push all CPU register values on the stack
� No modification of instruction pointer / stack pointer:
� rip and rsp were already pushed to the stack by CPU
2. Pop all CPU register values into a struct
3. Set currentThreadInfo, etc. to kernel thread
currentThreadRegisters
struct ArchThreadRegisters
{
uint64 rip; // 0
uint64 cs; // 8
uint64 rflags; // 16
uint64 rax; // 24
uint64 rcx; // 32
uint64 rdx; // 40
uint64 rbx; // 48
uint64 rsp; // 56
uint64 rbp; // 64
uint64 rsi; // 72
uint64 rdi; // 80
uint64 r8; // 88
uint64 r9; // 96
uint64 r10; // 104
uint64 r11; // 112
uint64 r12; // 120
uint64 r13; // 128
uint64 r14; // 136
uint64 r15; // 144
uint64 ds; // 152
uint64 es; // 160
uint64 fs; // 168
uint64 gs; // 176
uint64 ss; // 184
uint64 dpl; // 192
uint64 rsp0; // 200
uint64 ss0; // 208
uint64 cr3; // 216
uint32 fpu[28]; // 224
};
Context Switch: Old Thread → New Thread
1. “Restore” CPU register values
1.1 iretq (interrupt return) expects ss, rsp, rflags, cs, rip on the stack
1.2 iretq pops values from stack into the registers
2. Instruction pointer has a new value, execution continues there
Context Switch: Old Thread → New Thread
1. “Restore” CPU register values
1.1 iretq (interrupt return) expects ss, rsp, rflags, cs, rip on the stack
1.2 iretq pops values from stack into the registers
2. Instruction pointer has a new value, execution continues there
Context Switch: Old Thread → New Thread
1. “Restore” CPU register values
1.1 iretq (interrupt return) expects ss, rsp, rflags, cs, rip on the stack
1.2 iretq pops values from stack into the registers
2. Instruction pointer has a new value, execution continues there
Context Switch: Old Thread → New Thread
1. “Restore” CPU register values
1.1 iretq (interrupt return) expects ss, rsp, rflags, cs, rip on the stack
1.2 iretq pops values from stack into the registers
2. Instruction pointer has a new value, execution continues there
Context Switch
Looks identical for 64 bits
Context Switch: New Thread/First Thread
Act as if:
� Thread was running already
� We are returning from an interrupt
Context Switch: New Thread/First Thread
Act as if:
� Thread was running already
� We are returning from an interrupt
Context Switch: New Thread/First Thread
1. Push stored register values to stack (modifies registers)
2. “Restore” CPU register values as before
3. Instruction pointer has a new value, execution continues there
Context Switch: New Thread/First Thread
1. Push stored register values to stack (modifies registers)
2. “Restore” CPU register values as before
3. Instruction pointer has a new value, execution continues there
Context Switch: New Thread/First Thread
1. Push stored register values to stack (modifies registers)
2. “Restore” CPU register values as before
3. Instruction pointer has a new value, execution continues there
Context Switch: New Thread/First Thread
1. Push stored register values to stack (modifies registers)
2. “Restore” CPU register values as before
3. Instruction pointer has a new value, execution continues there
Context Switches: When and why?
Interrupts:
� clock
� device
� system call (syscall / sysenter / int 0x80)
� cpu fault (trap / interrupt)
� executing privileged instruction
� divide by 0
� integer overflow
� bad memory access
Context Switches: When and why?
Interrupts:
� clock
� device
� system call (syscall / sysenter / int 0x80)
� cpu fault (trap / interrupt)
� executing privileged instruction
� divide by 0
� integer overflow
� bad memory access
Context Switches: When and why?
Interrupts:
� clock
� device
� system call (syscall / sysenter / int 0x80)
� cpu fault (trap / interrupt)
� executing privileged instruction
� divide by 0
� integer overflow
� bad memory access
Context Switches: When and why?
Interrupts:
� clock
� device
� system call (syscall / sysenter / int 0x80)
� cpu fault (trap / interrupt)
� executing privileged instruction
� divide by 0
� integer overflow
� bad memory access
Context Switches: When and why?
Interrupts:
� clock
� device
� system call (syscall / sysenter / int 0x80)
� cpu fault (trap / interrupt)
� executing privileged instruction
� divide by 0
� integer overflow
� bad memory access
Context Switches: When and why?
Interrupts:
� clock
� device
� system call (syscall / sysenter / int 0x80)
� cpu fault (trap / interrupt)
� executing privileged instruction
� divide by 0
� integer overflow
� bad memory access
Context Switches: When and why?
Interrupts:
� clock
� device
� system call (syscall / sysenter / int 0x80)
� cpu fault (trap / interrupt)
� executing privileged instruction
� divide by 0
� integer overflow
� bad memory access
Context Switches: When and why?
Interrupts:
� clock
� device
� system call (syscall / sysenter / int 0x80)
� cpu fault (trap / interrupt)
� executing privileged instruction
� divide by 0
� integer overflow
� bad memory access
Process and Thread Organization
Program, Process, Thread
� Program: a binary file containing code and data
� a mold for a process
� Thread: an execution context
� a sequence of instructions
� if part of a process: restricted to the boundaries of a process
� Process: a container for threads and memory contents of a program
� an instance of a program
� restricted to its own boundaries and rights
Program, Process, Thread
� Program: a binary file containing code and data
� a mold for a process
� Thread: an execution context
� a sequence of instructions
� if part of a process: restricted to the boundaries of a process
� Process: a container for threads and memory contents of a program
� an instance of a program
� restricted to its own boundaries and rights
Program, Process, Thread
� Program: a binary file containing code and data
� a mold for a process
� Thread: an execution context
� a sequence of instructions
� if part of a process: restricted to the boundaries of a process
� Process: a container for threads and memory contents of a program
� an instance of a program
� restricted to its own boundaries and rights
Program, Process, Thread
� Program: a binary file containing code and data
� a mold for a process
� Thread: an execution context
� a sequence of instructions
� if part of a process: restricted to the boundaries of a process
� Process: a container for threads and memory contents of a program
� an instance of a program
� restricted to its own boundaries and rights
Program, Process, Thread
� Program: a binary file containing code and data
� a mold for a process
� Thread: an execution context
� a sequence of instructions
� if part of a process: restricted to the boundaries of a process
� Process: a container for threads and memory contents of a program
� an instance of a program
� restricted to its own boundaries and rights
Program, Process, Thread
� Program: a binary file containing code and data
� a mold for a process
� Thread: an execution context
� a sequence of instructions
� if part of a process: restricted to the boundaries of a process
� Process: a container for threads and memory contents of a program
� an instance of a program
� restricted to its own boundaries and rights
Program, Process, Thread
� Program: a binary file containing code and data
� a mold for a process
� Thread: an execution context
� a sequence of instructions
� if part of a process: restricted to the boundaries of a process
� Process: a container for threads and memory contents of a program
� an instance of a program
� restricted to its own boundaries and rights
Program, Process, Thread
� Program: a binary file containing code and data
� a mold for a process
� Thread: an execution context
� a sequence of instructions
� if part of a process: restricted to the boundaries of a process
� Process: a container for threads and memory contents of a program
� an instance of a program
� restricted to its own boundaries and rights
Process Resources
A process is a container.
� Process ID
� Filename
� Program file (Loader)
� (Open) file descriptors
� Address space (ArchMemory, CR3 register)
� Accounting
� Threads
� Child processes?
Process Resources
A process is a container.
� Process ID
� Filename
� Program file (Loader)
� (Open) file descriptors
� Address space (ArchMemory, CR3 register)
� Accounting
� Threads
� Child processes?
Process Resources
A process is a container.
� Process ID
� Filename
� Program file (Loader)
� (Open) file descriptors
� Address space (ArchMemory, CR3 register)
� Accounting
� Threads
� Child processes?
Process Resources
A process is a container.
� Process ID
� Filename
� Program file (Loader)
� (Open) file descriptors
� Address space (ArchMemory, CR3 register)
� Accounting
� Threads
� Child processes?
Process Resources
A process is a container.
� Process ID
� Filename
� Program file (Loader)
� (Open) file descriptors
� Address space (ArchMemory, CR3 register)
� Accounting
� Threads
� Child processes?
Process Resources
A process is a container.
� Process ID
� Filename
� Program file (Loader)
� (Open) file descriptors
� Address space (ArchMemory, CR3 register)
� Accounting
� Threads
� Child processes?
Process Resources
A process is a container.
� Process ID
� Filename
� Program file (Loader)
� (Open) file descriptors
� Address space (ArchMemory, CR3 register)
� Accounting
� Threads
� Child processes?
Process Resources
A process is a container.
� Process ID
� Filename
� Program file (Loader)
� (Open) file descriptors
� Address space (ArchMemory, CR3 register)
� Accounting
� Threads
� Child processes?
Thread Resources
A thread is a unit for execution.
� Thread ID
� Thread state (Running, Sleeping, . . . )
� A set of register values (defining the state of the execution of the userspace thread
function)
� Not all registers are different
� Some register values are process-specific and not thread-specific (e.g. CR3)
� A user stack
� A kernel stack (for syscalls)
� A second set of register values for the kernel (for syscalls)
Thread Resources
A thread is a unit for execution.
� Thread ID
� Thread state (Running, Sleeping, . . . )
� A set of register values (defining the state of the execution of the userspace thread
function)
� Not all registers are different
� Some register values are process-specific and not thread-specific (e.g. CR3)
� A user stack
� A kernel stack (for syscalls)
� A second set of register values for the kernel (for syscalls)
Thread Resources
A thread is a unit for execution.
� Thread ID
� Thread state (Running, Sleeping, . . . )
� A set of register values (defining the state of the execution of the userspace thread
function)
� Not all registers are different
� Some register values are process-specific and not thread-specific (e.g. CR3)
� A user stack
� A kernel stack (for syscalls)
� A second set of register values for the kernel (for syscalls)
Thread Resources
A thread is a unit for execution.
� Thread ID
� Thread state (Running, Sleeping, . . . )
� A set of register values (defining the state of the execution of the userspace thread
function)
� Not all registers are different
� Some register values are process-specific and not thread-specific (e.g. CR3)
� A user stack
� A kernel stack (for syscalls)
� A second set of register values for the kernel (for syscalls)
Thread Resources
A thread is a unit for execution.
� Thread ID
� Thread state (Running, Sleeping, . . . )
� A set of register values (defining the state of the execution of the userspace thread
function)
� Not all registers are different
� Some register values are process-specific and not thread-specific (e.g. CR3)
� A user stack
� A kernel stack (for syscalls)
� A second set of register values for the kernel (for syscalls)
Thread Resources
A thread is a unit for execution.
� Thread ID
� Thread state (Running, Sleeping, . . . )
� A set of register values (defining the state of the execution of the userspace thread
function)
� Not all registers are different
� Some register values are process-specific and not thread-specific (e.g. CR3)
� A user stack
� A kernel stack (for syscalls)
� A second set of register values for the kernel (for syscalls)
Thread Resources
A thread is a unit for execution.
� Thread ID
� Thread state (Running, Sleeping, . . . )
� A set of register values (defining the state of the execution of the userspace thread
function)
� Not all registers are different
� Some register values are process-specific and not thread-specific (e.g. CR3)
� A user stack
� A kernel stack (for syscalls)
� A second set of register values for the kernel (for syscalls)
Thread Resources
A thread is a unit for execution.
� Thread ID
� Thread state (Running, Sleeping, . . . )
� A set of register values (defining the state of the execution of the userspace thread
function)
� Not all registers are different
� Some register values are process-specific and not thread-specific (e.g. CR3)
� A user stack
� A kernel stack (for syscalls)
� A second set of register values for the kernel (for syscalls)
Process and Thread Interaction
Load program, create process, . . .
� 1 initial thread
� executes the main()-function
� it’s not a “main”-thread
� process may start further threads if required (how?)
Process and Thread Interaction
Load program, create process, . . .
� 1 initial thread
� executes the main()-function
� it’s not a “main”-thread
� process may start further threads if required (how?)
Process and Thread Interaction
Load program, create process, . . .
� 1 initial thread
� executes the main()-function
� it’s not a “main”-thread
� process may start further threads if required (how?)
Process and Thread Interaction
Load program, create process, . . .
� 1 initial thread
� executes the main()-function
� it’s not a “main”-thread
� process may start further threads if required (how?)
Process and Thread Interaction
Load program, create process, . . .
� 1 initial thread
� executes the main()-function
� it’s not a “main”-thread
� process may start further threads if required (how?)
Threads
� “There is no such thing as a thread” at the CPU-level
� As illustrated before: works by creative and clever usage of interrupts
� Threads can be implemented with and without support of the operating system
� Pure Userspace Threading: lightweight, but many drawbacks
� Threads can be implemented with and without support of the CPU (int 0x80 vs.
sysenter/syscall)
Threads
� “There is no such thing as a thread” at the CPU-level
� As illustrated before: works by creative and clever usage of interrupts
� Threads can be implemented with and without support of the operating system
� Pure Userspace Threading: lightweight, but many drawbacks
� Threads can be implemented with and without support of the CPU (int 0x80 vs.
sysenter/syscall)
Threads
� “There is no such thing as a thread” at the CPU-level
� As illustrated before: works by creative and clever usage of interrupts
� Threads can be implemented with and without support of the operating system
� Pure Userspace Threading: lightweight, but many drawbacks
� Threads can be implemented with and without support of the CPU (int 0x80 vs.
sysenter/syscall)
Threads
� “There is no such thing as a thread” at the CPU-level
� As illustrated before: works by creative and clever usage of interrupts
� Threads can be implemented with and without support of the operating system
� Pure Userspace Threading: lightweight, but many drawbacks
� Threads can be implemented with and without support of the CPU (int 0x80 vs.
sysenter/syscall)
Threads
� “There is no such thing as a thread” at the CPU-level
� As illustrated before: works by creative and clever usage of interrupts
� Threads can be implemented with and without support of the operating system
� Pure Userspace Threading: lightweight, but many drawbacks
� Threads can be implemented with and without support of the CPU (int 0x80 vs.
sysenter/syscall)
Pure Userspace Threads
� Kernel has no concept of threads and no idea they might exist
(that’s how it started)
� Implement threads in userspace as library
� can be implemented in all operating systems
Pure Userspace Threads
� Kernel has no concept of threads and no idea they might exist (that’s how it started)
� Implement threads in userspace as library
� can be implemented in all operating systems
Userspace Threads
Userspace Threads
� process manages threads
� user-mode-runtime-system in libc!
� function that might block the thread
� call method in libc to check: thread going to block?
� YES: save registers in thread table
� choose other thread ready to run
� load chosen the thread’s registers from thread table
� change stack pointer and instruction pointer (this time jmp)
Userspace Threads
� process manages threads
� user-mode-runtime-system in libc!
� function that might block the thread
� call method in libc to check: thread going to block?
� YES: save registers in thread table
� choose other thread ready to run
� load chosen the thread’s registers from thread table
� change stack pointer and instruction pointer (this time jmp)
Userspace Threads
� process manages threads
� user-mode-runtime-system in libc!
� function that might block the thread
� call method in libc to check: thread going to block?
� YES: save registers in thread table
� choose other thread ready to run
� load chosen the thread’s registers from thread table
� change stack pointer and instruction pointer (this time jmp)
Userspace Threads
� process manages threads
� user-mode-runtime-system in libc!
� function that might block the thread
� call method in libc to check: thread going to block?
� YES: save registers in thread table
� choose other thread ready to run
� load chosen the thread’s registers from thread table
� change stack pointer and instruction pointer (this time jmp)
Userspace Threads
� process manages threads
� user-mode-runtime-system in libc!
� function that might block the thread
� call method in libc to check: thread going to block?
� YES: save registers in thread table
� choose other thread ready to run
� load chosen the thread’s registers from thread table
� change stack pointer and instruction pointer (this time jmp)
Userspace Threads
� process manages threads
� user-mode-runtime-system in libc!
� function that might block the thread
� call method in libc to check: thread going to block?
� YES: save registers in thread table
� choose other thread ready to run
� load chosen the thread’s registers from thread table
� change stack pointer and instruction pointer (this time jmp)
Userspace Threads
� process manages threads
� user-mode-runtime-system in libc!
� function that might block the thread
� call method in libc to check: thread going to block?
� YES: save registers in thread table
� choose other thread ready to run
� load chosen the thread’s registers from thread table
� change stack pointer and instruction pointer (this time jmp)
Userspace Threads
� process manages threads
� user-mode-runtime-system in libc!
� function that might block the thread
� call method in libc to check: thread going to block?
� YES: save registers in thread table
� choose other thread ready to run
� load chosen the thread’s registers from thread table
� change stack pointer and instruction pointer (this time jmp)
Advantages
� Advantages
� no system calls for thread handling
� thread-switches are very fast
� no change of memory configuration when switching threads
� can use specialized scheduling
Advantages
� Advantages
� no system calls for thread handling
� thread-switches are very fast
� no change of memory configuration when switching threads
� can use specialized scheduling
Advantages
� Advantages
� no system calls for thread handling
� thread-switches are very fast
� no change of memory configuration when switching threads
� can use specialized scheduling
Advantages
� Advantages
� no system calls for thread handling
� thread-switches are very fast
� no change of memory configuration when switching threads
� can use specialized scheduling
Advantages
� Advantages
� no system calls for thread handling
� thread-switches are very fast
� no change of memory configuration when switching threads
� can use specialized scheduling
Disadvantages
� threads are not allowed to make direct syscalls since they might block
� ... one could make system-calls non-blocking
� ... but since this should work with unchanged (and unaware) OSs...
� sometimes you can find out if a syscall would block
� e.g. select-Systemcall
� before read is called: call select
� should read block: switch threads and check again later
� not very efficient and elegant
� Sometimes not
� Page faults
� if page not in memory, process will block
� if thread has an endless loop and does not free CPU...
Disadvantages
� threads are not allowed to make direct syscalls since they might block
� ... one could make system-calls non-blocking
� ... but since this should work with unchanged (and unaware) OSs...
� sometimes you can find out if a syscall would block
� e.g. select-Systemcall
� before read is called: call select
� should read block: switch threads and check again later
� not very efficient and elegant
� Sometimes not
� Page faults
� if page not in memory, process will block
� if thread has an endless loop and does not free CPU...
Disadvantages
� threads are not allowed to make direct syscalls since they might block
� ... one could make system-calls non-blocking
� ... but since this should work with unchanged (and unaware) OSs...
� sometimes you can find out if a syscall would block
� e.g. select-Systemcall
� before read is called: call select
� should read block: switch threads and check again later
� not very efficient and elegant
� Sometimes not
� Page faults
� if page not in memory, process will block
� if thread has an endless loop and does not free CPU...
Disadvantages
� threads are not allowed to make direct syscalls since they might block
� ... one could make system-calls non-blocking
� ... but since this should work with unchanged (and unaware) OSs...
� sometimes you can find out if a syscall would block
� e.g. select-Systemcall
� before read is called: call select
� should read block: switch threads and check again later
� not very efficient and elegant
� Sometimes not
� Page faults
� if page not in memory, process will block
� if thread has an endless loop and does not free CPU...
Disadvantages
� threads are not allowed to make direct syscalls since they might block
� ... one could make system-calls non-blocking
� ... but since this should work with unchanged (and unaware) OSs...
� sometimes you can find out if a syscall would block
� e.g. select-Systemcall
� before read is called: call select
� should read block: switch threads and check again later
� not very efficient and elegant
� Sometimes not
� Page faults
� if page not in memory, process will block
� if thread has an endless loop and does not free CPU...
Disadvantages
� threads are not allowed to make direct syscalls since they might block
� ... one could make system-calls non-blocking
� ... but since this should work with unchanged (and unaware) OSs...
� sometimes you can find out if a syscall would block
� e.g. select-Systemcall
� before read is called: call select
� should read block: switch threads and check again later
� not very efficient and elegant
� Sometimes not
� Page faults
� if page not in memory, process will block
� if thread has an endless loop and does not free CPU...
Disadvantages
� threads are not allowed to make direct syscalls since they might block
� ... one could make system-calls non-blocking
� ... but since this should work with unchanged (and unaware) OSs...
� sometimes you can find out if a syscall would block
� e.g. select-Systemcall
� before read is called: call select
� should read block: switch threads and check again later
� not very efficient and elegant
� Sometimes not
� Page faults
� if page not in memory, process will block
� if thread has an endless loop and does not free CPU...
Disadvantages
� threads are not allowed to make direct syscalls since they might block
� ... one could make system-calls non-blocking
� ... but since this should work with unchanged (and unaware) OSs...
� sometimes you can find out if a syscall would block
� e.g. select-Systemcall
� before read is called: call select
� should read block: switch threads and check again later
� not very efficient and elegant
� Sometimes not
� Page faults
� if page not in memory, process will block
� if thread has an endless loop and does not free CPU...
Disadvantages
� threads are not allowed to make direct syscalls since they might block
� ... one could make system-calls non-blocking
� ... but since this should work with unchanged (and unaware) OSs...
� sometimes you can find out if a syscall would block
� e.g. select-Systemcall
� before read is called: call select
� should read block: switch threads and check again later
� not very efficient and elegant
� Sometimes not
� Page faults
� if page not in memory, process will block
� if thread has an endless loop and does not free CPU...
Disadvantages
� threads are not allowed to make direct syscalls since they might block
� ... one could make system-calls non-blocking
� ... but since this should work with unchanged (and unaware) OSs...
� sometimes you can find out if a syscall would block
� e.g. select-Systemcall
� before read is called: call select
� should read block: switch threads and check again later
� not very efficient and elegant
� Sometimes not
� Page faults
� if page not in memory, process will block
� if thread has an endless loop and does not free CPU...
Disadvantages
� threads are not allowed to make direct syscalls since they might block
� ... one could make system-calls non-blocking
� ... but since this should work with unchanged (and unaware) OSs...
� sometimes you can find out if a syscall would block
� e.g. select-Systemcall
� before read is called: call select
� should read block: switch threads and check again later
� not very efficient and elegant
� Sometimes not
� Page faults
� if page not in memory, process will block
� if thread has an endless loop and does not free CPU...
Disadvantages
� threads are not allowed to make direct syscalls since they might block
� ... one could make system-calls non-blocking
� ... but since this should work with unchanged (and unaware) OSs...
� sometimes you can find out if a syscall would block
� e.g. select-Systemcall
� before read is called: call select
� should read block: switch threads and check again later
� not very efficient and elegant
� Sometimes not
� Page faults
� if page not in memory, process will block
� if thread has an endless loop and does not free CPU...
Implementation
Two and a half options:
� Userspace
� Kernelspace
� Mixed
kernel mode threads
� No runtime system needed
� less code the user can break
� thread management in kernel
� more or less as in userspace
� but: kernel programmers by definition only write safe code
� thread creation and management via syscall
� takes longer than before
� thread-recycling
kernel mode threads
� No runtime system needed
� less code the user can break
� thread management in kernel
� more or less as in userspace
� but: kernel programmers by definition only write safe code
� thread creation and management via syscall
� takes longer than before
� thread-recycling
kernel mode threads
� No runtime system needed
� less code the user can break
� thread management in kernel
� more or less as in userspace
� but: kernel programmers by definition only write safe code
� thread creation and management via syscall
� takes longer than before
� thread-recycling
kernel mode threads
� No runtime system needed
� less code the user can break
� thread management in kernel
� more or less as in userspace
� but: kernel programmers by definition only write safe code
� thread creation and management via syscall
� takes longer than before
� thread-recycling
kernel mode threads
� No runtime system needed
� less code the user can break
� thread management in kernel
� more or less as in userspace
� but: kernel programmers by definition only write safe code
� thread creation and management via syscall
� takes longer than before
� thread-recycling
kernel mode threads
� No runtime system needed
� less code the user can break
� thread management in kernel
� more or less as in userspace
� but: kernel programmers by definition only write safe code
� thread creation and management via syscall
� takes longer than before
� thread-recycling
kernel mode threads
� No runtime system needed
� less code the user can break
� thread management in kernel
� more or less as in userspace
� but: kernel programmers by definition only write safe code
� thread creation and management via syscall
� takes longer than before
� thread-recycling
kernel mode threads
� No runtime system needed
� less code the user can break
� thread management in kernel
� more or less as in userspace
� but: kernel programmers by definition only write safe code
� thread creation and management via syscall
� takes longer than before
� thread-recycling
Kernel mode threads
Hybrid solution
Thread states
Threads states
Thread states
Thread states
Thread states
Thread states
Thread states
Context Switching
Process Creation
� at boot time (kernel threads, init processes)
� at request of a user (how?)
� also: start of a scheduled batch job (cronjob, how?)
Process Creation
� at boot time (kernel threads, init processes)
� at request of a user (how?)
� also: start of a scheduled batch job (cronjob, how?)
Process Creation
� at boot time (kernel threads, init processes)
� at request of a user (how?)
� also: start of a scheduled batch job (cronjob, how?)
Process Creation at request of a user
via Syscall!
� UNIX/Linux: fork (exact copy)
� Windows: CreateProcess (new image)
� SWEB: fork (as soon as you have implemented it)
Process Creation at request of a user
via Syscall!
� UNIX/Linux: fork (exact copy)
� Windows: CreateProcess (new image)
� SWEB: fork (as soon as you have implemented it)
Process Creation at request of a user
via Syscall!
� UNIX/Linux: fork (exact copy)
� Windows: CreateProcess (new image)
� SWEB: fork (as soon as you have implemented it)
What does the fork do?
Check http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html!!
Process Creation via fork (on Unix / Linux / SWEB)
http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html:
pid_t fork(void);
The fork() function shall create a new process. The new process (child process) shall be an
exact copy of the calling process (parent process) except as detailed below:
� unique PID
� copy of file descriptors
� semaphore state is copied
� shall be created with a single thread. If a multi-threaded process calls fork(), the new
process shall contain a replica of the calling thread and its entire address space, possibly
including the states of mutexes and other resources.
� parent and the child processes shall be capable of executing independently before either
one terminates.
� . . .
fork/exec Return Value
http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html:
pid_t fork(void);
Upon successful completion, fork() shall return 0 to the child process and shall return the
process ID of the child process to the parent process. Both processes shall continue to execute
from the fork() function. Otherwise, -1 shall be returned to the parent process, no child
process shall be created, and errno shall be set to indicate the error.
Fork
pid_t child_pid;
child_pid = fork();
if (child_pid == -1) {
printf("fork failed\n");
} else if (child_pid == 0) {
printf("i’m the child\n");
} else {
printf("i’m the parent\n");
waitpid(child_pid,0,0); // wait
for child to die
}
� child does not know the parent
� parent knows the child
� parent waits for child to die (waitpid)
Fork
pid_t child_pid;
child_pid = fork();
if (child_pid == -1) {
printf("fork failed\n");
} else if (child_pid == 0) {
printf("i’m the child\n");
} else {
printf("i’m the parent\n");
waitpid(child_pid,0,0); // wait
for child to die
}
� child does not know the parent
� parent knows the child
� parent waits for child to die (waitpid)
Fork
pid_t child_pid;
child_pid = fork();
if (child_pid == -1) {
printf("fork failed\n");
} else if (child_pid == 0) {
printf("i’m the child\n");
} else {
printf("i’m the parent\n");
waitpid(child_pid,0,0); // wait
for child to die
}
� child does not know the parent
� parent knows the child
� parent waits for child to die (waitpid)
Process Termination
� Normal exit (return value: zero)
� Error exit (return value: non-zero)
� Fatal error (e.g. segmentation fault)
� Killed by another process
Process Termination
� Normal exit (return value: zero)
� Error exit (return value: non-zero)
� Fatal error (e.g. segmentation fault)
� Killed by another process
Process Termination
� Normal exit (return value: zero)
� Error exit (return value: non-zero)
� Fatal error (e.g. segmentation fault)
� Killed by another process
Process Termination
� Normal exit (return value: zero)
� Error exit (return value: non-zero)
� Fatal error (e.g. segmentation fault)
� Killed by another process
Process Hierarchies
Some operating systems have hierarchies:
� implicit hierarchy from forking
� process groups in UNIX/Linux
� doesn’t exist in Windows
Implicit parent-child hierarchy on Unix/Linux:
� when parent dies,
all children, grand-children, grand-grand-children, . . . , die aswell
� UNIX/Linux also cheats a bit: parent process typically inherits a processes’ children, etc.
Process Hierarchies
Some operating systems have hierarchies:
� implicit hierarchy from forking
� process groups in UNIX/Linux
� doesn’t exist in Windows
Implicit parent-child hierarchy on Unix/Linux:
� when parent dies,
all children, grand-children, grand-grand-children, . . . , die aswell
� UNIX/Linux also cheats a bit: parent process typically inherits a processes’ children, etc.
Process Hierarchies
Some operating systems have hierarchies:
� implicit hierarchy from forking
� process groups in UNIX/Linux
� doesn’t exist in Windows
Implicit parent-child hierarchy on Unix/Linux:
� when parent dies,
all children, grand-children, grand-grand-children, . . . , die aswell
� UNIX/Linux also cheats a bit: parent process typically inherits a processes’ children, etc.
Process Hierarchies
Some operating systems have hierarchies:
� implicit hierarchy from forking
� process groups in UNIX/Linux
� doesn’t exist in Windows
Implicit parent-child hierarchy on Unix/Linux:
� when parent dies,
all children, grand-children, grand-grand-children, . . . , die aswell
� UNIX/Linux also cheats a bit: parent process typically inherits a processes’ children, etc.
Process Hierarchies
Some operating systems have hierarchies:
� implicit hierarchy from forking
� process groups in UNIX/Linux
� doesn’t exist in Windows
Implicit parent-child hierarchy on Unix/Linux:
� when parent dies,
all children, grand-children, grand-grand-children, . . . , die aswell
� UNIX/Linux also cheats a bit: parent process typically inherits a processes’ children, etc.
Process Hierarchies
Some operating systems have hierarchies:
� implicit hierarchy from forking
� process groups in UNIX/Linux
� doesn’t exist in Windows
Implicit parent-child hierarchy on Unix/Linux:
� when parent dies, all children, grand-children, grand-grand-children, . . . , die aswell
� UNIX/Linux also cheats a bit: parent process typically inherits a processes’ children, etc.
Process/Thread State
git grep TODO | sort
Process/Thread State
git grep TODO | sort
� sort has to wait for input
Process/Thread State
git grep TODO | sort
� sort has to wait for input
� what does the sort do in the meantime?
Process/Thread State
git grep TODO | sort
� sort has to wait for input
� what does the sort do in the meantime?
� loop and check (busy wait)
Process/Thread State
git grep TODO | sort
� sort has to wait for input
� what does the sort do in the meantime?
� loop and check (busy wait)
� sleep and get woken up
Process/Thread State
git grep TODO | sort
� sort has to wait for input
� what does the sort do in the meantime?
� loop and check (busy wait)
� sleep and get woken up
� blocking the process makes sense
Process/Thread State
git grep TODO | sort
� sort has to wait for input
� what does the sort do in the meantime?
� loop and check (busy wait)
� sleep and get woken up
� blocking the process makes sense
� do we actually block the process?
Using Processes and Threads
Processes vs. Threads
� Threads are more lightweight than processes
� Less independent than processes
� No protection
Processes vs. Threads
� Threads are more lightweight than processes
� Less independent than processes
� No protection
Processes vs. Threads
� Threads are more lightweight than processes
� Less independent than processes
� No protection
Why threads?
� Things should happen in parallel - even within one application
� Example: text processing
� typing
� spell checking
� formatting on screen
� automatically saving
� Some of these things may block
� wait for mouse-click / keyboard press
� wait for disk
� etc.
Why threads?
� Things should happen in parallel - even within one application
� Example: text processing
� typing
� spell checking
� formatting on screen
� automatically saving
� Some of these things may block
� wait for mouse-click / keyboard press
� wait for disk
� etc.
Why threads?
� Things should happen in parallel - even within one application
� Example: text processing
� typing
� spell checking
� formatting on screen
� automatically saving
� Some of these things may block
� wait for mouse-click / keyboard press
� wait for disk
� etc.
Why threads?
� Things should happen in parallel - even within one application
� Example: text processing
� typing
� spell checking
� formatting on screen
� automatically saving
� Some of these things may block
� wait for mouse-click / keyboard press
� wait for disk
� etc.
Why threads?
� Things should happen in parallel - even within one application
� Example: text processing
� typing
� spell checking
� formatting on screen
� automatically saving
� Some of these things may block
� wait for mouse-click / keyboard press
� wait for disk
� etc.
Why threads?
� Things should happen in parallel - even within one application
� Example: text processing
� typing
� spell checking
� formatting on screen
� automatically saving
� Some of these things may block
� wait for mouse-click / keyboard press
� wait for disk
� etc.
Why threads?
� Things should happen in parallel - even within one application
� Example: text processing
� typing
� spell checking
� formatting on screen
� automatically saving
� Some of these things may block
� wait for mouse-click / keyboard press
� wait for disk
� etc.
Why threads?
� Things should happen in parallel - even within one application
� Example: text processing
� typing
� spell checking
� formatting on screen
� automatically saving
� Some of these things may block
� wait for mouse-click / keyboard press
� wait for disk
� etc.
Why threads?
� Things should happen in parallel - even within one application
� Example: text processing
� typing
� spell checking
� formatting on screen
� automatically saving
� Some of these things may block
� wait for mouse-click / keyboard press
� wait for disk
� etc.
Why threads?
� Things should happen in parallel - even within one application
� Example: text processing
� typing
� spell checking
� formatting on screen
� automatically saving
� Some of these things may block
� wait for mouse-click / keyboard press
� wait for disk
� etc.
Why threads
� Make programming easier
� Split tasks in different blocks
� Like with processes� But they cooperate easily because of the shared address space
� Consumes less memory
� Attention: do not confuse shared memory (between processes) with shared address space
(between threads)
� Switching between threads can be faster
� No need to reconfigure memory
� May achieve better performance
Why threads
� Make programming easier
� Split tasks in different blocks
� Like with processes� But they cooperate easily because of the shared address space
� Consumes less memory
� Attention: do not confuse shared memory (between processes) with shared address space
(between threads)
� Switching between threads can be faster
� No need to reconfigure memory
� May achieve better performance
Why threads
� Make programming easier
� Split tasks in different blocks
� Like with processes
� But they cooperate easily because of the shared address space
� Consumes less memory
� Attention: do not confuse shared memory (between processes) with shared address space
(between threads)
� Switching between threads can be faster
� No need to reconfigure memory
� May achieve better performance
Why threads
� Make programming easier
� Split tasks in different blocks
� Like with processes� But they cooperate easily because of the shared address space
� Consumes less memory
� Attention: do not confuse shared memory (between processes) with shared address space
(between threads)
� Switching between threads can be faster
� No need to reconfigure memory
� May achieve better performance
Why threads
� Make programming easier
� Split tasks in different blocks
� Like with processes� But they cooperate easily because of the shared address space
� Consumes less memory
� Attention: do not confuse shared memory (between processes) with shared address space
(between threads)
� Switching between threads can be faster
� No need to reconfigure memory
� May achieve better performance
Why threads
� Make programming easier
� Split tasks in different blocks
� Like with processes� But they cooperate easily because of the shared address space
� Consumes less memory
� Attention: do not confuse shared memory (between processes) with shared address space
(between threads)
� Switching between threads can be faster
� No need to reconfigure memory
� May achieve better performance
Why threads
� Make programming easier
� Split tasks in different blocks
� Like with processes� But they cooperate easily because of the shared address space
� Consumes less memory
� Attention: do not confuse shared memory (between processes) with shared address space
(between threads)
� Switching between threads can be faster
� No need to reconfigure memory
� May achieve better performance
Why threads
� Make programming easier
� Split tasks in different blocks
� Like with processes� But they cooperate easily because of the shared address space
� Consumes less memory
� Attention: do not confuse shared memory (between processes) with shared address space
(between threads)
� Switching between threads can be faster
� No need to reconfigure memory
� May achieve better performance
Why threads
� Make programming easier
� Split tasks in different blocks
� Like with processes� But they cooperate easily because of the shared address space
� Consumes less memory
� Attention: do not confuse shared memory (between processes) with shared address space
(between threads)
� Switching between threads can be faster
� No need to reconfigure memory
� May achieve better performance
Example
Example
while (TRUE)
{
get_next_request(&buf);
handoff_work(&buf);
}
while (TRUE)
{
wait_for_work(&buf);
look_for_page_in_cache(&buf,&page);
if (page_not_in_cache(&page))
read_page_from_disk(&buf,&page);
return_page(&page);
}
Without Threads
Without threads,
� just one thread
� complicated program structure
� read content from disk may block process
� non-blocking read (polling!) decreases performance
Without Threads
Without threads,
� just one thread
� complicated program structure
� read content from disk may block process
� non-blocking read (polling!) decreases performance
Without Threads
Without threads,
� just one thread
� complicated program structure
� read content from disk may block process
� non-blocking read (polling!) decreases performance
Without Threads
Without threads,
� just one thread
� complicated program structure
� read content from disk may block process
� non-blocking read (polling!) decreases performance
Non-Blocking Read
while (TRUE) { // VERY simplified
get_next_event(&buf);
if (is_request_event(&buf)) {
if (page_not_in_cache(&page)) {
request_page_from_disk(&buf,&page);
save_request_in_table(&buf);
} else {
return_page(&page);
}
} else if (is_disk_event(&buf)) {
find_request_in_table(&buf);
mark_requeust_as_done(&buf);
return_page(&page);
} else if (is_...
Non-Blocking Read
� Finite-state-machine!
� Actually simulates threads
� Better: use multithreading
Non-Blocking Read
� Finite-state-machine!
� Actually simulates threads
� Better: use multithreading
Non-Blocking Read
� Finite-state-machine!
� Actually simulates threads
� Better: use multithreading
Take Aways
� Processes divide resources amongst themselves (except processor time)
� Threads divide processor time amongst themsevles (and a few resources)
� Building block of modern multi-threading are context switches
� Operating system creates illusions
� for the hardware: there is only 1 thread and a lot of interrupts
� for the userspace: we can have an arbitrary number of threads
Take Aways
� Processes divide resources amongst themselves (except processor time)
� Threads divide processor time amongst themsevles (and a few resources)
� Building block of modern multi-threading are context switches
� Operating system creates illusions
� for the hardware: there is only 1 thread and a lot of interrupts
� for the userspace: we can have an arbitrary number of threads
Take Aways
� Processes divide resources amongst themselves (except processor time)
� Threads divide processor time amongst themsevles (and a few resources)
� Building block of modern multi-threading are context switches
� Operating system creates illusions
� for the hardware: there is only 1 thread and a lot of interrupts
� for the userspace: we can have an arbitrary number of threads
Take Aways
� Processes divide resources amongst themselves (except processor time)
� Threads divide processor time amongst themsevles (and a few resources)
� Building block of modern multi-threading are context switches
� Operating system creates illusions
� for the hardware: there is only 1 thread and a lot of interrupts
� for the userspace: we can have an arbitrary number of threads
Take Aways
� Processes divide resources amongst themselves (except processor time)
� Threads divide processor time amongst themsevles (and a few resources)
� Building block of modern multi-threading are context switches
� Operating system creates illusions
� for the hardware: there is only 1 thread and a lot of interrupts
� for the userspace: we can have an arbitrary number of threads
Take Aways
� Processes divide resources amongst themselves (except processor time)
� Threads divide processor time amongst themsevles (and a few resources)
� Building block of modern multi-threading are context switches
� Operating system creates illusions
� for the hardware: there is only 1 thread and a lot of interrupts
� for the userspace: we can have an arbitrary number of threads
Bibliography
[1] Thomas Haigh. Multicians.org and the history of operating systems. online, 9 2002. URL
http://www.cbi.umn.edu/iterations/haigh.html.
[2] Emerson Pugh, Lyle Johnson, and John Palmer. IBM’s 360 and Early 370 Systems (History
of Computing). The MIT Press, 2003.