Consider a scenario in kernel where we are initiating some activity outside of the current thread, then waiting for that activity to complete. This kind of synchronization could be well achieved by using semaphores. But, it is considered to be a good practice to use completions instead.
Why are completions preferred over semaphores in such situations?
Completions can be considered as condition variables, and mostly these are implemented using semaphores with a wrapper over it. Is this not true for completions in Linux kernel?
Also, the documentation says completions are better and lightweight than semaphores. How is implementation of completion different from semaphores that adds to these advantages?