Operating Systems: Threads, Memory, and Address Translation, Lecture notes of Operating Systems

The physical reality of limited CPUs operating independently, threads and concurrency, memory management, virtual memory, uni-programming, multi-programming, static address translation, register offset addressing, address translation, base and bounds, targeted test case, external fragmentation, growing address space, and segmentation. It also explains the abstractions provided by the OS and how stack and heap can grow independently. from a lecture in Winter 2018 at an unknown university.

Typology: Lecture notes

2017/2018

Uploaded on 05/11/2023

magicphil
magicphil 🇺🇸

4.3

(16)

241 documents

1 / 32

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
EECS 482
Introduction to Operating
Systems
Winter 2018
Harsha V. Madhyastha
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20

Partial preview of the text

Download Operating Systems: Threads, Memory, and Address Translation and more Lecture notes Operating Systems in PDF only on Docsity!

EECS 482

Introduction to Operating

Systems

Winter 2018

Harsha V. Madhyastha

Threads and Concurrency

● Physical reality:

◆ Limited # of CPUs operating independently

◆ Low-level H/W support: interrupts and test_and_set

● Abstraction:

◆ Threads can assume infinite CPUs

◆ Locks for mutual exclusion, condition variables for

ordering constraints, and semaphores for both

● Over-constrained synchronization à deadlock

OS Abstractions

Operating System Hardware Applications CPU Disk Physical memory Thread File system Virtual memory

Memory management

● Recall: Process = Set of threads + address space

● Address space

◆ All the memory space the process can use as it runs

● Hardware interface:

◆ Physical memory shared between processes

● Potential abstractions:

◆ Allow direct access to addresses in physical memory?

◆ Partition physical memory across processes?

Uni-programming

● 1 process runs at a time

● Always load process into

same spot in memory

● Reserve space for OS

● Virtual address = physical

address

fffff . . . 80000 operating system 7ffff . . . 00000 user process

Problems?

Context switch

fffff . . . 80000 operating system 7ffff . . . 00000 user process Physical memory Disk

A B

Multi-programming

● Allow >1 address space in physical memory

● Programs written assuming addr range starts at 0

● Only 1 process can start at physical address 0

● Implies address translation necessary for address

independence

Static address translation

● Compiler generates addresses starting at 0

● Linker-loader adds offset to instructions

◆ E.g., MOV 0x10, %eax becomes MOV 0x20010, %eax

fffff . 40000 operating system 3ffff . 20000 user process 1 1ffff . 00000 user process 2

Dynamic address translation

● Problem is application gets “last move”

◆ Compiler generates machine code (app)

◆ Linker-loader translates addresses (OS)

◆ Register values used to calculate addresses (app)

● Dynamic translation: system has the last move

◆ Hardware (MMU) translates all memory references

◆ Virtual address: address used by the process

◆ Physical address: address in physical memory

Dynamic address translation

● Address independence

◆ Virtual addresses are scoped to 1 process

● Protection

◆ One process can’t refer to another’s address space

● Virtual memory

◆ VA only needs to be in phys. mem. when accessed

◆ Allows changing translations on the fly

user process translator (MMU) physical memory virtual address physical address

Base and bounds

● Load each process into contiguous region of

physical memory

◆ Prevent process from accessing data outside its region

◆ Base register: starting physical address

◆ Bound register: size of region

physical memory base + bound base 0 bound virtual memory 0

Base and bounds

● MMU Translation:

if (virtual address > bound) { trap to kernel; kill process (core dump) } else { physical address = virtual address + base } physical memory base + bound base 0 bound virtual memory 0

What to change on

context switch?

How to grow

address

space?

Writing good test cases

● Need targeted test cases and stress tests

● Targeted test case:

◆ Tests 1 or a few specific things

◆ Failure tells you exactly what’s wrong

◆ Autograder gives you results for your tests (!)

● Stress tests:

◆ Lots of concurrency, activities

◆ Tests for rare, non-deterministic interleavings

◆ Failure doesn’t say why – run under debugger?

Targeted test case

● lock() blocks when mutex held, finishes when

lock released()

Thread A:

create thread B

m.lock()

yield()

m.unlock()

cout << “unlocked\n”

Thread B:

cout << “About to lock\n”

m.lock()

cout << “Lock released\n”