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:
- pthread_mutex_t go;
- pthread_cond_t cond;
- int stop;
and initialize. What initial values?
Create three functions to control the database client threads
- clientwait()
- clientgo()
- clientstop()
Use the global struct in these functions.
What should each one do and how should each one be implemented?
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).
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);
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);
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);
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);
What is the errno problem? the solution?
Pending Signals
Blocked Signals
Signal Handlers
What are the possible choices? What choices were made for
POSIX?
- Does each thread have its own separate set of pending/blocked signals
- Does each thread have its own separate set of signal handlers?
- Which thread(s) receives a given signal?
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(thrd) sends a signal to thread with id thrd.
pthread_cancel(thrd) terminates the thread with id thrd, but
...
- Cancel state: disabled or enabled
- Cancel type: asynchronous or deferred
- Cancel cleanup
Default: enabled and deferred
pthread_cleaup_push(func, func_arg)
pthread_cleanup_pop(int flag)
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.
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);
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.