Semaphore destroy vs lock destory

Based on reading the tests for locks, the correct implementation for lock_destroy seems to account for the lock being held by the thread destroying the lock or any other thread, in which case it panics.

However the implementation for semaphores being pretty similar to locks; why does sem_destroy not need to check whether the sem count is back to its initially set value? (I know this would mean adding to the semaphore structure to keep track of that initial value). If we don’t check this, sure sem destroy ensures that there aren’t any threads on the waiting channel (if so panics) and that the spinlock isn’t being held by a cpu but neither of these conditions mean that a thread isn’t executing in a critical section.

It is implicit that if the wait channel is empty and the spinlock is not currently being held, there cannot be another thread in a critical section that requires the semaphore (at that exact moment).

If another thread is in line and attempts to grab the use that semaphore after it has been destroyed, undefined behavior occurs.

Since there is no mechanism for making sure many threads/processes only call *_destroy() a single time, it’s up to you to make sure these things only get destroyed once. Does that help?

Yes thanks Matthew, I think wrapping my head around the use cases for semaphores is what I need to do.

Just start getting used to the idea that there can be lots of threads running at once, sharing file descriptors, sharing semaphores, sharing locks etc. If every thread had it’s own personal lock for some data, you would never have any threads waiting. You also wouldn’t be enforcing any mutual exclusion.

To manage this you need to keep some kind of record of whether it’s safe to destroy these things. That way, you provide a mechanism for the last executing thread to verify it’s safe to clean things up.

Some high level advice, hold back from jumping into the implementation on this assignment. You can’t hack your way through these last two. Take your time, identify requirements, ask lots of questions, and have a solid grasp of what is happening. You can then identify what is needed to fulfill the requirements of the assignment and proceed with designing that solution. Once you have a good sane design, start coding it up. If you are really smart you will start coding tests for your design first to catch logic errors during implementation.

I rushed into things a lot and got stuck and had to go back a few times. You spend the time reading slowly at some point, it might as well be at the front :slight_smile:

You could add this check, and it would make sense. We just don’t check this currently.