/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ECMASCRIPT_BASE_ATOMIC_HELPER_H #define ECMASCRIPT_BASE_ATOMIC_HELPER_H #include "ecmascript/js_dataview.h" namespace panda::ecmascript::base { enum class BytesSize : uint32_t {ONEBYTES = 1, TWOBYTES = 2, FOURBYTES = 4, EIGHTBYTES = 8}; class AtomicHelper final { public: struct SubFun { template T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const { ASSERT(length >= 1); // 1: max argnum std::atomic *atomicValue = reinterpret_cast *>(ptr); return atomicValue->fetch_sub(arg[0], std::memory_order_seq_cst); } }; struct AddFun { template T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const { ASSERT(length >= 1); // 1: max argnum std::atomic *atomicValue = reinterpret_cast *>(ptr); return atomicValue->fetch_add(arg[0], std::memory_order_seq_cst); } }; struct AndFun { template T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const { ASSERT(length >= 1); // 1: max argnum std::atomic *atomicValue = reinterpret_cast *>(ptr); return atomicValue->fetch_and(arg[0], std::memory_order_seq_cst); } }; struct OrFun { template T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const { ASSERT(length >= 1); // 1: max argnum std::atomic *atomicValue = reinterpret_cast *>(ptr); return atomicValue->fetch_or(arg[0], std::memory_order_seq_cst); } }; struct XorFun { template T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const { ASSERT(length >= 1); // 1: max argnum std::atomic *atomicValue = reinterpret_cast *>(ptr); return atomicValue->fetch_xor(arg[0], std::memory_order_seq_cst); } }; struct CompareExchangeFun { template T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const { ASSERT(length >= 2); // 2: max argnum T a = arg[0]; std::atomic *atomicValue = reinterpret_cast *>(ptr); atomicValue->compare_exchange_strong(a, arg[1], std::memory_order_seq_cst); return a; } }; struct ExchangeFun { template T operator()(T *ptr, const T *arg, [[maybe_unused]] uint32_t length) const { ASSERT(length >= 1); // 1: max argnum std::atomic *atomicValue = reinterpret_cast *>(ptr); return atomicValue->exchange(arg[0], std::memory_order_seq_cst); } }; // 25.4.1.1 ValidateIntegerTypedArray ( typedArray [ , waitable ] ) static JSTaggedValue ValidateIntegerTypedArray(JSThread *thread, JSHandle typedArray, bool waitable = false); // 25.4.2.2 ValidateAtomicAccess ( typedArray, requestIndex ) static uint32_t ValidateAtomicAccess(JSThread *thread, const JSHandle typedArray, JSHandle requestIndex); static JSTaggedValue AtomicStore(JSThread *thread, const JSHandle &typedArray, JSHandle index, JSHandle &value); static JSTaggedValue AtomicLoad(JSThread *thread, const JSHandle &typedArray, JSHandle index); }; } // namespace panda::ecmascript::base #endif // ECMASCRIPT_BASE_ATOMIC_HELPER_H