CSC443 Jan29

slide version

single file version

Contents

  1. Today
  2. Stop and Start commands
  3. db.h an db.c:
  4. Barrier Problem (1)
  5. Barrier (2)
  6. Barrier (3)
  7. Barrier Posix Solution
  8. Single Threaded C Libraries and Multithreaded Processes: errno
  9. Single Threaded C Libraries and Multithreaded Processes: printf
  10. Signals and Multithreaded Processes
  11. Dedicating One Thread for Signals
  12. pthread_kill an pthread_cancel
  13. Cleanup
  14. Deferred type and Cancellation Points
  15. Example
  16. Program Assignment 2

Today[1] [top]

  1. Second and third parts of program assignment 1
  2. Finish chapter 2 thread topics
  3. Program Assignment 2

Stop and Start commands[2] [top]

Modify the main function in server.c to handle 's' and 'g' commands as well as creating new threads (blank line - no command)

Define a global struct in server.c with members of type:

and initialize. What initial values?

Create three functions to control the database client threads

Use the global struct in these functions.

What should each one do and how should each one be implemented?

db.h an db.c:[3] [top]

Add an member of type pthread_rwlock_t to the node type Node_t

Modify Node_constructor function to initialize this extra member.

Use a enum for the two lock types (in db.c is ok):

enum lock_type = {dblock_read, dblock_write};

Add a parameter to the search function in db.c for lock_type.

Modify query, add, and xremove functions to call search with the appropriate lock_type value. E.g., query should call with dblock_read.

For fine grain locking, only nodes that are involved in being changed need be locked. As search moves down the tree, how many nodes need to be locked?

Before calling search, query, add, and xremove should lock the head node.

When search returns, query, add, and xremove should unlock node(s) that remain locked, but this depends on which function called search and/or whether the search was successful (found the name).

Barrier Problem (1)[4] [top]

Problem: Want to block threads until all n have been blocked, then release all (possibly repeat).

Not a solution:

    1	  pthread_mutex_lock(&m);
    2	  if (++count == number) {
    3	  
    4	    pthread_cond_broadcast(&cond_var);
    5	  } else {
    6	    while (!(count == number)) 
    7	      {
    8		pthread_cond_wait(&cond_var, &m);
    9	      }
   10	  }
   11	  pthread_mutex_unlock(&m);

Barrier (2)[5] [top]

Also not a solution:

    1	  pthread_mutex_lock(&m);
    2	  if (++count == number) {
    3	  
    4	    pthread_cond_broadcast(&cond_var);
    5	    count = 0;
    6	  } else {
    7	    while (!(count == number)) 
    8	      {
    9		pthread_cond_wait(&cond_var, &m);
   10	      }
   11	  }
   12	  pthread_mutex_unlock(&m);

Barrier (3)[6] [top]

Should be, but isn't a POSIX solution

    1	  pthread_mutex_lock(&m);
    2	  if (++count == number) {
    3	  
    4	    pthread_cond_broadcast(&cond_var);
    5	    count = 0;
    6	  } else {
    7	    pthread_cond_wait(&cond_var, &m);
    8	  }
    9	  pthread_mutex_unlock(&m);

Barrier Posix Solution[7] [top]

    1	  pthread_mutex_lock(&m);
    2	  if (++count < number) {
    3	    int my_generation = generation;
    4	    while(my_generation == generation) {
    5	      pthread_cond_wait(&waitQ, &m);
    6	    }
    7	  } else {
    8	    count = 0;
    9	    generation++;
   10	    pthread_cond_broadcast(&waitQ);
   11	  }
   12	  pthread_mutex_unlock(&m);

Single Threaded C Libraries and Multithreaded Processes: errno[8] [top]

What is the errno problem? the solution?

Single Threaded C Libraries and Multithreaded Processes: printf[9] [top]

Problem? Solution?

Signals and Multithreaded Processes[10] [top]

Pending Signals

Blocked Signals

Signal Handlers

What are the possible choices? What choices were made for POSIX?

  1. Does each thread have its own separate set of pending/blocked signals
  2. Does each thread have its own separate set of signal handlers?
  3. Which thread(s) receives a given signal?

Dedicating One Thread for Signals[11] [top]

The sigwait function blocks until a signal in the specified set is received.

What if more than one of those signals received?

What if several threads are calling sigwait for the same signal(s)?

computation_state_t state;
sigset_t set;
main( ) {
  pthread_t thread;

  sigemptyset(&set);
  sigaddset(&set, SIGINT);
  sigprocmask(SIG_BLOCK,
	      &set, 0);
  pthread_create(&thread, 0, monitor, 0);
  long_running_procedure( );
}

void *monitor( ) {
  int sig;
  while (1) {
    sigwait(&set, &sig);
    display(&state);
  }
  return(0);
}

pthread_kill an pthread_cancel[12] [top]

pthread_kill(thrd) sends a signal to thread with id thrd.

pthread_cancel(thrd) terminates the thread with id thrd, but ...

Default: enabled and deferred

Cleanup[13] [top]

pthread_cleaup_push(func, func_arg)

pthread_cleanup_pop(int flag)

Deferred type and Cancellation Points[14] [top]

What does deferred mean?

What are valid cancellation points?

read and write are cancellation points

pthread_cond_wait is a cancellation point, but ...

pthread_mutex_lock is NOT a cancellation point.

Example[15] [top]

What does this code do if it is "cancelled while in the pthread_cond_wait call?

Does the thread leaving the mutex locked?

Does the cleanup try to unlock a mutex that is not locked?

    1	pthread_mutex_lock(&m);
    2	pthread_cleanup_push(pthread_mutex_unlock, &m);
    3	while(should_wait)
    4	  pthread_cond_wait(&cv, &m);
    5	
    6	// . . . (code containing other cancellation points)
    7	
    8	pthread_cleanup_pop(1);

Program Assignment 2[16] [top]

On Linux (cdmlinux or you if you have linux installed, you can use your installation)

Implement user level thread library: i.e., could be a substitute for POSIX pthreads.

80% of code provided!

19 functions to write.

Test suite provided. (9 tests, can be run individually or all at once)

A make target (nyi) displays the function, line number, file of code that is NOT_YET_IMPLEMENTED.