1 /* 2 * Copyright (c) 2022 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 ECMASCRIPT_BASE_ATOMIC_HELPER_H 17 #define ECMASCRIPT_BASE_ATOMIC_HELPER_H 18 19 #include "ecmascript/js_dataview.h" 20 21 namespace panda::ecmascript::base { 22 enum class BytesSize : uint32_t {ONEBYTES = 1, TWOBYTES = 2, FOURBYTES = 4, EIGHTBYTES = 8}; 23 24 class AtomicHelper final { 25 public: 26 struct SubFun { 27 template<typename T> operatorSubFun28 T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const 29 { 30 ASSERT(length >= 1); // 1: max argnum 31 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 32 return atomicValue->fetch_sub(arg[0], std::memory_order_seq_cst); 33 } 34 }; 35 36 struct AddFun { 37 template<typename T> operatorAddFun38 T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const 39 { 40 ASSERT(length >= 1); // 1: max argnum 41 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 42 return atomicValue->fetch_add(arg[0], std::memory_order_seq_cst); 43 } 44 }; 45 46 struct AndFun { 47 template<typename T> operatorAndFun48 T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const 49 { 50 ASSERT(length >= 1); // 1: max argnum 51 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 52 return atomicValue->fetch_and(arg[0], std::memory_order_seq_cst); 53 } 54 }; 55 56 struct OrFun { 57 template<typename T> operatorOrFun58 T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const 59 { 60 ASSERT(length >= 1); // 1: max argnum 61 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 62 return atomicValue->fetch_or(arg[0], std::memory_order_seq_cst); 63 } 64 }; 65 66 struct XorFun { 67 template<typename T> operatorXorFun68 T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const 69 { 70 ASSERT(length >= 1); // 1: max argnum 71 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 72 return atomicValue->fetch_xor(arg[0], std::memory_order_seq_cst); 73 } 74 }; 75 76 struct CompareExchangeFun { 77 template<typename T> operatorCompareExchangeFun78 T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const 79 { 80 ASSERT(length >= 2); // 2: max argnum 81 T a = arg[0]; 82 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 83 atomicValue->compare_exchange_strong(a, arg[1], std::memory_order_seq_cst); 84 return a; 85 } 86 }; 87 88 struct ExchangeFun { 89 template<typename T> operatorExchangeFun90 T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const 91 { 92 ASSERT(length >= 1); // 1: max argnum 93 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 94 return atomicValue->exchange(arg[0], std::memory_order_seq_cst); 95 } 96 }; 97 98 // 25.4.1.1 ValidateIntegerTypedArray ( typedArray [ , waitable ] ) 99 static JSTaggedValue ValidateIntegerTypedArray(JSThread *thread, JSHandle<JSTaggedValue> typedArray, 100 bool waitable = false); 101 // 25.4.2.2 ValidateAtomicAccess ( typedArray, requestIndex ) 102 static uint32_t ValidateAtomicAccess(JSThread *thread, const JSHandle<JSTaggedValue> typedArray, 103 JSHandle<JSTaggedValue> requestIndex); 104 static JSTaggedValue AtomicStore(JSThread *thread, const JSHandle<JSTaggedValue> &typedArray, 105 JSHandle<JSTaggedValue> index, JSHandle<JSTaggedValue> &value); 106 static JSTaggedValue AtomicLoad(JSThread *thread, const JSHandle<JSTaggedValue> &typedArray, 107 JSHandle<JSTaggedValue> index); 108 }; 109 } // namespace panda::ecmascript::base 110 111 #endif // ECMASCRIPT_BASE_ATOMIC_HELPER_H 112