Usefulness of Interlocked* functions?
I read MSDN''s documentation on these functions and now I''m confused. What makes them useful?
InterlockedIncrement/Decrement ensure that when two threads increment or decrement a shared variable at the same time, both get accurate read results (the return value of operators ++ and -- in C++). Trouble is, InterlockedIncrement/Decrement may not always return the correct value - so why bother synchronizing it?
InterlockedExchange ensures that two threads don''t set the value of an integer at the same time, but what''s to stop one thread from setting it and another from reading it? What good is it to synchronize write access on a variable you can''t read?
(InterlockedExchangeAdd and InterlockedCompareExchange are not supported on Windows 95.)
March 02, 2001 11:04 AM
What do you mean by "InterlockedIncrement/Decrement may not always return the correct value"? There is a lot of code that relies on these functions and they work fine in my experience.
One of the most common uses for InterlockedExchange is to build your own syncronization scheme:
The way this works is that "lock" is a variable that is 0 if nobody is in the critical section and 1 otherwise. What the code does is to atomically read the current value and then set the lock to 1. If it gets back a 0 then it knows that nobody had the lock before it did. If it gets back a 1 then it knows that somebody else already had the lock.
-Mike
One of the most common uses for InterlockedExchange is to build your own syncronization scheme:
// Poor man''s critical sectionif (0 == InterlockedExchange(&lock, 1)){ // Only one thread at a time can get here lock = 0; // reset the lock when done}
The way this works is that "lock" is a variable that is 0 if nobody is in the critical section and 1 otherwise. What the code does is to atomically read the current value and then set the lock to 1. If it gets back a 0 then it knows that nobody had the lock before it did. If it gets back a 1 then it knows that somebody else already had the lock.
-Mike
Straight from MSDN:
That''s from the docs on InterlockedIncrement. InterlockedDecrement says basically the same thing. This worries me - why can''t you count on it returning the correct resulting incremented value?
With regards to all of the Interlocked* functions, you are only supposed to read the value by checking the return value of the Interlocked* function? Okay, I think I understand how that works now.
quote:
Excerpt from MSDN
Return Values
Windows 98, Windows NT 4.0 and later: The return value is the resulting incremented value.
Windows 95, Windows NT 3.51 and earlier: If the result of the operation is zero, the return value is zero. If the result of the operation is less than zero, the return value is negative, but it is not necessarily equal to the result. If the result of the operation is greater than zero, the return value is positive, but it is not necessarily equal to the result.
That''s from the docs on InterlockedIncrement. InterlockedDecrement says basically the same thing. This worries me - why can''t you count on it returning the correct resulting incremented value?
With regards to all of the Interlocked* functions, you are only supposed to read the value by checking the return value of the Interlocked* function? Okay, I think I understand how that works now.
First of all the most obvious benefit of the Interlocked* functions is that they work in user mode. The functions do not have to transition to kernel mode and back which saves CPU cycles (approximately 50 cycles for Interlocked* and typically 1000 cycles for kernel mode functions).
Another good purpose of Interlocked* functions is that they do not allow other CPUs to to access the same memory address (hence proper multi-processor serialized access to memory).
To be honest with you I''d rather use InterlockedIncrement/Decrement under Windows 98/NT 4 or higher because you can then use the return value of the function. I''m wondering if Windows 95 and NT 3.51 do not implement the Incremented functions in a way that the return value can be returned atomically (without possibility of the value being changed).
It is better to use InterlockedIncrement/Decrement over EnterCriticalSection/LeaveCriticalSection for simple incrementing and decrementing of variables (it''s surprising how many people don''t use InterlockedDecrement etc);
Swapping values should be done using InterlockedExchangePointer.
InterlockedCompareExchange is an excellent way to serialize:
by doing it this way:
InterlockedCompareExchange(&result, newvalue, value);
Hopefully this explains a few things ( and hopefully I haven''t got anything wrong
)
Dire Wolf
www.digitalfiends.com
Another good purpose of Interlocked* functions is that they do not allow other CPUs to to access the same memory address (hence proper multi-processor serialized access to memory).
To be honest with you I''d rather use InterlockedIncrement/Decrement under Windows 98/NT 4 or higher because you can then use the return value of the function. I''m wondering if Windows 95 and NT 3.51 do not implement the Incremented functions in a way that the return value can be returned atomically (without possibility of the value being changed).
It is better to use InterlockedIncrement/Decrement over EnterCriticalSection/LeaveCriticalSection for simple incrementing and decrementing of variables (it''s surprising how many people don''t use InterlockedDecrement etc);
Swapping values should be done using InterlockedExchangePointer.
InterlockedCompareExchange is an excellent way to serialize:
if(result == value)
{
result = newvalue;
}
by doing it this way:
InterlockedCompareExchange(&result, newvalue, value);
Hopefully this explains a few things ( and hopefully I haven''t got anything wrong
![](smile.gif)
Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
www.digitalfiends.com
Thanks, Dire.Wolf!
BTW, with the newer API functions only being supported for Windows 98 and Windows 2000, does anyone think it is a good idea to drop support for Windows 95?
BTW, with the newer API functions only being supported for Windows 98 and Windows 2000, does anyone think it is a good idea to drop support for Windows 95?
In my opinion I''d say yes. Unless you are programming software for a client that has not moved beyond Windows 95 it''s better to drop support for Windows 95 IMHO.
Dire Wolf
www.digitalfiends.com
Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
www.digitalfiends.com
The Win95 version probably did InterlockedIncrement using "lock inc". inc doesn''t return anything but zero or non-zero and the sign so the restrictions in the docs are obvious.
Later versions probably use xadd instead of inc so they can get away with returning the value reliably.
I wouldn''t give up Win95 soley on the basis of missing Interlocked functions. They''re trivial to write in inline assembly.
-Mike
Later versions probably use xadd instead of inc so they can get away with returning the value reliably.
I wouldn''t give up Win95 soley on the basis of missing Interlocked functions. They''re trivial to write in inline assembly.
-Mike
-Mike
Thanks for the info. I'm not overly up on the specifics of CPU instructions so thats a good piece of info. Thanks.
Dire Wolf
www.digitalfiends.com
Edited by - Dire.Wolf on March 6, 2001 12:30:13 AM
Dire Wolf
www.digitalfiends.com
Edited by - Dire.Wolf on March 6, 2001 12:30:13 AM
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
www.digitalfiends.com
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement