java_volatile.hpp (3064B)
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_VOLATILE_HPP 11 #define RL_JAVA_VOLATILE_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 template<typename T> class jvolatile; 24 25 26 template<typename T> 27 class jvolatile_proxy 28 { 29 public: 30 typedef typename atomic_add_type<T>::type add_type; 31 template<typename Y> friend class jvolatile; 32 33 operator T () const 34 { 35 return load(); 36 } 37 38 T operator = (T value) 39 { 40 store(value); 41 return value; 42 } 43 44 T operator = (jvolatile_proxy const& r) 45 { 46 T const value = r.load(); 47 store(value); 48 return *this; 49 } 50 51 T operator ++ (int) 52 { 53 T tmp = load(); 54 store(tmp + 1); 55 return tmp; 56 } 57 58 T operator -- (int) 59 { 60 T tmp = load(); 61 store(tmp - 1); 62 return tmp; 63 } 64 65 T operator ++ () 66 { 67 T tmp = load(); 68 store(tmp + 1); 69 return tmp + 1; 70 } 71 72 T operator -- () 73 { 74 T tmp = load(); 75 store(tmp - 1); 76 return tmp - 1; 77 } 78 79 T operator += (add_type value) 80 { 81 T tmp = load(); 82 store(tmp + value); 83 return tmp + value; 84 } 85 86 T operator -= (add_type value) 87 { 88 T tmp = load(); 89 store(tmp - value); 90 return tmp - value; 91 } 92 93 private: 94 jvolatile<T>& var_; 95 debug_info info_; 96 97 jvolatile_proxy(jvolatile<T>& var, debug_info_param info) 98 : var_(var) 99 , info_(info) 100 { 101 } 102 103 T load() const 104 { 105 return var_.load(mo_seq_cst, info_); 106 } 107 108 void store(T value) 109 { 110 var_.store(value, mo_seq_cst, info_); 111 } 112 }; 113 114 115 116 117 template<typename T> 118 class jvolatile : generic_atomic<T, true> 119 { 120 public: 121 typedef jvolatile_proxy<T> proxy_t; 122 friend class jvolatile_proxy<T>; 123 124 jvolatile() 125 { 126 } 127 128 explicit jvolatile(T value) 129 { 130 //??? whether here must be mo_relaxed or mo_release? 131 this->store(value, mo_seq_cst, $); 132 } 133 134 jvolatile(jvolatile const& r) 135 { 136 T const value = r.load(mo_seq_cst, $); 137 //??? whether here must be mo_relaxed or mo_release? 138 this->store(value, mo_seq_cst, $); 139 } 140 141 jvolatile(proxy_t const& r) 142 { 143 T const value = r.var_.load(mo_seq_cst, r.info_); 144 //??? whether here must be mo_relaxed or mo_release? 145 this->store(value, mo_seq_cst, r.info_); 146 } 147 148 proxy_t operator () (debug_info_param info) 149 { 150 return proxy_t(*this, info); 151 } 152 }; 153 154 155 156 } 157 158 #endif