















Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
These are the Exam of Operating System which includes Caller-Save, Trap Frame, Interrupt Handling, Latest, Processor-Architecture News, Building, Management, Analysis, Management etc.Key important points are: Kernel Mode, Standard Form, Requirement, Format Presented, Demonstrates, Solution, Critical-Section Protocol, Extra, Space, Page
Typology: Exams
1 / 23
This page cannot be seen from the preview
Don't miss anything!
















think clearly about a problem, you will probably have time to write your answer legibly.
Give a definition of each of the following terms as it applies to this course. We are expecting three to five sentences or “bullet points” for each definition. Your goal is to make it clear to your grader that you understand the concept and can apply it when necessary.
(a) 5 points “Atomic instruction sequence”
(b) 5 points “kernel mode”
Use this page for your solution to the critical-section protocol question.
You may use this page as extra space for the critical-section protocol question if you wish.
int main(int argc, char argv[]) { total_exams = 54; // should come from command line if (thr_init(641024)) panic("thr_init");
mutex_init(&table_lock); table_exams = total_exams; graded_exams = 0; graders[0].waiting = -1; cond_init(&graders[0].removed); graders[1].waiting = -1; cond_init(&graders[1].removed);
if ((thr_create(run_grader, (void) 0) < 0) || (thr_create(run_grader, (void) 1) < 0)) panic("thr_create"); thr_exit(0); exit(0); // placate compiler }
// This can take a while, so we enter and leave with the table unlocked. int handle_exam(int i, int j, int e) { if (examine_exam_number(e) >= 0) { // I was able to assign a score myself! // Note that this is ALWAYS true if I am the second reader. printf("Grader %d graded exam %d.\n", i, e); mutex_lock(&table_lock); ++graded_exams; mutex_unlock(&table_lock); return 1; } else { // I wrote down some comments, now my partner will finish grading. printf("Grader %d perplexed by exam %d.\n", i, e); mutex_lock(&table_lock); while (graders[j].waiting > 0) { cond_wait(&graders[j].removed, &table_lock); } graders[j].waiting = e; mutex_unlock(&table_lock); printf("Grader %d handed off exam %d.\n", i, e); return 0; } }
void *run_grader(void *vid) { int i = (int) vid; int j = 1 - i;
while (graded_exams < total_exams) { int e; int succeeded = 1;
mutex_lock(&table_lock);
if (table_exams > 0) { e = table_exams--; mutex_unlock(&table_lock); succeeded = handle_exam(i, j, e); mutex_lock(&table_lock); }
if (succeeded && graders[i].waiting > 0) { e = graders[i].waiting; graders[i].waiting = -1; mutex_unlock(&table_lock); cond_signal(&graders[i].removed); handle_exam(i, j, e); } else { mutex_unlock(&table_lock); } }
printf("Grader %d is DONE GRADING!\n", i); thr_exit(0); exit(0); // placate compiler }
Suggestions for working on this problem:
You may use this page as extra space for the first part of the exam-grading question if you wish.
(b) 5 points Briefly describe how to fix or restructure the code so that it does not deadlock. It is not necessary for your answer to include code for it to receive full credit if it is clear and convincing (be sure to indicate how your solution addresses one or more deadlock ingredient(s)).
You may use the buffer t structure described previously in your implementation.
Your solution can use Project 2 thread library mutexes, condition variables, and/or semaphores, which you may assume to be strictly-FIFO if you wish. You may use deschedule()/make runnable() if you must, though we don’t recommend it; otherwise, you may not use other atomic or thread- synchronization operations, such as, but not limited to: reader/writer locks or any atomic instruc- tions (XCHG,LL/SC). You may use various system calls not prohibited above, e.g., get ticks(), if you wish, and non-synchronization-related thread-library routines in the “thr xxx() family,” e.g., thr getid(). For the purposes of the exam you should assume an error-free envi- ronment (memory allocation and initialization functions will always succeed; system calls and thread-library primitives will not detect internal inconsistencies or other- wise “fail” (unless you indicate in your comments that you have arranged, and are expecting, a particular failure), etc.). You may wish to refer to the “cheat sheets” at the end of the exam.
It is strongly recommended that you rough out an implementation on the scrap paper provided at the end of the exam, or on the back of some other page, before you write anything on the next page. If we cannot understand the solution you provide on the next page, your grade will suffer!
Hint: it is possible to implement both the synchronous and asynchronous functionality in terms of common “core code” with one or more small modifications “around the edges.” Such implementa- tions might even be more likely to be correct...
Please declare a struct chan and implement chan init(), chan send(), and chan receive() (you do not need to implement chan destroy()).
typedef struct chan {
} chan_t;
...space for channel implementation...
You may use this page as extra space for your channel solution if you wish.
In Project 2, you implemented a traditional 1:1 thread library in which the size of every created thread was identical and specified to thr init() as the thread library was initialized.
This can be inconvenient for an application developer writing multi-threaded code. The stack size must be set according to the maximum needs of any code path which will run in any thread. This can result in a multi-threaded application allocating much more memory for thread stacks than is actually required.
“Segmented stacks” are one solution to this problem. In a segmented-stack system, each thread begins with a relatively small stack. When stack space is running low, the thread allocates a new block of space and begins using that space for its stack. If that space is eventually no longer needed, the thread will free it and return to using its previous stack. The Go programming language uses segmented stacks and an M:N thread library to efficiently support hundreds of thousands of Go threads (called “goroutines”) at once. The LLVM compiler project has experimental support for compiling C code to use segmented stacks.
A C program can manually implement segmented stacks even if the compiler and standard run-time do not provide them. In this question we will ask you to implement, using a mixture of C and assembly language, a crude segmented-stack facility called ss call().
In particular, we will ask you to implement void *ss call(size t stack size, void (func)(void *), void arg) such that invoking ss call(201024, my function, foo) is equivalent to calling my function(foo) except that the execution of my function() will take place in a new 20-kilobyte stack segment, which will be freed after that invocation of my function() returns.
(a) 10 points Implement the ss call() facility. We expect most solutions to be phrased in terms of a short C function and a short assembly-language routine. For the purposes of the exam you should assume an error-free environment (memory allocation and initialization functions will always succeed; system calls and thread-library primitives will not detect internal inconsistencies or otherwise “fail” (unless you indicate in your comments that you have arranged, and are expecting, a particular failure), etc.).
One awkward aspect of ss call() is that an application developer still must guess how much stack space the function being called will need. During development, it would be helpful if memory corruption caused by stack overflows were detected “fairly quickly” when “easily possible.”
(b) 5 points Briefly, in a few sentences, describe a way that ss call() can be modified to help detect such errors.
System-Call Cheat-Sheet
/* Life cycle */ int fork(void); int exec(char *execname, char *argvec[]); void set_status(int status); void vanish(void) NORETURN; int wait(int *status_ptr); void task_vanish(int status) NORETURN;
/* Thread management / int thread_fork(void); / Prototype for exam reference, not for C calling!!! */ int gettid(void); int yield(int pid); int deschedule(int flag); int make_runnable(int pid); int get_ticks(); int sleep(int ticks); / 100 ticks/sec / typedef void (swexn_handler_t)(void *arg, ureg_t *ureg); int swexn(void *esp3, swexn_handler_t eip, void *arg, ureg_t *newureg):
/* Memory management */ int new_pages(void * addr, int len); int remove_pages(void * addr);
/* Console I/O */ char getchar(void); int readline(int size, char *buf); int print(int size, char *buf); int set_term_color(int color); int set_cursor_pos(int row, int col); int get_cursor_pos(int *row, int *col);
/* Miscellaneous */ void halt(); int ls(int size, char *buf);
/* "Special" */ void misbehave(int mode);
If a particular exam question forbids the use of a system call or class of system calls, the presence of a particular call on this list does not mean it is “always ok to use.”