cli_var.hpp (2823B)
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_CLI_VAR_HPP 11 #define RL_CLI_VAR_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 nvar; 24 25 26 template<typename T> 27 class nvar_proxy 28 { 29 public: 30 typedef typename atomic_add_type<T>::type add_type; 31 template<typename Y> friend class nvar; 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 = (nvar_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 nvar<T>& var_; 95 debug_info info_; 96 97 nvar_proxy(nvar<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_relaxed, info_); 106 } 107 108 void store(T value) 109 { 110 var_.store(value, mo_relaxed, info_); 111 } 112 }; 113 114 115 116 117 template<typename T> 118 class nvar : public generic_atomic<T, true> 119 { 120 public: 121 typedef nvar_proxy<T> proxy_t; 122 friend class nvar_proxy<T>; 123 124 nvar() 125 { 126 } 127 128 explicit nvar(T value) 129 { 130 this->store(value, mo_relaxed, $); 131 } 132 133 nvar(nvar const& r) 134 { 135 T const value = r.load(mo_relaxed, $); 136 this->store(value, mo_relaxed, $); 137 } 138 139 nvar(proxy_t const& r) 140 { 141 T const value = r.load(); 142 this->store(value, mo_relaxed, r.info_); 143 } 144 145 proxy_t operator () (debug_info_param info) 146 { 147 return proxy_t(*this, info); 148 } 149 150 private: 151 nvar& operator = (nvar const&); 152 }; 153 154 155 156 } 157 158 #endif