medfall

A super great game engine
Log | Files | Refs

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