Alternate Final Exam, Schemes and Mind Maps of Computer Architecture and Organization

Computer Science 162 ... University of California, Berkeley ... (g) (1 point) In the x86 architecture, the MMU clears the use bit of page ...

Typology: Schemes and Mind Maps

2022/2023

Uploaded on 05/11/2023

parolie
parolie 🇺🇸

4.9

(15)

249 documents

1 / 24

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Computer Science 162
David E. Culler
University of California, Berkeley
Alternate Final Exam
December 16, 2019
Name
Student ID
Login (studentXXX)
TA Name and Section Time
Name of Students to
your Left and Right
Name of Students in
Front of You and Behind You
This is a closed-book exam with two 2-sided handwritten pages of notes permitted. It is intended
to be a 110 minute exam. You have 170 minutes to complete it. The number at the beginning
of each question indicates the points for that question. Write all of your answers directly on this
exam. Make your answers as concise as possible. If there is something in a question that you believe
is open to interpretation, please raise your hand to request clarification. When told to open the
exam, put your Student ID on every page and check that you have them all. The final pages are
for reference.
By my signature below, I swear that this exam is my own work. I have not obtained answers or
partial answers from anyone, and I promise not to discuss this exam with anyone prior to completion
of the regular exam.
X _______________________________________
Grade Table (for instructor use only)
Question: 1 2 3 4 5 6 7 8 9 Total
Points: 1 24 20 10 9 12 14 18 0 108
Score:
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18

Partial preview of the text

Download Alternate Final Exam and more Schemes and Mind Maps Computer Architecture and Organization in PDF only on Docsity!

Computer Science 162 David E. Culler University of California, Berkeley Alternate Final Exam December 16, 2019

Name

Student ID

Login (studentXXX)

TA Name and Section Time

Name of Students to your Left and Right

Name of Students in Front of You and Behind You

This is a closed-book exam with two 2-sided handwritten pages of notes permitted. It is intended to be a 110 minute exam. You have 170 minutes to complete it. The number at the beginning of each question indicates the points for that question. Write all of your answers directly on this exam. Make your answers as concise as possible. If there is something in a question that you believe is open to interpretation, please raise your hand to request clarification. When told to open the exam, put your Student ID on every page and check that you have them all. The final pages are for reference. By my signature below, I swear that this exam is my own work. I have not obtained answers or partial answers from anyone, and I promise not to discuss this exam with anyone prior to completion of the regular exam.

X _______________________________________ Grade Table (for instructor use only) Question: 1 2 3 4 5 6 7 8 9 Total

Points: 1 24 20 10 9 12 14 18 0 108

Score:

  1. (1 point) Miscellaneous Questions

(a) (1 point) Write your Student ID on every page of the exam.

(b) (1 bonus point) You will receive one point for completing the CS 162 Exit Survey.

(c) (1 bonus point) The winners of the Pintos Music Contest will each receive one point.

(n) (1 point) The low-level file API (read, write) is accelerated by the kernel’s buffer cache. √ True © False (o) (1 point) The Transmission Control Protocol (TCP) allows each endpoint of a connection to have multiple outstanding unACKed packets at a time. √ True © False (p) (1 point) In the Andrew File System (AFS), a user’s modifications to a file might become visible to other users in the system as soon as the close operation completes. √ True © False (q) (1 point) A group of machines can use the Two-Phase Commit (2PC) protocol to guarantee that they will perform a task atomically, i.e., either all or none. √ True © False (r) (1 point) For consistent hashing each node chooses a random value in the range of a hash function on the key and shares it with the other nodes to partition the key space with no particular pattern. √ True © False (s) (1 point) The virtual machine monitor maintains the shadow page table by setting the guest page tables as read only, so that writes to the guest page table trap and the VMM is able to update both the guest and shadow page tables. √ True © False (t) Containers handle package dependences for collections of processes, whereas Kubernetes introduces pods as a mechanism for co-locating a related set of containers on a set of (virtualized) resources. √ True © False (u) (1 point) Neither containers nor virtual machines isolate a collection of processes from all the rest of the processes. © True

False (v) (1 point) The socket abstraction is dictated by the transport layer of the network stack to allow a client and a server to communicate over HTTP. © True

False

(w) (1 point) The total number of virtual pages is always greater than or equal to the total number of physical page frames. © True

False (x) (1 point) A distributed key/value store can use a master directory server to direct client put/get requests to at most one of multiple replicas. © True

False

  1. (20 points) Operating System Concepts: Short Answer

There are 24 points of questions below. You must answer 20 points worth of questions. Clearly cross out or leave blank the ones that should not be graded.

Fill in the blanks correctly for the questions below. You do not need to provide justifications. (a) (1 point) A process may request the operating system to perform a privileged action on its behalf by issuing a/an system call. (b) (1 point) A scheduling algorithm that provides proportional shares is Stride, Lottery, or Completely Fair Scheduling. (c) (1 point) The subset of its virtual address space that a process is actively using over a given time interval is called a/an working set. (d) (1 point) To evict a page to disk, the operating system finds which page table entries map to pages that are not recently used. (e) (1 point) A transaction is a/an atomic sequence of reads/writes. (f) (1 point) A group of n machines can maintain safety and liveness in the face of fail-stop failures as long as at most a minority of (or ⌊n− 2 1 ⌋) node(s) is/are faulty. (g) (2 points) Components of a file system i. (1 point) What are the four components of a file system?

Solution: Directory Structure, Index, Storage Blocks, and Free Blocks

ii. (1 point) Which component(s) of a file system might the kernel access to handle a write system call? Assume the file descriptor corresponds to a regular file (not an I/O device, directory, or soft link).

Solution: Index, Storage Blocks, and Free Blocks

(h) (2 points) In the Redo Logging scheme discussed in class, which logged operations must be performed during recovery and which must be discarded?

Solution: Operations for committed transactions must be performed. Those for un- committed transactions are discarded.

(i) (2 points) The concept of dispatch—passing a request to the appropriate request handler for processing—arises in a variety of systems. Give two examples of dispatch in software systems that we studied in class.

Solution: Any two of the following would receive full credit: interrupt vector table, system call handler, RPC server (or HTTP server), and Linux VFS. Other examples that we didn’t cover in class are language polymorphism (e.g., vtables), opcode dispatch in bytecode interpreters, and protocol dispatch in network stacks.

  1. (10 points) Pintos

Choose True or False for the questions below according to Pintos, the operating system you used in the projects for this class. You do not need to justify your answers. (a) (1 point) Accesses to kernel memory (PHYS_BASE and above) in the system call handler and interrupt handlers operate directly on physical addresses, bypassing all page tables. © True

False (b) (1 point) It is inherently unsafe to call sema_down on a zero-value semaphore in a thread while interrupts are disabled. © True

False (c) (1 point) Interrupts are disabled while Pintos switches threads (i.e., while executing the switch_threads function). √ True © False (d) (1 point) On a successful call to pagedir_clear_page, Pintos flushes the TLB. √ True © False (e) (1 point) The memory for the page table of a process is allocated from the user pool. © True

False (f) (1 point) If two processes simultaneously hold open file descriptors corresponding to the same file, then two instances of an in-memory inode exist for that file. © True

False

Answer the questions below according to Pintos, the operating system you used in the projects for this class. You do not need to justify your answers. (g) (1 point) If Pintos is implemented with a global lock around the file system, as in Project 1, what is the maximum number of outstanding disk requests at any one time?

(g) 1 (h) (1 point) If Pintos is implemented with a 64-sector buffer cache without a global lock, as in Project 3, what is the maximum number of outstanding disk requests at any one time?

(h) 64 (i) (1 point) When scheduling timer expires, causing the timer_interrupt function to be invoked, in which stack does the timer_interrupt function execute?

Solution: It executes in the kernel stack of the currently executing thread.

(j) (1 point) While a thread is suspended (another thread is running), what is stored on its kernel stack?

Solution: The switch_threads frame is at the top of the stack, including the thread’s registers.

  1. (9 points) Multi-Threaded Processes

In the CS 162 projects, each Pintos process consists of a single thread of execution. Suppose now that we want to make processes in Pintos multi-threaded. We will represent a process control block using struct process and we will represent a thread control block using struct thread. (a) (1 point) How must the exit system call change to handle multi-threaded processes?

Solution: If a thread issues an exit system call, then that thread, and all other threads in its process, should exit.

(b) (5 points) Fill in struct thread and struct process below. Here are some guidelines:

  • Account for each field in the current struct thread (see detachable reference material for this definition).
  • Your design should support the full lifecycle of a thread/process: creation, system call/page fault handling, and exit.

struct thread { tid_t tid;

enum thread_status status;

uint8_t* stack;

int priority;

struct list_elem allelem;

struct list_elem elem;

struct list_elem processelem;

struct process* process;

unsigned magic;

struct process { pid_t pid;

char name[16];

uint32_t* pagedir;

struct list threads;

struct lock process_lock;

(c) (1 point) Suppose we would like to implement file descriptors in this system, as you did in Project 1. Which structure(s) must you modify to implement this? © struct thread only

struct process only © both structs (d) (1 point) Suppose we would like to implement non-busy-waiting sleep in this system, as you did in Project 2. Which structure(s) must you modify to implement this? √ struct thread only © struct process only © both structs (e) (1 point) Suppose we would like to implement a current working directory in this system, as you did in Project 3. Which structure(s) must you modify to implement this? © struct thread only

struct process only © both structs

  1. (12 points) Inode Design

Alice, Benjamin, Catherine, and David would like to design a file system for Pintos as follows. The on-disk inode has 10 direct pointers. The inode does not have any indirect pointers, but instead may point to another on-disk inode, which provides links to the remaining bytes of the file. The inode that it points to may point to yet another inode, and so on. Note that an inode may point to another inode even if it is not completely full. This does not mean that the file is sparse, only that the remaining bytes in the inode are unused. (a) (1 point) What is the size, in bytes, of the largest file that can be represented by a single inode, without using a pointer to another inode?

(a) 5120 (or^ 10 * BLOCK_SECTOR_SIZE) (b) (1 point) List an access pattern that this inode structure supports efficiently.

Solution: Sequential reads and writes through a file.

(c) (1 point) List one similarity between this inode structure and the FAT file system.

Solution: Accesses to bytes at an offset in middle of a file require disk accesses linear in the byte offset.

(d) (1 point) List one difference between this inode structure and the FAT file system.

Solution: Whereas FAT stores a linked list of blocks, each node of the linked list for this inode structure references many blocks directly.

(e) (2 points) Complete struct inode_disk for this design. Do not assume any useful file data is stored in the magic or unused fields. You may not need all of the blank lines. Ensure that sizeof(struct inode_disk) == BLOCK_SECTOR_SIZE. Note that off_t is defined as follows: typedef int32_t off_t;. struct inode_disk { off_t length; // length of data in THIS inode, not including linked inodes uint32_t isdir;

block_sector_t direct[10];

block_sector_t linked; // inumber of linked inode

unsigned magic; uint8_t unused[ BLOCK_SECTOR_SIZE - (4 + 4 + 40 + 4 + 4) ]; };

(f) (6 points) The group is using the following in-memory inode structure. Note that there is no bounce buffer within the in-memory inode (this is different from the Pintos starter code, which has the struct inode_disk data; element in struct inode). struct inode { struct list_elem elem; /* Element in inode list. / block_sector_t sector; / Sector number of disk location. / int open_cnt; / Number of openers. / bool removed; / True if deleted, false otherwise. / int deny_write_cnt; / 0: writes ok, >0: deny writes. */ }; Based on this information, implement byte_to_sector for this group’s inode design.

  • Assume the syscall handler acquires a global file system lock, as in Project 1.
  • You may call read/write from disk directly; do not use a buffer cache.
  • Assume there is enough stack space to store a buffer of BLOCK_SECTOR_SIZE bytes.
  • Assume that files are not sparse.

/* Returns the block device sector that contains byte offset POS within a file. Returns INVALID_SECTOR if the file does not contain data for a byte at offset POS (e.g., POS is past the end of file). */ block_sector_t byte_to_sector(const struct inode *inode, off_t pos) { ASSERT(inode != NULL); block_sector_t rv = INVALID_SECTOR; struct inode_disk bounce;

block_read(fs_device, inode->sector, &bounce);

while ( pos >= bounce.length ) {

if (bounce.linked == INVALID_SECTOR) {

return rv; // end of file

}

pos -= bounce.length;

block_read(fs_device, bounce.linked, &bounce);

rv = bounce.direct[pos / BLOCK_SECTOR_SIZE];

return rv; }

(c) (5 points) Finally, implement cond_signal. Do not use semaphores. void cond_signal(struct condition* cond, struct lock* lock) { ASSERT(cond != NULL); ASSERT(lock != NULL); ASSERT(!intr_context()); ASSERT(lock_held_by_current_thread(lock)); struct thread* t = thread_current();

enum intr_level old_state = intr_disable();

if (!list_empty(&cond->waiters)) {

struct list_elem* entry = list_pop_front(&cond->waiters);

struct thread* waiter = list_entry(entry, struct thread, elem);

thread_unblock(waiter);

}

intr_set_level(old_state);

(d) (1 point) How would you implement cond_broadcast? Starting from your implementa- tion of cond_signal, explain what changes you would make.

Solution: Change the if statement to a while loop.

(e) (1 point) Implementing condition variables directly makes it possible to implement a semaphore using locks and condition variables. Explain one disadvantage of this ap- proach, other than performance, compared to implementing semaphores directly.

Solution: A semaphore implemented using locks and condition variables cannot be safely used in external interrupt context. In contrast, a semaphore that is implemented directly by disabling interrupts can be used safely in external interrupt context.

Commentary:

The solution given above is defensive in how it disables interrupts. If you assume that the condition variable is always used correctly according to how we learned in class (each condition variable is associated with a single lock that is held during all operations on that condition variable), then it isn’t necessary to disable interrupts in cond_signal, and in cond_wait, it’s fine to only disable interrupts around releasing the lock and blocking the thread. For the purposes of grading, we considered this to be a valid solution. That said, it is better design to disable interrupts as done in the example solution above, because the memory safety of the condition variable should, ideally, not depend on how the user of the condition variable acquires locks. If the user uses a different lock with cond_signal than they do with cond_wait, we don’t want to concurrently modify the list of waiters in two different threads because we were depending on the locks being the same.

Surprisingly, about 12% of students attempted to implement cond_wait with a spin loop. I’d like to clarify here that a busy-waiting solution is strictly inferior to one that properly puts the waiting thread to sleep. You should avoid busy-waiting solutions where possible in your code. There really is no good reason to busy wait for code that’s (1) in the kernel, and (2) on a uniprocessor system, which is exactly the case of Pintos (unless you need to wait for a very small duration where scheduling costs are significant). That said, we did not impose any penalty for busy-waiting, because the problem did not explicitly disallow it. Students who busy-waited, however, typically scored lower than students who did not, because a proper busy-waiting implementation of condition variables is trickier to implement.

A few students attempted to block a thread by acquiring a lock twice from the same thread. I’d like to clarify that you should never attempt to block a thread by acquiring a lock, and then attempt to unblock it by releasing a lock from another thread. In Pintos, if a thread holds a lock and then attempts to acquire it, the result is a kernel panic. It is indeed the case that some lock implementations, especially implementations of userspace locks, can be used this way. Even so, using locks this way is extremely bad practice. Even if we were to ignore this and implement a condition variable this way, an additional obstacle to this approach is that locks are stateful, whereas condition variables are not. Thus, a correct implementation needs one lock per waiting thread, not one lock for the condition variable. The condition variable would have to have a list of locks, and each thread would have to be put to sleep by double-acquiring a different lock from other threads. See the Pintos implementation, which uses semaphores, as an example of how this is done. No student who attempted this approach implemented it correctly.

For the final part of this question (disadvantage of implementing a semaphore out of locks and condition variables), many students wrote that it is more complex to do that than to implement semaphores directly. This is highly debatable. It is common to build synchro- nization primitives out of others. If you need a complex type of lock, it is more natural to build it out of locks and condition variables than it is to implement it by disabling inter- rupts. Think about how we implemented reader-writer locks and bounded buffers in lecture. We awarded some partial credit to answers that gave complexity as a reason, along with a concrete reason or example. One concrete reason we gave full credit to is that locks would have to be reimplemented to no longer use a semaphore with this approach. A few other answers with debatable reasons but concrete reasons or examples were awarded half credit.

The state of the machine described on the previous page is shown below. The contents of several frames of physical memory are shown on the right with physical addresses. On the left are several machine registers, including the eip, esp, and the page table base register (cr3), which contains the physical frame number of the root page table. The TLB is initially empty. Page table entries have the valid flag as the most significant bit and the physical frame number of valid entries in the low order bits. Other flags can be assumed to be zero for this problem.

Registers

cr3 (PTBR) 0x0001 0030 eip esp 0x1044 0100 eax 0x8001 0050 ebx 0x0001 0080 ecx edx

Current Instruction 0x1004 0100 pushl %eax

TLB Contents

Valid Tag Frame

Physical Memory

Phys. Addr. Contents

0x1001 0000 ... 0x1001 0100 0x0001 0080 0x1001 0104 0x8001 5350 0x1001 0108 0x8001 0080

0x1002 0000 ... 0x1002 0100 0x8001 0050 0x1002 0104 0x8001 0080 0x1002 0108 0x0001 0080

0x1003 0000 ... 0x1003 0100 0x8001 0020 0x1003 0104 0x8001 0040 0x1003 0108 0x0001 0080

0x1004 0000 ... 0x1004 0100 0x0001 0000 0x1004 0104 0x0001 0010 0x1004 0108 0x0001 0080

0x1005 0000 ... 0x1005 0100 0x0001 5350 0x1005 0104 0x8001 5350 0x1005 0108 0x0001 0080

(b) (6 points) You are to step through one instruction whose address and disassem- bly are shown above. In the space provided below, write down the operation, address, and value associated with every memory operation associated with the instructions up to the point of the first page fault, by filling in the blank cells in the table. You should also update the state of the memory, registers, and TLB by over-writing the figure. You may not need all of the rows provided in the table.

Operation Address Value Comment

N/A N/A N/A Fetch instruction

Fetch root PT 0x1003 0100 0x8001 0020 Read valid PTE for top level page

Fetch L2 PT 0x1002 0100 0x8001 0050 Read valid PTE for code page

Add to TLB Tag: 0x10040 Val: 0x10050 N/A

Read Instr. 0x1005 0100 0x0001 5350 Fetch pushl %eax

N/A N/A N/A Write eax to *esp

Fetch root PT 0x1003 0104 0x8001 0040 Read valid PTE in top level page

Fetch L2 PT 0x1004 0100 0x0001 0000 Read invalid PTE for data page

Page Fault 0x1044 0100 N/A N/A

Question continues on the next page −→

(c) (2 points) Upon entering the page fault handler, the operating system determines that the fault occurs on reference to an unallocated page. Explain why the operating system should not read in a page from disk in this case and why it is reasonable for it to instead allocate a new page to this process.

Solution: There is no object on backing store for this page. It represents an unused segment of the process virtual address space. By pushing this value onto the stack, the process is implicitly extending its stack segment. It will need to allocate a page frame, update the PTE to refer to this page and restart the instruction.

(d) (2 points) Assume the first free frame is number 0x10010. What changes to the memory does the operating system need to make to provide this page to the process to resolve this fault?

Solution: The PTE at physical 0x1004 0100 is updated to contain 0x8001 0010. Valid and frame 0x10010.

(e) (1 point) What does the operating system need to do with the page frame contents before returning from the page fault?

Solution: Clear its contents (i.e., memset to 0x00 or allocate with PAL_ZERO).

(f) (1 point) Does the operating system need to do anything to the TLB before returning from the page fault?

Solution: No. The previously invalid PTE would not have been present in the TLB. No need to flush.

(g) (2 points) Upon resuming from the page fault, describe what will happen in the user process (i.e., memory accesses, TLB accesses, etc.).

Solution: The pushl %eax instruction will be re-executed. This time it will hit in the TLB for the instruction fetch and load the instruction. It will miss in the TLB for the write, but the MMU will find a valid page table entry for the data page and load that translation into the TLB. It will store the value of eax to the data page and update esp.

  1. (0 points) Optional Questions

(a) (0 points) Having finished the exam, how do you feel about it? Check all that apply:

   Other (please draw):

(b) (0 points) If there’s anything you’d like to tell the course staff (e.g., feedback about the class or exam, suspicious activity during the exam, new logo suggestions, etc.) you can write it on this page.