/* 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!