Implementation of condition variables
Apart from the missing return value checks, there are some more issues that should be fixable:
sem_destroy
is not called.- Signal/broadcast touch the
cond_node_t
after waking the target thread, potentially resulting in a use-after-free.
Further comments:
- The omitted destroy operation may require changes to the other operations so it is safe to destroy the condition variable when POSIX says it shall be safe. Not supporting destroy or imposing stronger restrictions on when it may be called will simplify things.
- A production implementation would handle thread cancellation.
- Backing out of a wait (such as required for thread cancellation and
pthread_cond_timedwait
timeouts) may lead to complications. - Your implementation queues threads in userland, which is done in some production implementations for performance reasons; I do not understand exactly why.
- Your implementation always queues threads in LIFO order. This is often faster (such as because of cache effects) but may lead to starvation. Production implementation may use FIFO order sometimes to avoid starvation.
Basically your strategy looks ok, but you have one major danger, some undefined behavior, and a nit pick:
- your are not inspecting the return values of your POSIX functions. In particular
sem_wait
is interruptible so under heavy load or bad luck your thread will be woken up spuriously. You'd have to carefully catch all that - none of your functions returns a value. If some user of the functions will decide to use the return values some day, this is undefined behavior. Carefully analyse the error codes that the condition functions are allowed to return and do just that.
- don't cast the return of
malloc
orcalloc
Edit: Actually, you don't need malloc
/free
at all. A local variable would do as well.