Support PicoSpinLock on MSVC
authorChristopher Dykes <cdykes@fb.com>
Tue, 26 Jul 2016 23:17:39 +0000 (16:17 -0700)
committerFacebook Github Bot 3 <facebook-github-bot-3-bot@fb.com>
Tue, 26 Jul 2016 23:23:31 +0000 (16:23 -0700)
Summary:
It was using inline assembly in order to get atomic single-bit operations, so add a variant for MSVC that uses intrinsics.
MSVC is also weird in-that it doesn't have a 16-bit variant of these, so use an atomic OR and AND to achieve the required effect.

Reviewed By: yfeldblum

Differential Revision: D3623220

fbshipit-source-id: b4ff985ef2ed7787115f4d20de6f244123410dc8

folly/PicoSpinLock.h

index 32c5abfb43ae742895a27cde78f9fa802c1eb572..9f52a7a9a86e5af27b9c94a7730a65f6afa8ed1c 100644 (file)
@@ -128,7 +128,20 @@ struct PicoSpinLock {
   bool try_lock() const {
     bool ret = false;
 
-#if FOLLY_X64
+#ifdef _MSC_VER
+    switch (sizeof(IntType)) {
+      case 2:
+        // There is no _interlockedbittestandset16 for some reason :(
+        ret = _InterlockedOr16((volatile short*)&lock, 1 << Bit) & (1 << Bit);
+        break;
+      case 4:
+        ret = _interlockedbittestandset((volatile long*)&lock_, Bit);
+        break;
+      case 8:
+        ret = _interlockedbittestandset64((volatile long long*)&lock_, Bit);
+        break;
+    }
+#elif FOLLY_X64
 #define FB_DOBTS(size)                                  \
   asm volatile("lock; bts" #size " %1, (%2); setnc %0"  \
                : "=r" (ret)                             \
@@ -193,7 +206,20 @@ struct PicoSpinLock {
    * integer.
    */
   void unlock() const {
-#if FOLLY_X64
+#ifdef _MSC_VER
+    switch (sizeof(IntType)) {
+      case 2:
+        // There is no _interlockedbittestandreset16 for some reason :(
+        _InterlockedAnd16((volatile short*)&lock, ~(1 << Bit));
+        break;
+      case 4:
+        _interlockedbittestandreset((volatile long*)&lock_, Bit);
+        break;
+      case 8:
+        _interlockedbittestandreset64((volatile long long*)&lock_, Bit);
+        break;
+    }
+#elif FOLLY_X64
 #define FB_DOBTR(size)                          \
   asm volatile("lock; btr" #size " %0, (%1)"    \
                :                                \