I have now renamed thread_wait_on_goal/2 to simply thread_wait/2 and added thread_update/1. I think that finished round one for this interface.
thread_update/2 has an option to control this. The default is to wake all waiting threads (broadcast as POSIX calls it).
As a module now bundles the data, CV and lock, you can only handle them as a triple. You can of course have multiple modules. Multiple condition variables can do nothing new as you can do the same adding some data that tells the waiting threads what to look for. Multiple condition variables can only avoid unnecessary wakeup. We already have additional conditions for the wakeup to only watch certain predicates and either watch any modification or only assert or only retract. That still may lead to more than necessary wakeups, but we should be able to reduce this further given the current interface.
Possibly, but I’d rather go for transactions. These allow for concurrent read with an ongoing update without the need for locks. Still, lock based updating of a shared database is a can of worms. It will probably be needed for some specific cases, but I rather invest time in stuff that reduces the need for locks.