Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.
The Intel sign-in experience has changed to support enhanced security controls. If you sign in, click here for more information.
2449 Discussions

Is it safe to spin on a volatile variable in user-mode threads?


I'm not quite sure if it's safe to spin on a volatile variable in user-mode threads, to implement a light-weight spin_lock, I looked at the TBB source code, tbb_machine.h:170,

//! Spin WHILE the value of the variable is equal to a given value
/** T and U should be comparable types. */
void spin_wait_while_eq( const volatile T& location, U value ) {
atomic_backoff backoff;
while( location==value ) backoff.pause();

And there is no fences in atomic_backoff class as I can see. And from other user-mode spin_lock implementation, most of them use CAS (Compare and Swap).

BTW, I also asked this question on stack-overflow, and the answer I got is, it's not safe if the compiler does not place fences for volatile variable accesses.

I'm expecting the TBB authors could give me a hint, thanks a lot!

0 Kudos
3 Replies
Valued Contributor I
It's not safe in general. A user of spin_wait_while_eq() must provide it's own fencing. Note that there are use cases that are just not require fencing at all.


Typically it is best to spin without a fence, and then once the spinning is done, do the fence. That way the fence impacts the system only once. For example, on Itanium, the recommended sequence foracquiring aspin lock is tospin with a plainload untilthe lock appearsto be available, and then use a cmpxchg.acq to attempt to grab the lock.

Seciton 2.4.1 "Spin Lock" ofIntel Itanium Architecture Software Developers Manual Volume 2: System Architecturediscusses this technique.

Valued Contributor I
Moreover, sometimes it's possible to issue a single fence for several objects. I.e. discover presence of messages in several queues, then issue a single acquire fence, then consume all the messages.