Add atomic multiply and divide operations, built on top of CompareAndSwap.
authorOwen Anderson <resistor@mac.com>
Tue, 23 Jun 2009 21:19:04 +0000 (21:19 +0000)
committerOwen Anderson <resistor@mac.com>
Tue, 23 Jun 2009 21:19:04 +0000 (21:19 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74004 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/System/Atomic.h
lib/System/Atomic.cpp

index c4049d40da797bbd3f47d5efa0bd799e027933e1..4ec117be2926f0b594ad3e056b6d959fc31bc5f8 100644 (file)
@@ -27,6 +27,8 @@ namespace llvm {
     cas_flag AtomicIncrement(volatile cas_flag* ptr);
     cas_flag AtomicDecrement(volatile cas_flag* ptr);
     cas_flag AtomicAdd(volatile cas_flag* ptr, cas_flag val);
+    cas_flag AtomicMul(volatile cas_flag* ptr, cas_flag val);
+    cas_flag AtomicDiv(volatile cas_flag* ptr, cas_flag val);
   }
 }
 
index 6e751a30d4d291dc3f0252711f8a54f6bc2ffadc..f9b55a186d1829fa0e6498d1e0e70aba46bed995 100644 (file)
@@ -91,4 +91,22 @@ sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) {
 #endif
 }
 
+sys::cas_flag sys::AtomicMul(volatile sys::cas_flag* ptr, sys::cas_flag val) {
+  sys::cas_flag original, result;
+  do {
+    original = *ptr;
+    result = original * val;
+  } while (sys::CompareAndSwap(ptr, result, original) != original);
 
+  return result;
+}
+
+sys::cas_flag sys::AtomicDiv(volatile sys::cas_flag* ptr, sys::cas_flag val) {
+  sys::cas_flag original, result;
+  do {
+    original = *ptr;
+    result = original / val;
+  } while (sys::CompareAndSwap(ptr, result, original) != original);
+
+  return result;
+}