Noah Lewis (Personal Website)


Introduction Answers

This page provides an answers for chapter 1 (Introduction) of the book "Modern Operating Systems".


Question & Answers

Problem 1

What are the two main functions of an operating system?

Answer Problem 1

  1. Provide users with good abstractions
  2. Managing devices and resources

Problem 2

In Section 1.4, nine different types of operating systems are described. Give a list of applications for each of these systems (one per operating systems type).

Answer Problem 2

  1. Mainframe Operating Systems: Bank transaction system
  2. Server Operating Systems: HTTP servers
  3. Multiprocessor Operating Systems: Scientific simulations
  4. Personal Computer Operating Systems: Word processing
  5. Handheld Computer Operating Systems: Phone calls and text message
  6. Embedded Operating Systems: Music playing software (MP2 player)
  7. Sensor-node operating system: Temperature sensors
  8. Real-time operating systems: Manufacturing assembly line
  9. Smart card operating systems: Electronic payments

Problem 3

What is the difference between timesharing and multiprogramming systems?

Answer Problem 3

In a timesharing system, multiple interactive users are managed each of which can perform multiprogramming. Multiprogramming simply means multiple processes can run concurrently.

Problem 4

To use cache memory, main memory is divided into cache lines, typically 32 or 64 bytes long. An entire cache line is cached at once. What is the advantage of caching an entire line instead of a single byte or word at a time?

Answer Problem 4

Imagine caching was done with byte level granularity and the user will access 64 bytes contiguously. There will be 64 cache misses. Whereas if the cache lines are 64 bytes then there will be a single cache miss for the first byte at which point the following 63 bytes are cached.

Problem 5

On early computers, every byte of data read or written was handled by the CPU (i.e., there was no DMA). What implications does this have for multiprogramming?

Answer Problem 5

If each byte read/written is managed by the CPU then when multiple processes are running the OS must manage in what order processes receive/send the data requested. This would increase CPU contention tremendously decreasing performance.

Problem 6

Instructions related to accessing I/O devices are typically privileged instructions, that is, they can be executed in kernel mode but not in user mode. Give a reason why these instructions are privileged.

Answer Problem 6

If I/O instructions are available in userspace there is nothing preventing bad (malicious or buggy) processes from incorrectly interacting with devices.

Problem 7

The family-of-computers idea was introduced in the 1960s with the IBM System/360 mainframes. Is this idea now dead as a doornail or does it live on?

Answer Problem 7

This is still alive and well. An example includes the x86 CPU family.

Problem 8

One reason GUIs were initially slow to be adopted was the cost of the hardware needed to support them. How much video RAM is needed to support a 25-line x 80-row character monochrome text screen? How much for a 1200 x 900-pixel 24-bit color bitmap? What was the cost of this RAM at 1980 prices ($5/KB)? How much is it now?

Answer Problem 8

RAM for 25-line x 80-column monochrome text screen: 25 x 80 = 2,000 bytes

RAM for 1200 x 900-pixel 24-bit color bitmap: 1200 x 900 x 3 = 3,240,000 bytes

Assuming decimal kilobytes (1 KB = 1,000 bytes), this is approximately 3,240 KB of memory.

Price for 3,240 KB of memory in 1980 at $5 per KB: $16,200

Price for 3,240 KB of memory in 2025 at $0.00000214577 per KB: approximately $0.00695

Problem 9

There are several design goals in building an operating system, for example, resource utilization, timeliness, robustness, and so on. Give an example of two design goals that may contradict one another.

Answer Problem 9

Correctness and speed (especially in the context of multiprocessor programming).

Problem 10

What is the difference between kernel and user mode? Explain how having two distinct modes aids in designing an operating system.

Answer Problem 10

Kernel mode grants access to specialized CPU instructions only available when the CPU is at a specific ring level.

Kernel level drivers have full responsibility for ensuring devices are used correctly. By decoupling the kernel from userspace, the kernel can provide abstractions (APIs) which userspace programs can use. This allows for the underlying implementation of these APIs to be changed without breaking userspace (most of the time :)...).

Problem 11

A 255-GB disk has 65,536 cylinders with 255 sectors per track and 512 bytes per sector. How many platters and heads does this disk have? Assuming an average cylinder seek time of 11 ms, average rotational delay of 7 msec and reading rate of 100 MB/sec, calculate the average time it will take to read 400 KB from one sector.

Answer Problem 11

Number of platters: (total_data / data_per_platter_side) / 2_sides_per_platter = (255 GB / (65536 * 255 * 512) B) / 2 = 16

Number of heads: 16 * 2 = 32 heads

400 KB / 512 B = ceiling(781.25) = 782 sectors

Average time = 782 * (11 ms + 7 ms + 5.12 * 10^(-6)) = 14.06 sec

This answer assumes sectors are randomly scattered on disk and not contiguous.

Problem 12

Which of the following instructions should be allowed only in kernel mode?
(a) Disable all interrupts.
(b) Read the time-of-day clock.
(c) Set the time-of-day clock.
(d) Change the memory map.

Answer Problem 12

(a) YES
(b) NO
(c) YES
(d) YES

Problem 13

Consider a system that has two CPUs, each CPU having two threads (hyperthreading). Suppose three programs, P0, P1, and P2, are started with run times of 5, 10 and 20 msec, respectively. How long will it take to complete the execution of these programs? Assume that all three programs are 100% CPU bound, do not block during execution, and do not change CPUs once assigned.

Answer Problem 13

The system can run up to 4 threads in parallel. P0 and P1 finish in 5 and 10 msec respectively. P2 finishes in 20 msec.
Total time: 25 msec

Problem 14

A computer has a pipeline with four stages. Each stage takes the same time to do its work, namely, 1 nsec. How many instructions per second can this machine execute?

Answer Problem 14

Once the pipeline is filled, one instruction completes every 1 nsec.
So the system can execute 1 billion (109) instructions/sec.
Note: the first instruction takes 4 nsec, but this is amortized over many instructions.

Problem 15

Consider a computer system that has cache memory, main memory (RAM), and disk, and an operating system that uses virtual memory. It takes 1 nsec to access a word from the cache, 10 nsec to access a word from the RAM, and 10 ms to access a word from the disk. If the cache hit rate is 95% and main memory hit rate (after a cache miss) is 99%, what is the average time to access a word?

Answer Problem 15

Average access time = (1 ns * 0.95) + ((1 ns + 10 ns) * 0.99 * 0.05) + ((1 ns + 10 ns + 10 ms) * 0.01 * 0.05)
= 0.95 ns + 0.5445 ns + 5000 ns ≈ 5001.5 ns

Problem 16

When a user program makes a system call to read or write a disk file, it provides an indication of which file it wants, a pointer to the data buffer, and the count. Control is then transferred to the OS, which calls the appropriate driver. Suppose the driver starts the disk and terminates until an interrupt occurs. In the case of reading, the caller blocks. What about writing to the disk? Must the caller be blocked?

Answer Problem 16

No, writing can often be performed asynchronously. The OS may buffer the write and return control to the caller before the physical write completes. The caller can later sync the file system if needed.

Problem 17

What is a trap instruction? Explain its use in operating systems.

Answer Problem 17

A trap instruction switches execution from user mode to kernel mode. It is the mechanism by which system calls are implemented, allowing user programs to request services from the operating system securely.

Problem 18

Why is the process table needed in a timesharing system? Is it also needed in personal computer systems running UNIX or Windows with a single user?

Answer Problem 18

The process table tracks active processes and their states. Even in a single-user system, multiple processes (apps, services) run concurrently, so the OS needs the process table to manage them.

Problem 19

Is there any reason why you might want to mount a file system on a nonempty directory? If so, what is it?

Answer Problem 19

Yes, mounting over a nonempty directory can be used to temporarily hide its contents. This can be useful to mask sensitive or irrelevant files, or to override parts of the directory tree.

Problem 20

For each of the following system calls, give a condition that causes it to fail: fork, exec, and unlink.

Answer Problem 20

fork: Not enough system resources (e.g., memory or process table full).
exec: Executable file is missing, not permitted, or of an unsupported format.
unlink: File does not exist or permission denied.

Problem 21

What type of multiplexing (time, space, or both) can be used for sharing the following resources: CPU, memory, disk, network card, printer, keyboard, and display?

Answer Problem 21

CPU - Time
Memory - Space
Disk - Space
Network Card - Time
Printer - Both
Keyboard - Time
Display - Time

Problem 22

Can the count = write(fd, buffer, nbytes); call return any value in count other than nbytes? If so, why?

Answer Problem 22

Yes. If there is insufficient space or an error occurs partway through, write may write only some of the bytes and return the actual number written. The caller must check the return value.

Problem 23

A file whose file descriptor is fd contains the following bytes: 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5. The following system calls are made: lseek(fd, 3, SEEK_SET); read(fd, &buffer, 4); What does buffer contain after the read has completed?

Answer Problem 23

The seek moves the file pointer to byte 3 (zero-indexed), which contains the value 1.
Reading 4 bytes gives: 1, 5, 9, 2
So buffer contains: 1, 5, 9, 2

Answer Problem 24

move_to_cylinder + move_to_track + read_bytes
(50 x 1 ms) + 5 ms + (10 MB / 200 MB/s)
= 0.05 s + 0.005 s + 0.05 s = 0.105 seconds

Answer Problem 25

Block special files work on blocks of data at a time, while character special files work on characters of data at a time.

Answer Problem 26

No, the library procedure name is more important for the users of the system.

Answer Problem 27

Each process thinks it has access to the full memory space. Pages can be loaded and unloaded to and from disk while a process is running. This allows many large processes to run simultaneously, since only a subset of their data is actually in memory at any one time.

Answer Problem 28

Yes, syscalls have performance implications. It is useful to know which functions invoke syscalls when optimizing for performance or debugging.

Answer Problem 29

link: May have to copy data and ensure consistency.
mount: Cannot have a single filesystem tree.
umount: Same limitation as mount.
chmod: Use `icacls` instead.
kill: Use `taskkill`.
execve: Fork and exec is a single call in Windows now.

Answer Problem 30

New CPU architectures are introduced frequently.
Syscall API: Not always trapping to the kernel.
Device drivers: These interact with hardware controllers and are often architecture-specific.

Answer Problem 31

Microservices declare the policy they want. Services responsible for handling it then determine how to implement it (the mechanism). Separating policy and mechanism allows mechanism implementations to reside in the kernel, increasing stability and flexibility.

Answer Problem 32

They take a long time to boot (hence the popularity of containers) and also suffer from a runtime performance hit.

Answer Problem 33

(a) Nanoyear = 0.0315576 seconds
(b) Megamicron = 1 meter
(c) 1 PB = 1,000,000,000,000,000 bytes
(d) 6000 yottagrams = 6 x 1024 kilograms

Answer Problem 34

Still in progress...

Github Link

Answer Problem 35

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

static void recurse_fork() {
    pid_t pid = fork();
    int wait_stat;
    if(pid == 0)
        recurse_fork();
    else
        wait(&wait_stat);
}

int main() {
    recurse_fork();
    return 0;
}
        

Answer Problem 36

Viewed... Moving on.