I do not believe that spinning a bit before invoking the operating system is an efficient method.
Checking at least once if the lock is free is absolutely necessary before invoking the operating system.
Optionally, it is good to wait a short time (e.g. with an empty loop) and then check again if the lock is free, before invoking the operating system to wait.
On the other hand, to execute repeatedly in a loop atomic read-memory-write instructions on the address contended with other threads wastes energy and it wastes time for the other threads, due to the generated cache traffic. Even if spinning on the lock gives a higher chance for your thread to be the first that will get the lock, this makes the performance worse for the whole system. If you must be certain that no other thread gets the lock before, at least a ticket lock should be used, if not a better queued lock.
If you define spinning to mean the most naive and bad way to repeatedly check a condition, then yes that would be bad, tautologically. Some libraries have used the x86 PAUSE instruction or its equivalent. Recent x86 offers UMWAIT which is also applicable. These are both good and efficient ways to briefly wait.
Checking at least once if the lock is free is absolutely necessary before invoking the operating system.
Optionally, it is good to wait a short time (e.g. with an empty loop) and then check again if the lock is free, before invoking the operating system to wait.
On the other hand, to execute repeatedly in a loop atomic read-memory-write instructions on the address contended with other threads wastes energy and it wastes time for the other threads, due to the generated cache traffic. Even if spinning on the lock gives a higher chance for your thread to be the first that will get the lock, this makes the performance worse for the whole system. If you must be certain that no other thread gets the lock before, at least a ticket lock should be used, if not a better queued lock.