Question 1 (1 points): In xv6, the arguments to system calls like write()
are stored on the user program's stack
in user mode.
This allows kernel function that implement the system call like sys_write()
to obtain
the arguments because
Question 2 (1 points): On a typical Unix-like operating system (e.g. xv6), which of the following operations typically must be done in kernel mode?
Select all that apply
Suppose a single-core xv6 system is running two programs. Program A is processing a large input file, doing some time-consuming computation, then writing an output file. Before this data processing finished, the user typed in some input for Program B. Eventually, xv6 starts running Program B instead of Program A, even though Program A is not finished.
Question 3 (1 points): (see above) When program A was last running before xv6 switched to program B, which of the following are possible
ways in which it might have been stopped?
Select all that apply
Question 4 (1 points): (see above) When program B starts running, the value of program A's user stack pointer (that is, the value %esp
last had when A was running in user mode) will be saved
Question 1 (2 points): Consider the following C code that uses the POSIX API:
write(STDOUT_FILENO, "A", 1);
int value = 0;
pid_t pid1 = fork();
if (pid1 == 0) {
write(STDOUT_FILENO, "B", 1);
value += 1;
} else {
write(STDOUT_FILENO, "C", 1);
value += 2;
}
pid_t pid2 = fork();
char value_as_string[2];
sprintf(value_as_string, "%d", value);
write(STDOUT_FILENO, value_as_string, 1);
Assume each POSIX API call (fork
, write
, etc.) does not fail. Which of the
following are possible outputs?
Select all that apply
Question 2 (1 points): If successful, execv("/bin/program", args)
will _________.
Select all that apply
Question 3 (1 points): The following C function attempts to use the POSIX
API to run another program, sending it input
as its input and reading its output_size
byte output into output
.
void run_program_with_input_and_get_output(char *program, const char *input, size_t input_size, char *output, size_t output_size) {
char *argv[2] = {program, NULL};
int output_pipe_fds[2];
int input_pipe_fds[2];
pipe(output_pipe_fds);
pipe(input_pipe_fds);
int pid = fork();
if (pid == 0) {
/* child */
dup2(output_pipe_fds[1], STDOUT_FILENO);
dup2(input_pipe_fds[0], STDIN_FILENO);
close(input_pipe_fds[0]); close(input_pipe_fds[1]);
close(output_pipe_fds[0]); close(output_pipe_fds[1]);
execv(program, argv);
} else {
/* parent */
close(input_pipe_fds[0]); close(output_pipe_fds[1]);
write(input_pipe_fds[1], input, input_size);
close(input_pipe_fds[1]);
read(output_pipe_fds[0], output, output_size);
close(output_pipe_fds[0]);
waitpid(pid, NULL, 0);
}
}
This function works for a small input.
But, when attempting to run this function with a large input, the program ends up
hanging. But, when the program is run manually, it terminates normally
when given the specified input,
and produces output that fits in the supplied output_size
.
What is a likely cause of the hang?
Select all that apply
Question 4 (1 points): Typically programs on a POSIX-like system use library functions that are implemented in
terms the read()
and write()
system calls, such as
printf
, fwrite
, fgets
, fread
and the various methods of the iostream
classes.
The implementation of these functions usually do their own buffering in addition to any buffering
the operating system kernel may perform within the system call implementations.
Besides being more portable to non-POSIX systems, which of the following are usually advantages of these
wrapper functions?
Select all that apply
Question 5 (1 points): On a typical POSIX-like system, when a program A uses the write()
system call to send data to another program B via a pipe (like created with pipe()
), the write()
system call will return
(assuming no errors occur and that write()
writes as many bytes as program A requests)
Suppose a single-core system is running three processes A, B, and C.
Process A becomes ready to run (after finishing some previous I/O) at time 0, and process B becomes ready to run at time 2, and process C becomes ready to run at time 5. The operating system runs the programs until they start waiting for their next I/O operation using the following schedule:
For these questions, assume the time spent context switching, etc. are negligible.
Question 1 (1 points): (see above) What is the turnaround time experienced by process A (in the schedule above)?
Question 2 (1 points): (see above) What is the turnaround time experienced by process B (in the schedule above)?
Question 3 (0 points): (see above) [This question will be dropped because there is an off-by-one error in it.] Suppose the workload above were scheduled with a FCFS (first-come, first-served) scheduler instead of the schedule used above. Under this scheduler, process A would finish running at time 5. When would process B finish running and start its next I/O operation?
Question 4 (1 points): (see above) Suppose the workload above were scheduled with a preemptive SRTF (shortest remaining time first) scheduler instead of the schedule used above. Under this scheduler, when would process B finish running and start its next I/O operation?
Question 5 (1 points): When running a mix of jobs that need to react quickly to input and jobs that perform lots of long computation,
increasing the time quantum in a round-robin scheduler generally ___________.
Select all that apply
Question 1 (1 points): Consider a multi-level feedback queue scheduler with 4 priority levels:
Whenever a process finishes running without using its entire time quantum, it is moved up to a higher priority level (except if it is already at the highest priority level) for the next time it is runnable. If a process is still runnable after using its entire quantum, it is moved down to a lower priority level (unless it is already at the lowest priority level).
Within each priority level, the scheduler uses round-robin.
Suppose this scheduler is running two processes: * process A which alternates between performing 5 ms of computation and starting and waiting for an I/O operation that takes 50 ms to complete * process B which alternates between performing 15 ms of computation and starting and waiting for an I/O operation that takes 25 ms to complete
After the processes are running for a long time, ______.
Question 2 (1 points): Suppose one wanted to use a lottery scheduler to approximate an SJF (shortest job first) scheduler. Which of the following would be the best approach?
Question 3 (1 points): Consider the following C program that uses the POSIX API:
void *thread_function(void *argument) {
const char *ptr = (const char*) argument;
write(STDOUT_FILENO, ptr, strlen(ptr));
return NULL;
}
int main(int argc, const char **argv) {
pthread_t a, b;
pthread_create(&a, NULL, thread_function, (void*) "A");
pthread_create(&b, NULL, thread_function, (void*) "B");
pthread_join(&a, NULL);
write(STDOUT_FILENO, "C", 1);
pthread_join(&b, NULL);
return 0;
}
Assume none of the calls to pthread_create
, pthread_join
, or write
fail
(and ignore minor syntax errors, missing #include
s, etc.).
Which of the following are possible outputs of this code?
Select all that apply
Consider the following C program that uses the POSIX API:
pthread_mutex_t lock;
int global = 100;
struct ThreadData { int *pointer; };
struct ThreadData a_data, b_data;
void *thread_function(void *argument) {
ThreadData *data = (struct ThreadData*) argument;
int *pointer = data->pointer;
pthread_mutex_lock(&lock);
*pointer = global + *pointer; /* <--- here */
global += 10;
pthread_mutex_unlock(&lock);
return NULL;
}
int main() {
pthread_t a, b;
int value1 = 1, value2 = 2;
a_data.pointer = &value1;
b_data.pointer = &value2;
pthread_mutex_init(&lock, NULL);
pthread_create(&a, NULL, thread_function, (void*) &a_data);
pthread_create(&b, NULL, thread_function, (void*) &b_data);
pthread_join(&a, NULL);
pthread_mutex_lock(&lock);
printf("%d %d %d", global, value1, value2);
pthread_mutex_unlock(&lock);
pthread_join(&b, NULL);
return 0;
}
Assume none of the calls to pthread_create
, pthread_join
, pthread_mutex_lock
, or
printf
fail (and ignore minor syntax errors, missing #include
s, etc.)
Question 4 (1 points): (see above) Which of the following are possible outputs of this code?
Select all that apply
Question 5 (1 points): (see above) The line marked with a <--- here
modifies:
Question 1 (1 points): The implementation of a mutex lock we discussed in lecture involves using a spinlock
and a queue of waiting threads.
Which of the following are true about the spinlock this implementation uses?
Select all that apply
Question 2 (1 points): False sharing occurs when two or more threads access logically independent resources simulatenously, but end up needing to synchronize those accesses because they are actually dependent. Most commonly, the threads area accessing values that are stored in the same cache block.
Which of the following are strategies to prevent false sharing?
Select all that apply
Consider the modified/shared/invalid cache coherency protocol we discussed in lecture running on a system with three processors A, B, and C, each of which have their own caches with 64 byte cache blocks. (With 64 byte cache blocks, addresses 0x0 through 0x3F are in the same cache block, as are 0x40 through 0x7F, and are 0x80 through 0xBF, and so on.)
Assume that when it is necessary to write a modified cache block to memory, the processor writes the value but keeps its cache block in the shared state when possible. Also assume that values are not evicted from caches due to lack of capacity
The caches are initially empty, and the processors perform the following accesses to the following addresses in this order:
0x100
0x200
0x200
0x100
0x200
0x108
0x100
Question 3 (1 points): (see above) What is the final state of address 0x100
in processor A's cache?
Question 4 (1 points): (see above) What is the final state of address 0x100
in processor B's cache?
A multithreaded batch processing program sometimes produces a very large number of messages. In attempt to limit the amount of messages the user sees, the program transfers all the messages to a dedicated "message displayer" thread, which only displays at most one message per second. When a data processing thread wants to display a message, it waits until its message is displayed before proceeding with its processing.
To facilitate this, the program uses a monitor with relevant variables and data structures declared as follows:
struct MessageInfo {
const char *message;
pthread_cond_t cv;
MessageInfo *next;
bool displayed;
};
pthread_mutex_t lock;
pthread_cond_t new_message_cv;
MessageInfo *head; MessageInfo *tail;
And once the "message displayer" thread decides to show a message, it uses code like the following (which is called with the mutex locked):
void ShowNextMessage() {
MessageInfo *info = head;
head = info->next;
std::cout << info->message << std::endl;
info->displayed = true;
pthread_cond_signal(&info->cv);
}
(Please ignore minor syntax errors, etc. in the code above and assume all values are initialized appropriately.)
Question 5 (1 points): (see above) Each data processing thread that wants to display a message allocates and initializes a MessageInfo struct
called info
(initializing all the fields within it),
then acquires the mutex lock
, then adds it to the linked list (using the head
and tail
pointers), then
signals the new_message_cv
. Following this, it runs code like the following:
_______ ( ______________________________ ) {
pthread_cond_wait(&info->cv, &lock);
}
What should go in the blanks above to make this code correct?
Question 6 (1 points): (see above) The following is an incorrect implementation of the part of the "message displayer" thread that waits for
messages and calls ShowNextMessage()
as new messages arrive.
pthread_mutex_lock(&lock);
while (head == NULL) {
pthread_cond_wait(&new_message_cv, &lock);
ShowNextMessage();
}
pthread_mutex_unlock(&lock);
Which of the following are types of incorrect behavior that could happen from this code?
Select all that apply
A multithreaded batch processing program sometimes produces a very large number of messages. In attempt to limit the amount of messages the user sees, the program attempts to allow at most one message to be sent per second. When a thread generates a message and it cannot be shown to the user immediately, it waits until it can display the message before proceeding.
The program implements this using two counting semaphores. One semaphore, called the "prepare-to-send" semaphore, is used to indicate to a dedicated timekeeping thread that a data processing thread is ready to send a message to a user. When this timekeeping thread processes that indication, it indicates to the data processing thread that it can show the message, then waits one second, then starts checking for another data processing thread that wishes to send a message. The other semaphore, called the "ready-to-send" semaphore, is how the timekeeping thread indicates to a data processing thread that it can show a messsage.
Question 1 (1 points): (see above) When a data processing thread is using the "prepare-to-send" semaphore to ask the timekeeeping thread to send a message, what semaphore operation should it use?
Question 2 (1 points): (see above) When the timekeeping thread is using the "ready-to-send" semaphore to indicate to a data processing thread that it can send a message now, what semaphore operation should it use?
Question 3 (1 points): (see above) What should the initial value of the "ready-to-send" semaphore be?
An online encyclopedia keeps track of articles, which are grouped into categories. To do this, it keeps data structures in memory representing both the articles and categories:
struct Article {
pthread_mutex_t lock;
Category* category;
...
};
struct Category {
pthread_mutex_t lock;
vector<Article*> articles;
...
};
The online encyclopedia implementation is multithreaded sometimes experiences deadlock when simulatenously performing some combinations of the following operations on Articles and Categories:
Question 4 (1 points): (see above) Which of the following combinations of operations, if performed in parallel, could cause deadlock? D, E, and F represent categories
and X, Y, and Z represent articles.
Select all that apply
Question 5 (1 points): (see above) Which of the following changes would reduce the ways deadlocks could occur?
Select all that apply
Question 1 (1 points): When writing a multithreaded program, a common alternative to having the threads communicate
in shared memory regions (synchronized via monitors, semaphores, etc.) is to use message passing.
What are some advantages of using message passing?
Select all that apply
32-bit x86 as configured by xv6 uses a two-level page table with a 32-bit virtual addresses, 4096 byte pages, and 4-byte page table entries stored in 4096 byte page tables (for each level).
For the purposes of these questions, a first-level page table is one pointed to directly by the page table base pointer (CR3 on x86), which on x86 is also called a page directory. The second-level page table is one pointed to by an page table entry in the first-level page table.
Question 2 (1 points): (see above) If the page table base pointer is set to byte address 0x10000
, then first-level page table entry for virtual address
0x11222333
is stored at what physical byte address?
Question 3 (1 points): (see above) If the second-level page table corresponding to virtual address 0x44555666
is located as physical byte address
0x80000
, then the second-level page table entry for the virtual address is what physical byte
address?
Consider the following POSIX C code that uses mmap
:
int fd1 = open("test1.dat", O_RDWR);
char *ptr1 = mmap(0, 16384, PROT_READ | PROT_WRITE, MAP_SHARED, fd1, 0);
int fd2 = open("test2.dat", O_RDWR);
char *ptr2 = mmap(0, 16384, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0);
for (int i = 1024; i < 6 * 1024; ++i) {
ptr2[i] = ptr2[i] + 10;
ptr1[i] = ptr2[i];
}
Assume this runs on a system where:
mmap
with an offset argument of 0 always returns a pointer to the beginning of pageMAP_PRIVATE
, and the copy-on-write implementation only copies pages when they are written to (it never tries to "guess" what will be written to)mmap
, each page that is modified will (eventually) be written to the file on disk (even if only part of the page is actually modified)Question 1 (0 points): (see above) [This question will be dropped, since I accidentally made an adjustment that removed MAP_PRIVATE
from the code above.] How many bytes must have been copied to run this program as part of the copy-on-write used to implement MAP_PRIVATE
?
Question 2 (1 points): (see above) How many pages will (eventually) be written to disk as a result of the modifications this program makes via mmap?
Question 3 (1 points): A mapping from physical pages to page table entries referencing that physical page could be helpful to _____.
Select all that apply
For the following questions consider an application running on a system with virtual memory backed by 4 physical pages. Exactly one application is running and, initially, the all the physical pages are empty, and these physical pages are only used for this application's virtual memory.
The application that accesses its virtual memory pages (identified using letters like A, B, C, D, E, F, G, ...) in the following sequence:
The questions below ask about page replacements.
For these questions, count replacing the contents of an empty OR non-empty physical page with data for a particular virtual page as a page replacement.
Question 4 (1 points): (see above) What is the minimum number of page replacements required to complete the above access pattern? (See note above about what counts as a page replacement.) Write your answer as an integer.
Question 5 (1 points): (see above) To achieve the minimum number of page replacements described in the previous question,
a physical page containing the contents of _____ must be replaced with the contents of virtual page E.
Select all that apply
Question 6 (1 points): (see above) If an LRU (least recently used) replacement policy is used, how many page replacements are used to complete the above access pattern? (See note above about what counts as a page replacement.) Write your answer as an integer.
Question 1 (1 points): A second-chance replacement policy is an approximation of LRU (least recently used). For which of the following decisions is the second-chance replacement most likely to choose a page which has been accessed relatively recently?
When operating systems perform readahead for their page cache, they try to take advantage of sequential access patterns by detecting when a program appears to be accessing data sequentially. Then, they cache the data that the program should access next (based on the prior sequential accesses) before the program first accesses it.
Question 2 (1 points): (see above) After reading ahead pages X to X+K of a large file (where K is a relatively small portion of the available memory), an operating system wants to detect whether to readahead more pages from the file. To do this, which of the following is likely to minimize the number of page cache misses?
For non-file pages in its page cache (such as pages representing part of a process's stack or heap), the Linux kernel keeps a separate ordered accessed list and inactive list. Pages are initially added to the top of the active list. Pages are removed from the bottom of the active list and added to the top of the inactive list in order to keep the inactive list a certain size. If a page is accessed while on the inactive list, it is moved to the active list. Otherwise, pages are taken from the bottom of the inactive list to perform page replacements.
Suppose an operating system implements a page cache using this replacement policy where:
Question 3 (1 points): (see above) Suppose the program accesses its virtual pages in the following pattern that repeats indefinitely: (each letter identifies a virtual page)
How many of these accesses will require a page replacement?
Question 4 (1 points): (see above) Suppose the program accesses its virtual pages in the following pattern: (each letter identifies a virtual page)
The second access to A
will replace the page containing ____.
Question 5 (1 points): Suppose a mouse controller is connected to the processor via the memory bus. Whenever a mouse button is pressed or released or the mouse is moved, the mouse controller adds an a record of that event to a small buffer it maintains and signals the processor to trigger an interrupt. Suppose a process on this system can make a system call that waits for a mouse click to occur. (That is, the system call only cares about mouse clicks that occur after the system call is started.) To implement this system call, what would be the best choice for the device driver?
Question 6 (1 points): Which of the following are advantages of direct memory access (DMA) over programmed I/O
(where, in both cases, the device controller is attached to the memory bus)?
Select all that apply
Question 1 (1 points): When writing a 10000 cluster file to a FAT-based filesystem, which strategy is likely to minimize seek times for reading the file from a hard disk assuming the operating system caches the entire file allocation table in memory but other data from the disk is typically not cached?
Question 2 (1 points): Suppose an operating system wanted to make a filesystem that uses flash memory like is contained in an SSD but without the benefit of block remapping. In this design, the operating system is responsible for determining which flash pages (name for the equivalent for sectors in the flash hardware) data is stored in and triggering the erasure of an erasure block. Which of the following techniques would most help the filesystem get good reliablity out of the flash?
Question 3 (1 points): In order for a filesystem to get the best performance out of a hard disk drive, it is useful to ________.
Select all that apply
Suppose one has an inode-based filesystem where:
Question 4 (1 points): (see above) How many blocks must be allocated to store a 2000KB file on the filesystem? Ignore space required for inodes and directory entries but include any space outside of inodes required to store block pointers. (Write your answer as a base 10 number.)
Question 5 (1 points): (see above) How many blocks must be allocated to store a directory of 2 1KB files on the fiesystem? Ignore space required for inodes and any space required for the directory's directory entry in its parent directory, but include any space outside of inodes rquired to store block pointers and space required for directory entries for the 1KB files. (Write your answer as a base-10 number.)
Question 6 (1 points): (see above) How many inodes must be allocated to store a directory of 1000 2KB files on the fiesystem? Include any inodes required for the directory itself as well as the files it contains.
Question 7 (1 points): Which of the following schemes would be most space-efficient at storing the locations of the data for 20MB large file that is divided up into 4 contiguous 5MB segments? Assume 1K blocks for any inode-based filesystems, and 1K clusters for FAT filesystems.
Consider a inode-based filesystem. For each of these questions, consider the process of moving a subdirectory X from one parent directory A to another parent directory B, assuming that the filesystem needs to an additonal data block for the directory entry in directory B.
For these questions, ignore any changes to modification and creation times the filesystem may store in inodes and assume no additional data blocks need to be allocated to store block pointers.
Question 1 (1 points): (see above) Suppose this filesystem that attempts to keep data consistent and avoid data loss by using careful ordering of updates. As a result, for the entire move, the filesystem needs to perform the following updates:
What is an appropriate order for these operations occur in that would best avoid data loss and inconsistency? For example, if you think 1, then 2, then 3, then would be appropriate, write "1234".
Question 2 (1 points): (see above) Suppose this filesystem uses journalling with redo logging to keep data consistent and avoid data loss. As a result, for the entire move, the filesystem needs to perform the following updates:
What is an appropriate order for these operations occur in that would best avoid data loss and inconsistency? For example, if you think 1, then 2, then 3, then 4, then 5, then 9, then 7, then 8, then 9 again, write "123459789". (Multiple answers may be correct.)
Question 3 (1 points): Adding redo logging to a filesystem generally __________.
Select all that apply
Question 4 (1 points): In the POSIX sockets API, the connect()
function __________.
Question 5 (1 points): Which of the following is generally true about
the client/server based model of a distributed system?
Select all that apply
Question 1 (1 points): Which of the following are possible for an RPC system to implement over
a typical network?
Select all that apply
Question 2 (1 points): Given a C prototype like:
int ExampleFunction(char *s)
a typical RPC system needs extra information to create useful server and client stubs
that represent (for client stubs) or handle this function.
What would this information most likely include?
Select all that apply
Question 3 (1 points): Suppose in a system that uses two-phase commit,
agree-to-commit messages are sent to a coordinator from each of its three
workers. Immediately after this, the coordinator crashes and does not
return to service for a very long time.
Assuming maintaining consistency is the highest priority,
which of the following are acceptable things for a worker to do in this scenario
while the coordinator is still unavailable?
Select all that apply
Suppose two programs A and B running on separate machines are both accessing a file X on an NFSv3 server. They do the following operations in this order:
Assume no operations overlap in time. For example, when A and B close the file the first time, the close for B, and everything required as a result of the close, completes entirely before the close for A starts.
Question 4 (1 points): (see above) Suppose the machines A and B are running both do as much caching as is allowed by NFSv3 protocol and its open-to-close consistency model. Assume that they never need to evict values from the cache, except when required by the consistency model. What values would A read from file X in the read operation marked with ***** above?
Question 5 (1 points): (see above) Suppose the machines A and B are running both do as much caching as is allowed by NFSv3 protocol and its open-to-close consistency model. Assume that they never need to evict values from the cache, except when required by the consistency model. What values would B read from file X in th eread operation marked with +++++ above?
Question 1 (1 points): In a typical POSIX-style OS, during an open()
call, the file's access control lists are ______.
Question 2 (1 points): In a typical POSIX-like system, access control lists and file permissions are evaluated using ________.
Select all that apply
Question 3 (1 points): Consider a multiuser system with many users. Suppose on this system we want to implement a database of public contact
information for each user. We want to give each user the ability to edit their own contact information, but not
the ability to edit other user's contact information.
Which of the following mechanisms would be suitable for doing this?
Select all that apply
Question 4 (1 points): In a hypervisor implemented using trap-and-emulate, suppose the guest OS is running and the exception corresponding to system call occurs. The hypervisor should ______.
Question 5 (1 points): In a hypervisor implemented using trap-and-emulate,
suppose the guest OS is running and the exception corresponding to protection fault occurs.
Depending on the details of the protection fault and state around it, the hypervisor might want to
do which of the following?
Select all that apply
For this question, virtual address refer to addresses the guest OS accesses when it is running; physical addresses refer the addresses produced by taking virtual addresses and translating them using the guest OS's page table, and machine address refer to the addresses on the underlying hardware used the implement the corresponding physical addresses.
Consider a hypervisor uses shadow page tables to implement virtual memory.
Question 6 (0 points): (see above) [question dropped] Suppose a page fault occurs in the guest OS and:
rcr2()
in xv6) is 0x5043
which is in virtual page 50x50
When this page fault occurs, the hypervisor sometimes needs to modify or create a shadow page table entry. This entry can be found by reading the PTE at index _________ of the first level of the shadow page table, then, in the second-level table pointed to by that PTE, reading the PTE at index ______.
Question 7 (1 points): (see above) The shadow page table will primarily be read by _______.