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) const 29 { 30 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 31 return atomicValue->fetch_sub(arg[0], std::memory_order_seq_cst); 32 } 33 }; 34 35 struct AddFun { 36 template<typename T> operatorAddFun37 T operator()(T *ptr, const T *arg) const 38 { 39 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 40 return atomicValue->fetch_add(arg[0], std::memory_order_seq_cst); 41 } 42 }; 43 44 struct AndFun { 45 template<typename T> operatorAndFun46 T operator()(T *ptr, const T *arg) const 47 { 48 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 49 return atomicValue->fetch_and(arg[0], std::memory_order_seq_cst); 50 } 51 }; 52 53 struct OrFun { 54 template<typename T> operatorOrFun55 T operator()(T *ptr, const T *arg) const 56 { 57 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 58 return atomicValue->fetch_or(arg[0], std::memory_order_seq_cst); 59 } 60 }; 61 62 struct XorFun { 63 template<typename T> operatorXorFun64 T operator()(T *ptr, const T *arg) const 65 { 66 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 67 return atomicValue->fetch_xor(arg[0], std::memory_order_seq_cst); 68 } 69 }; 70 71 struct CompareExchangeFun { 72 template<typename T> operatorCompareExchangeFun73 T operator()(T *ptr, const T *arg) const 74 { 75 T a = arg[0]; 76 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 77 atomicValue->compare_exchange_strong(a, arg[1], std::memory_order_seq_cst); 78 return a; 79 } 80 }; 81 82 struct ExchangeFun { 83 template<typename T> operatorExchangeFun84 T operator()(T *ptr, const T *arg) const 85 { 86 std::atomic<T> *atomicValue = reinterpret_cast<std::atomic<T> *>(ptr); 87 return atomicValue->exchange(arg[0], std::memory_order_seq_cst); 88 } 89 }; 90 91 // 25.4.1.1 ValidateIntegerTypedArray ( typedArray [ , waitable ] ) 92 static JSTaggedValue ValidateIntegerTypedArray(JSThread *thread, JSHandle<JSTaggedValue> typedArray, 93 bool waitable = false); 94 // 25.4.2.2 ValidateAtomicAccess ( typedArray, requestIndex ) 95 static uint32_t ValidateAtomicAccess(JSThread *thread, const JSHandle<JSTaggedValue> typedArray, 96 JSHandle<JSTaggedValue> requestIndex); 97 static JSTaggedValue AtomicStore(JSThread *thread, const JSHandle<JSTaggedValue> &typedArray, 98 JSHandle<JSTaggedValue> index, JSHandle<JSTaggedValue> &value); 99 static JSTaggedValue AtomicLoad(JSThread *thread, const JSHandle<JSTaggedValue> &typedArray, 100 JSHandle<JSTaggedValue> index); 101 }; 102 } // namespace panda::ecmascript::base 103 104 #endif // ECMASCRIPT_BASE_ATOMIC_HELPER_H 105