@@ -398,11 +398,15 @@ class Atomic : AllStatic {
398398                                T compare_value,
399399                                T exchange_value);
400400
401-   //  Support platforms that do not provide Read-Modify-Write
402-   //  byte-level atomic access . To use, derive PlatformCmpxchg<1> from 
403-   //  this class .
401+   //  Support platforms that do not provide Read-Modify-Write atomic 
402+   //  accesses for 1-byte and 8-byte widths . To use, derive PlatformCmpxchg<1>, 
403+   //  PlatformAdd<S>, PlatformXchg<S> from these classes .
404404public:  //  Temporary, can't be private: C++03 11.4/2. Fixed by C++11.
405405  struct  CmpxchgByteUsingInt ;
406+   template <size_t  byte_size>
407+   struct  XchgUsingCmpxchg ;
408+   template <size_t  byte_size>
409+   class  AddUsingCmpxchg ;
406410private: 
407411
408412  //  Dispatch handler for xchg.  Provides type-based validity
@@ -677,6 +681,47 @@ struct Atomic::CmpxchgByteUsingInt {
677681               atomic_memory_order order) const ;
678682};
679683
684+ //  Define the class before including platform file, which may use this
685+ //  as a base class, requiring it be complete.  The definition is later
686+ //  in this file, near the other definitions related to xchg.
687+ template <size_t  byte_size>
688+ struct  Atomic ::XchgUsingCmpxchg {
689+   template <typename  T>
690+   T operator ()(T volatile * dest,
691+                T exchange_value,
692+                atomic_memory_order order) const ;
693+ };
694+ 
695+ //  Define the class before including platform file, which may use this
696+ //  as a base class, requiring it be complete.
697+ template <size_t  byte_size>
698+ class  Atomic ::AddUsingCmpxchg {
699+ public: 
700+   template <typename  D, typename  I>
701+   static  inline  D add_then_fetch (D volatile * dest,
702+                                  I add_value,
703+                                  atomic_memory_order order) {
704+     D addend = add_value;
705+     return  fetch_then_add (dest, add_value, order) + add_value;
706+   }
707+ 
708+   template <typename  D, typename  I>
709+   static  inline  D fetch_then_add (D volatile * dest,
710+                           I add_value,
711+                           atomic_memory_order order) {
712+     STATIC_ASSERT (byte_size == sizeof (I));
713+     STATIC_ASSERT (byte_size == sizeof (D));
714+ 
715+     D old_value;
716+     D new_value;
717+     do  {
718+       old_value = Atomic::load (dest);
719+       new_value = old_value + add_value;
720+     } while  (old_value != Atomic::cmpxchg (dest, old_value, new_value, order));
721+     return  old_value;
722+   }
723+ };
724+ 
680725//  Define the class before including platform file, which may specialize
681726//  the operator definition.  No generic definition of specializations
682727//  of the operator template are provided, nor are there any generic
@@ -1170,4 +1215,18 @@ inline D Atomic::xchg(volatile D* dest, T exchange_value, atomic_memory_order or
11701215  return  XchgImpl<D, T>()(dest, exchange_value, order);
11711216}
11721217
1218+ template <size_t  byte_size>
1219+ template <typename  T>
1220+ inline  T Atomic::XchgUsingCmpxchg<byte_size>::operator ()(T volatile * dest,
1221+                                              T exchange_value,
1222+                                              atomic_memory_order order) const  {
1223+   STATIC_ASSERT (byte_size == sizeof (T));
1224+ 
1225+   T old_value;
1226+   do  {
1227+     old_value = Atomic::load (dest);
1228+   } while  (old_value != Atomic::cmpxchg (dest, old_value, exchange_value, order));
1229+   return  old_value;
1230+ }
1231+ 
11731232#endif //  SHARE_RUNTIME_ATOMIC_HPP
0 commit comments