CS360 Final Exam - April 30, 2014 - James S. Plank

Answers and Explanations

Question 1

Straightforward malloc() question. The first thing that you should do is figure out the size of each memory block, and then put that size 8 bytes before the malloc() pointers:
  1. malloc(5): Size = 16 bytes, starting at 0xb80f0.
  2. malloc(12): Size = 24 bytes, starting at 0xb8000.
  3. malloc(8): Size = 16 bytes, starting at 0xb8020.
  4. malloc(8): Size = 16 bytes, starting at 0xb8048.
  5. malloc(16): Size = 24 bytes, starting at 0xb8070.
  6. malloc(20): Size = 32 bytes, starting at 0xb80b0.
Draw rectangles around these guys, and now the unrectangled regions of memory will be the nodes on the free list. However, before you start making the freelist, you should note that the first free region -- the eight bytes starting at 0xb8018 -- are not big enough to hold a free list node. So, you simply allocate them to the malloc'd memory: The block starting at 0xb8000 should be 32 bytes long rather then 24.

Go ahead now and put in the free nodes:

You can see the answer in This pdf file..

Grading


Question 2

setjmp() stores the state of the registers into jmpbuf, and returns zero. This includes the stack pointer, frame pointer and program counter.

longjmp() restores the registers. Since this include the stack pointer, frame pointer and program counter, this means that longjmp() doesn't return, and instead, setjmp() returns. It returns with the argument to longjmp() as a return value.

The following program calls setjmp(), which will return 0. It will print "First", and then call longjmp(), which will return from the setjmp() call, but with a return value of one. It will thus print Second and then exit.

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

main()
{
  jmp_buf b;
  int i;

  i = setjmp(b);

  if (i == 0) {
    printf("First\n");
  } else {
    printf("Second\n");
    exit(0);
  }   

  longjmp(b, 1);
}

Grading


Question 3 - 16 points

Part A: There are two cases to your code -- first, suppose that the keyword is not in the tree. You should insert it into the tree with your person pointer as the val. Then you block on your condition variable. When you wake up, your match will have been found, and you will have been taken off the tree. You simply unlock the mutex and return.

In the second case, the keyword is in the tree. You need to set your match to the person in that node. Also, go ahead and set the match of that person to you, and delete the person from the tree. Finally, signal the person to wake him/her up:

The code below does this. You may be tempted to have the person who first called find_match() be the one to remove itself from the tree, but that's going to get you in trouble, because a third client may get the mutex before the first client gets it waking up from his signal call.

void find_match(Person *me, char *keyword)
{
  JRB tmp;

  pthread_mutex_lock(lock);
  tmp = jrb_find_str(tree, keyword);
  if (tmp == NULL) {
    jrb_insert_str(tree, keyword, new_jval_v((void *) me));
    pthread_cond_wait(me->cond, lock);
  } else {
    me->match = (Person *) tmp->val.v;
    me->match->match = me;
    jrb_delete_node(tmp);
    pthread_cond_signal(me->match->cond);
  }
  pthread_mutex_unlock(lock);
}

Part B: In the code above, the specified scenario may indeed occur:

Grading

Part A:This one starts at 12 points, and you suffer deductions when things aren't right.

Part B: Four points.


Question 4 - 5 points

If a thread does not call pthread_detach(), and if no thread calls pthread_join() on it, then its stack never gets deallocated. Eventually, you run out of space to allocate stacks, and if you're not checking return values to pthread_create(), youll seg fault.

The reason this doesn't happen in a single gradescript call is that there's enough room for a lot of stacks. Every gradescript has multiple clients attach to the server, so they all create stacks. In the beginning, there is enough space for all of these stacks. However, around gradescript 50, you run out of room, and get the seg fault.

Grading

5 points.


Question 5 - 24 points

Question 5A: Just once -- it is only creating "shemp child," who is creating the rest.

Question 5B: "Shemp Child" calls fork() three times -- once each for larry, moe and curly.

Question 5C: None -- the parent and child are sharing code, so both will be in code that follow's the parent's fork() statement. Since none of your programs take command line arguments, you'll have a hard time convincing me that you can call exec() on shemp and have the child figure out that it's the child...

Question 5D: I'd accept two answers. The first is zero -- it's the larry, moe and curly processes that are calling exec, not "Shemp Child." Three times is actually what I had in mind though -- once for each of larry, moe and curly -- either answer got full credit.

Question 5E: Just once -- this is the pipe for the parent's standard input.

Question 5F: Twice -- it will close both ends of the pipe after duping the pipe onto file descriptor zero.

Question 5G: At least eight, and potentially eleven. It is going to have to close all eight ends of the four pipe() calls (the pipe from the parent will be opened, so that larry, moe and curly can access it). It may want to close 0, 1 and 2 as well.

Question 5H: Three times -- once for standard input, once for standard output, and once for standard error.

Question 5I: "Shemp child" should be calling wait(), which will return when the first child dies. In this case, it will return when moe seg faults. The return value of wait() contains information about how moe died, including the signal number of SIGSEGV.

Question 5J: Curly has been making write() calls to standard output, which is to a pipe. When moe dies, the read end of the pipe is gone, so curly will get the SIGPIPE signal and die.

Question 5K: When they all die, there is no write end of the pipe to "shemp parent"'s standard input. Thus, it will read EOF.

Question 5L: Just once -- it needs to call wait() to clean up "shemp child." Because "shemp child" exits, larry, moe and curly can't be zombies.

Grading

Two points per answer, except three points for I and L, which are three each.