iMSTK
Interactive Medical Simulation Toolkit
imstkAtomicOperations.h
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #pragma once
8 
9 #include <atomic>
10 #include "imstkMath.h"
11 
12 namespace imstk
13 {
14 namespace ParallelUtils
15 {
19 template<class T, class Function>
20 void
21 atomicOp(T& target, const T operand, Function&& f)
22 {
23  std::atomic<T>& tgt = *(static_cast<std::atomic<T>*>(&target));
24 
25  T cur_val = target;
26  T new_val;
27  do
28  {
29  new_val = f(cur_val, operand);
30  }
31  while (!tgt.compare_exchange_weak(cur_val, new_val));
32 }
33 
37 template<class T>
38 void
39 atomicAdd(T& target, const T operand)
40 {
41  atomicOp(target, operand, [](T a, T b) { return a + b; });
42 }
43 
47 template<class T>
48 void
49 atomicSubtract(T& target, const T operand)
50 {
51  atomicOp(target, operand, [](T a, T b) { return a - b; });
52 }
53 
57 template<class T>
58 void
59 atomicMultiply(T& target, const T operand)
60 {
61  atomicOp(target, operand, [](T a, T b) { return a * b; });
62 }
63 
67 template<class T>
68 void
69 atomicDivide(T& target, const T operand)
70 {
71  atomicOp(target, operand, [](T a, T b) { return a / b; });
72 }
73 
77 template<class T, int N>
78 void
79 atomicAdd(Eigen::Matrix<T, N, 1>& target, const Eigen::Matrix<T, N, 1>& operand)
80 {
81  for (int i = 0; i < N; ++i)
82  {
83  atomicAdd(target[i], operand[i]);
84  }
85 }
86 
90 template<class T, int N>
91 void
92 atomicSubtract(Eigen::Matrix<T, N, 1>& target, const Eigen::Matrix<T, N, 1>& operand)
93 {
94  for (int i = 0; i < N; ++i)
95  {
96  atomicSubtract(target[i], operand[i]);
97  }
98 }
99 
103 template<class T, int N>
104 void
105 atomicMultiply(Eigen::Matrix<T, N, 1>& target, const T operand)
106 {
107  for (int i = 0; i < N; ++i)
108  {
109  atomicMultiply(target[i], operand);
110  }
111 }
112 
116 template<class T, int N>
117 void
118 atomicDivide(Eigen::Matrix<T, N, 1>& target, const T operand)
119 {
120  for (int i = 0; i < N; ++i)
121  {
122  atomicDivide(target[i], operand);
123  }
124 }
125 } // end namespace namespace ParallelUtils
126 } // end namespace imstk
Compound Geometry.