4 minute read

UCL Course COMP0133: Distributed Systems and Security LEC-01


Goals

  • Share Hardware Resources (CPU, Memory, Disk …)

  • Protection (App-to-App, App-to-OS): bugs in one App should not crash OS or other Apps

  • Communication (App-to-App, App-to-OS)

  • Hardware Independence: no need to rewrite software for different hardwware

Methods

  • Abstractions & Well-defined Interfaces (Virtualization)

UNIX Abstractions

  • Process: Address space, Thread of control, User ID

  • Filesystem

  • File Descriptor: File on disk, Pipe between processes, Network connection, Hardware device

Kernel implements abstractions, executes with privilege to directly touch hardware

(high kernel privilege & low application privilege: the former one can directly touch hardware)

Unix System Call Interface

Processes see system call interface to kernel abstractions

e.g., fork(), exec(), open(), read(), close()

like function call but special:

  • system call: from application to kernel, kernel executes, return to application

  • function call: just in application

App_1 and App_2 has separate address spaces in User Space (protected from each other)

Hardware runs kernel with higher privilege


Case Study: System Call close()

Process-Kernel Communication

One application closes a file: calls close(x)

Implementation of close() in C library (assembly pseudocode)

close(x)
{
    R0 <- 73
    R1 <- x
    TRAP
    RET
}

Calling convention:

CPU Register: R0 and R1

R0 always holds a constant which defines what system call is being invoked (mapping in table)

R1 holds the file wants to close

TRAP Instruction

TRAP
{
    XP <- PC
    Switch to Kernel address space
    Set privileged flag (high)
    PC <- address of Kernel Trap Handler
}

PC - Program Counter

PC is incremented after fetching an instruction,

and holds the memory address of the next instruction that would be executed.

Kernel Trap Handler

Kernel Trap Handler
{
    Save all registers to currently executing process: Process Control Block (PCB)
    Set SP to Kernel stack (from applciaiton stack to Kernel stack)
    call sys_close() in the kernel address space
    ... Execute "Kernel Half" of process ...
    Restore all registers from PCB
    TRAPRET (return from TRAP)
}

Why need to save all registers:

  • There are some states of the application in registers

  • However, Kernel also needs to use these registers to invoke system calls

  • Save these states will help return from Kernel to previous application

SP - Stack Pointer

TRAPRET Instruction

TRAPRET
{
    PC <- XP
    Clear privileged flag
    Switch to process address space
    continue execution
}

Proctected Transfer

Danger: Application seems to execute codes in Kernel

  • Process granted Kernel privilege level by hardware

  • Transfer needs to known Kernel entry point (e.g., Kernel Trap Handler)


Blocking I/O

Since process suspended until system call finishes,

what if system call must wait for I/O (e.g., read() from disk)?

sys_open(path)
{
    for each pathname component
    {
        Start read of directory from disk (cost milliseconds)
        Call sleep() to wait for disk read
        Wake up: process directory contents
     }
}

Sleep current process and its Kernel execution (give up CPU)

sleep()
{
    Save its all Kernel Registers to PCB1 (including its SP)
    Find another runnable PCB2 (operated by the operation system scheduler)
    Restore Kernel Registers from PCB2 (continue other process execution)
    return
}

Each user process has Kernel stack which contains state of pending system call

System call “blocks” while awating I/O


Case Study: Disk I/O Completion

  • Disk controller genreates interrupt (boolean signal that pauses CPU)

  • CPU hardware jumps to Device Interrupt Routine in Kernel, finds process blocked on that I/O

  • The process is marked as runnable

  • CPU hardware returns from interrupt (continue what CPU does before interrupt)

  • Process scheduler will reschedule waiting process (not run immediately)


Case Study: server_1()

includes network syscalls, disk syscalls, CPU (used very little in web server)

Read and Write socket using network syscalls (frequently)

Read blocks from disk using disk syscalls (often)

Server waits for each resource in turn \( \implies \) Each resource largely idle

Concurrency for better Performance