CS 537 - Quiz #5 1. Remember how I said it's easy to implement semaphores with locks and CVs, but difficult the other way around? Let's look at that: typedef struct __cond_t { sem_t s; } cond_t; void cond_init(cond_t *c) { sem_init(&c->s, 0); } void cond_wait(cond_t *c, mutex_t *m) { mutex_unlock(&m); // release lock and go to sleep sem_wait(&c->s); mutex_lock(&m); // grab lock before returning } void cond_signal(cond_t *c) { sem_post(&c->s); // wake up one waiter (if there is one) } Why doesn't this work properly? (Hint: think about how you would expect a CV to behave if it signals and there's nothing in the queue. What happens next?)