java_atomic.hpp (3195B)
1 /* Relacy Race Detector 2 * Copyright (c) 2008-2013, Dmitry S. Vyukov 3 * All rights reserved. 4 * This software is provided AS-IS with no warranty, either express or implied. 5 * This software is distributed under a license and may not be copied, 6 * modified or distributed except as expressly authorized under the 7 * terms of the license contained in the file LICENSE in this distribution. 8 */ 9 10 #ifndef RL_JAVA_ATOMIC_HPP 11 #define RL_JAVA_ATOMIC_HPP 12 #ifdef _MSC_VER 13 # pragma once 14 #endif 15 16 #include "base.hpp" 17 #include "atomic.hpp" 18 19 20 namespace rl 21 { 22 23 24 template<typename T> class jatomic; 25 26 27 template<typename T> 28 class jatomic_proxy 29 { 30 public: 31 T get() const 32 { 33 return var_.load(mo_seq_cst, info_); 34 } 35 36 void set(T value) 37 { 38 var_.store(value, mo_seq_cst, info_); 39 } 40 41 T addAndGet(T delta) 42 { 43 return getAndAdd(delta) + delta; 44 } 45 46 bool compareAndSet(T expect, T update) 47 { 48 bool result = var_.compare_exchange(bool_t<false>(), expect, update, mo_seq_cst, info_); 49 return result; 50 } 51 52 bool weakCompareAndSet(T expect, T update) 53 { 54 bool result = var_.compare_exchange(bool_t<true>(), expect, update, mo_seq_cst, info_); 55 return result; 56 } 57 58 T decrementAndGet() 59 { 60 return getAndAdd(-1) - 1; 61 } 62 63 T getAndAdd(T delta) 64 { 65 T result = var_.rmw(rmw_type_t<rmw_type_add>(), delta, mo_seq_cst, info_); 66 return result; 67 } 68 69 T getAndDecrement() 70 { 71 return getAndAdd(-1); 72 } 73 74 T getAndIncrement() 75 { 76 return getAndAdd(+1); 77 } 78 79 T getAndSet(T newValue) 80 { 81 T result = var_.rmw(rmw_type_t<rmw_type_swap>(), newValue, mo_seq_cst, info_); 82 return result; 83 } 84 85 T incrementAndGet() 86 { 87 return getAndAdd(1) + 1; 88 } 89 90 private: 91 jatomic<T>& var_; 92 debug_info info_; 93 94 //typedef typename atomic_add_type<T>::type add_type; 95 template<typename Y> friend class jatomic; 96 97 jatomic_proxy(jatomic<T>& var, debug_info_param info) 98 : var_(var) 99 , info_(info) 100 { 101 } 102 103 jatomic_proxy& operator = (jatomic_proxy const&); 104 }; 105 106 107 template<typename T> 108 class jatomic : generic_atomic<T, true> 109 { 110 public: 111 typedef jatomic_proxy<T> proxy_t; 112 friend class jatomic_proxy<T>; 113 114 jatomic() 115 { 116 } 117 118 jatomic(T value) 119 { 120 //??? whether here must be mo_relaxed or mo_release? 121 this->store(value, mo_seq_cst, $); 122 } 123 124 jatomic(jatomic const& r) 125 { 126 T const value = r.load(mo_seq_cst, $); 127 //??? whether here must be mo_relaxed or mo_release? 128 this->store(value, mo_seq_cst, $); 129 } 130 131 jatomic(proxy_t const& r) 132 { 133 T const value = r.var_.load(mo_seq_cst, r.info_); 134 //??? whether here must be mo_relaxed or mo_release? 135 this->store(value, mo_seq_cst, r.info_); 136 } 137 138 proxy_t operator () (debug_info_param info) 139 { 140 return proxy_t(*this, info); 141 } 142 }; 143 144 145 typedef jatomic<int> AtomicInteger; 146 typedef jatomic<long> AtomicLong; 147 148 149 150 151 152 153 } 154 155 #endif