1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef COMMON_INTERFACES_OBJECTS_FIELD_H 17 #define COMMON_INTERFACES_OBJECTS_FIELD_H 18 19 #include <atomic> 20 21 namespace common { 22 class BaseObject; 23 24 using MemoryOrder = std::memory_order; 25 // T is primitive field 26 template <typename T, bool isAtomic = false> 27 class Field { 28 public: 29 // the interfaces fellow are only used in atomic operation. 30 bool CompareExchange(T expectedValue, T newValue, std::memory_order succOrder = std::memory_order_relaxed, 31 MemoryOrder failOrder = std::memory_order_relaxed) 32 { 33 static_assert(isAtomic, "this interface must be used in atomic operation"); 34 // compiling failure: 35 // std::atomic_compare_exchange_strong_explicit(&value, &expectedValue, newValue, order, order) 36 return __atomic_compare_exchange(&value, &expectedValue, &newValue, false, succOrder, failOrder); 37 } 38 39 T Exchange(T newValue, std::memory_order order = std::memory_order_relaxed) 40 { 41 static_assert(isAtomic, "this interface must be used in atomic operation"); 42 T ret; 43 __atomic_exchange(&value, &newValue, &ret, order); 44 return ret; 45 } 46 47 T FetchAdd(T val, std::memory_order order = std::memory_order_relaxed) 48 { 49 static_assert(isAtomic, "this interface must be used in atomic operation"); 50 return __atomic_fetch_add(&value, val, order); 51 } 52 53 T FetchSub(T val, std::memory_order order = std::memory_order_relaxed) 54 { 55 static_assert(isAtomic, "this interface must be used in atomic operation"); 56 return __atomic_fetch_sub(&value, val, order); 57 } 58 59 T FetchAnd(T val, std::memory_order order = std::memory_order_relaxed) 60 { 61 static_assert(isAtomic, "this interface must be used in atomic operation"); 62 return __atomic_fetch_and(&value, val, order); 63 } 64 65 T FetchOr(T val, std::memory_order order = std::memory_order_relaxed) 66 { 67 static_assert(isAtomic, "this interface must be used in atomic operation"); 68 return __atomic_fetch_or(&value, val, order); 69 } 70 71 T FetchXor(T val, std::memory_order order = std::memory_order_relaxed) 72 { 73 static_assert(isAtomic, "this interface must be used in atomic operation"); 74 return __atomic_fetch_xor(&value, val, order); 75 } 76 77 private: 78 T value; 79 }; 80 } // namespace common 81 #endif // COMMON_INTERFACES_OBJECTS_REF_FIELD_H 82