+ All Categories
Home > Documents > Operating Systems - iaik.tugraz.at

Operating Systems - iaik.tugraz.at

Date post: 02-Apr-2022
Category:
Upload: others
View: 2 times
Download: 0 times
Share this document with a friend
432
Operating Systems Introduction, Processes, Threads Daniel Gruss 2021-10-04
Transcript

Operating Systems

Introduction, Processes, Threads

Daniel Gruss

2021-10-04

Table of contents

1. Basics

2. Booting

3. Process and Thread Fundamentals

4. Context Switches

5. Process and Thread Organization

Bachelor@IAIK Topics + Student Research Awards

Thursday 14 Oct 2021, 12:00–14:00, virtualwww.iaik.tugraz.at/bachelorwww.iaik.tugraz.at/isw

software - manage - resources - users - applications. reliability - security - responsiveness - portability.

Basics

What is an Operating System

HW provides processors, memory and a set of devices for storing data and communicating with the outside world. the HW also provides primitives that the operating system can use for fault isolation and synchronization.

What is an Operating System

The OS runs as the lowest layer of software on that computer. It contains both a device specific layer for managing hte multitude of hardware devoces and a set of device independent services provided to applications. THink: services! Since operating sytem must isolate malicious and buggy aps from ohter apps or the OS, much of the OS runs in a separate exec environment protected from application code

What is an Operating System

apps run in an exec context provided by the kernel. This is much more than a simple abstraction top of hw devices: apps execute in a virtual environment that is more constraint (to prevent harm), more powerful (to mask HW limitations) and more useful (via common services) than the underlying hardware

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

� Named 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

Reliability and Availability (does the operating system do what we want), Security (can it be corrupted by an attacker), Portability (is it easy to move to new HW platforms), Performance (UI responsive, OS too much overhead), Adoption (how many users...)

Design Criteria for OS

Design Criteria for Operating Systems

� Reliability and Availability

� Security

� Portability

� Performance

� Adoption

Reliability and Availability (does the operating system do what we want), Security (can it be corrupted by an attacker), Portability (is it easy to move to new HW platforms), Performance (UI responsive, OS too much overhead), Adoption (how many users...)

Design Criteria for OS

Design Criteria for Operating Systems

� Reliability and Availability

� Security

� Portability

� Performance

� Adoption

Reliability and Availability (does the operating system do what we want), Security (can it be corrupted by an attacker), Portability (is it easy to move to new HW platforms), Performance (UI responsive, OS too much overhead), Adoption (how many users...)

Design Criteria for OS

Design Criteria for Operating Systems

� Reliability and Availability

� Security

� Portability

� Performance

� Adoption

Reliability and Availability (does the operating system do what we want), Security (can it be corrupted by an attacker), Portability (is it easy to move to new HW platforms), Performance (UI responsive, OS too much overhead), Adoption (how many users...)

Design Criteria for OS

Design Criteria for Operating Systems

� Reliability and Availability

� Security

� Portability

� Performance

� Adoption

Reliability and Availability (does the operating system do what we want), Security (can it be corrupted by an attacker), Portability (is it easy to move to new HW platforms), Performance (UI responsive, OS too much overhead), Adoption (how many users...)

Design Criteria for OS

Design Criteria for Operating Systems

� Reliability and Availability

� Security

� Portability

� Performance

� Adoption

Reliability and Availability (does the operating system do what we want), Security (can it be corrupted by an attacker), Portability (is it easy to move to new HW platforms), Performance (UI responsive, OS too much overhead), Adoption (how many users...)

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...

Maybe the most important characteristic

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...

Maybe the most important characteristic

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...

Maybe the most important characteristic

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

MTTF: frequency of failures .... MTTR: how long to restore working situation .... Improve availability by increasing MTTF and decreasing MTTR

Security

Security: computers operation cannot be compromised by a malicious attacker

Privacy: data stored on the computer is only accessible to authorized users

Privacy is only one aspect of security

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

Sometimes this doesn't work out - MS-DOS was based on the assumption that PCs will never have more than 640kByte of RAM

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

compared to running it directly on the hardware

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 [MulticsHistory])

� 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 [MulticsHistory])

� 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 [MulticsHistory])

� 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 [MulticsHistory])

� 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 [MulticsHistory])

� 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 [MulticsHistory])

� 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!

Ritchie also developed the C programming language.

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!

Ritchie also developed the C programming language.

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!

Ritchie also developed the C programming language.

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!

Ritchie also developed the C programming language.

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!

Ritchie also developed the C programming language.

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!

Ritchie also developed the C programming language.

IBM’s OS/360

IBM360 [IBM360]

� 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

GRUB

One 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 i


Recommended