However, as you say, some end up being hideously complicated. Some are "closer to the metal" than others - both in terms of the actual instruction set implementation, and kernel mechanisms used.
I've never been a fan of semaphores, because when used with count>1, they tend to be duplicating some other information in the system, which is easy to get out of sync. When used with just count 0 or 1, it's more intuitive (and closer to underlying implementation) to just use a mutex. And as you point out, the various mutex incarnations usually have an easier time of tracking ownership and debugging, by their nature.