[System] Ensure we use logical shift and not arithmetic shift
authorJeremie Laval <jeremie.laval@gmail.com>
Fri, 27 Jul 2012 13:16:56 +0000 (14:16 +0100)
committerJeremie Laval <jeremie.laval@gmail.com>
Fri, 27 Jul 2012 13:17:57 +0000 (14:17 +0100)
mcs/class/System/System.Collections.Concurrent/ConcurrentBag.cs

index 827bc74b83cdca80c0bf7127051d4b99d64f6bb1..5998c061ab0302690b8f07f5328a0919759de805 100644 (file)
@@ -153,15 +153,19 @@ namespace System.Collections.Concurrent
                                return;
                        var hs = hints;
                        // If cas failed then we don't retry
-                       Interlocked.CompareExchange (ref hints, (hs << 4) | (uint)index, hs);
+                       Interlocked.CompareExchange (ref hints, (long)(((ulong)hs) << 4 | (uint)index), (long)hs);
                }
 
                bool TryGetHint (out int index)
                {
+                       /* Funny little thing to know, since hints is a long (because CAS has no ulong overload),
+                        * a shift-right operation is an arithmetic shift which might set high-order right bits
+                        * to 1 instead of 0 if the number turns negative.
+                        */
                        var hs = hints;
                        index = 0;
 
-                       if (Interlocked.CompareExchange (ref hints, hs >> 4, hs) == hs)
+                       if (Interlocked.CompareExchange (ref hints, (long)(((ulong)hs) >> 4), hs) == hs)
                                index = (int)(hs & 0xF);
 
                        return index > 0;