medfall

A super great game engine
Log | Files | Refs

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