It works like this:
cpu1 cpu2
kill thread (on cpu2)
complete_and_exit()
- takes spinlock
wait_for_completion()
- spins on completion spinlock
- increments x->done
- wakes up anyone waiting on
the completion
- releases spinlock
- checks x->done
- decrements x->done
- releases spinlock
OR:
cpu1 cpu2
kill thread (on cpu2)
wait_for_completion()
- takes spinlock
complete_and_exit()
- spins on spinlock
- checks x->done
- adds to waitqueue
- releases spinlock
- increments x->done
- sleeps
- wakes up anyone waiting on
the completion
- wakes up
- spins on spinlock
- releases spinlock
- decrements x->done
- releases spinlock
OR:
cpu1 cpu2
kill thread (on cpu2)
wait_for_completion()
- takes spinlock
- checks x->done
- adds to waitqueue
- releases spinlock
- sleeps
complete_and_exit()
- takes spinlock
- increments x->done
- wakes up anyone waiting on
the completion
- wakes up
- spins on spinlock
- releases spinlock
- decrements x->done
- releases spinlock
As you can see, wait_for_completion() will never return until complete()
has released the spinlock.
-- Russell King (rmk@arm.linux.org.uk) The developer of ARM Linux http://www.arm.linux.org.uk/personal/aboutme.html- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/