/* semaphore representation known only to semaphore methods */
struct semaphore {
int count;
struct thread_queue queue;
};
/* methods applying to semaphores */
void thread_semaphore_init( struct semaphore * s, int v )
/* call this to initialize semaphore s to a count of v */
{
s->count = v;
thread_queue_init( &s->queue );
}
void thread_wait( struct thread_semaphore * s )
/* call this within a thread to block on a semaphore */
{
if (s->count > 0) {
s->count--;
} else {
if (_setjmp( current->state ) == 0) {
thread_enqueue( current, &s->queue );
current = thread_dequeue( &readylist );
if (current == thread_null) {
/* crisis */
thread_error = "possible deadlock";
_longjmp( thread_death, 1 );
}
_longjmp( current->state, 1 );
}
}
}
void thread_signal( struct thread_semaphore * s )
/* call this within a thread to signal a semaphore */
{
struct thread * t = thread_dequeue( &s->queue );
if (t == thread_null) {
s->count++;
} else {
thread_enqueue( t, &readylist );
}
}
Problem: a)
Explain the major differences between this implementation of semaphores
and the implementation given at the end of the notes for
lecture 3.
Problem: b) Explain why it is desirable to include a completely different definition of the type semaphore in the header file than is included with the C source code. For example, why might the following definition be desirable in the header file:
struct semaphore {
void * unused_fields[3];
};
Problem: c)
Put all of the above code into your copy of the semaphore implementation,
get it to compile correctly, and prepare for next week's assignment involving
writing a parallel application using semaphores to mediate interprocess
communication. Your answer to this question should be in the form of a
statement that you have done this, with no proof required!