00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #ifndef AMINO_COUNTER
00022 #define AMINO_COUNTER
00023 
00024 #include <amino/util.h>
00025 #include <amino/cstdatomic>
00026 
00027 namespace amino{
00028     template<typename Num_Type, int copier_num>
00029         class Counter{
00030             typedef atomic<Num_Type> Atomic_Num;
00031             private:
00032                 Atomic_Num counter_array[copier_num];
00033             public:
00034                 Counter(){
00035                     for(int i=0;i<copier_num;i++)
00036                         counter_array[i] = 0;
00037                 }
00038 
00045                 void increment(int rand){
00046                     increment(rand, 1);
00047                 }
00048 
00056                 void increment(int rand, int value){
00061                     rand |= rand>>16;
00062                     rand |= rand>>8;
00063 
00064                     counter_array[rand%copier_num].fetch_add(value, memory_order_relaxed);
00065                 }
00066 
00073                 void decrement(int rand){
00074                     decrement(rand, 1);
00075                 }
00076 
00084                 void decrement(int rand, int value){
00085                     rand |= rand>>16;
00086                     rand |= rand>>8;
00087 
00088                     counter_array[rand%copier_num].fetch_sub(value, memory_order_relaxed);
00089                 }
00090 
00097                 Num_Type load(){
00098                     Num_Type sum;
00099                     sum=0;
00100                     for(int i=0;i<copier_num;i++){
00101                         sum +=
00102                             counter_array[i].load(memory_order_relaxed);
00103                     }
00104 
00105                     return sum;
00106                 }
00107 
00114                 void store(Num_Type value){
00115                     Num_Type tmp = load();
00116                     increment((int) value%copier_num, value - tmp);
00117                 }
00118         };
00119 }
00120 
00121 
00122 #endif