I know that we can use pthread_cond_init
, pthread_cond_wait
, and pthread_cond_broadcast
to implement thread condition signaling in user space. But how can we implement it in a kernel module that is using kthread
?
linux/mutex.h provides locking as discussed in this question. But it does not seem to be associated with any condition variables.
linex/wait.h seems to have condition waiting but it has no documentation so there are too many concerns around it. For example, wake_up_interruptable
could have a race condition when used as suggested in examples with no mutex. It seems unlikely that the wait queues could be combined with mutex waits in a way that would implement semantics like pthread_cond_wait
, because the thread scheduling functions implementing these different APIs need to be integrated to provide atomic semantics.
How can a kernel module get atomic sleep-and-unlock semantics, like in a normal user-space API, like pthread_cond_wait
?
The specific semantics I need are (from the pthread_cond_wait*
manpage):
These functions atomically release mutex and cause the calling thread to block on the condition variable cond; atomically here means "atomically with respect to access by another thread to the mutex and then the condition variable". That is, if another thread is able to acquire the mutex after the about-to-block thread has released it, then a subsequent call to pthread_cond_broadcast() or pthread_cond_signal() in that thread shall behave as if it were issued after the about-to-block thread has blocked.
The important requirements are:
- The condition is a shared structure, and can only be accessed when the mutex is held.
- Atomicity prevents the condition from becoming true in between the mutex release and thread blocking. Without this, the thread could check the condition (when it's false), then release the mutex, then the condition becomes true (and a signal is generated and propagated), and then the thread falls asleep and misses the signal.
(Here is how pthread_cond_wait
is used in a program).