1 /** 2 * Copyright (c) 2021-2024 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 PANDA_PLUGINS_ETS_RUNTIME_FFI_CLASSES_ETS_SHAREDMEM_H 17 #define PANDA_PLUGINS_ETS_RUNTIME_FFI_CLASSES_ETS_SHAREDMEM_H 18 19 #include <atomic> 20 #include <cstdint> 21 #include <optional> 22 #include "include/mem/panda_containers.h" 23 #include "libpandabase/macros.h" 24 #include "libpandabase/mem/space.h" 25 #include "libpandabase/os/mutex.h" 26 #include "libpandabase/mem/object_pointer.h" 27 #include "plugins/ets/runtime/types/ets_class.h" 28 #include "plugins/ets/runtime/types/ets_primitives.h" 29 #include "plugins/ets/runtime/types/ets_object.h" 30 #include "plugins/ets/runtime/ets_class_root.h" 31 #include "plugins/ets/runtime/ets_vm.h" 32 #include "plugins/ets/runtime/types/ets_array.h" 33 34 namespace ark::ets { 35 36 class EtsSharedMemory : public ObjectHeader { 37 public: 38 EtsSharedMemory() = delete; 39 ~EtsSharedMemory() = delete; 40 41 NO_COPY_SEMANTIC(EtsSharedMemory); 42 NO_MOVE_SEMANTIC(EtsSharedMemory); 43 44 class Waiter; 45 AsObject()46 EtsObject *AsObject() 47 { 48 return EtsObject::FromCoreType(this); 49 } 50 AsObject()51 const EtsObject *AsObject() const 52 { 53 return EtsObject::FromCoreType(this); 54 } 55 FromEtsObject(EtsObject * sharedMem)56 static EtsSharedMemory *FromEtsObject(EtsObject *sharedMem) 57 { 58 return reinterpret_cast<EtsSharedMemory *>(sharedMem); 59 } 60 61 static EtsSharedMemory *Create(size_t length); 62 63 void Initialize(size_t length); 64 65 size_t GetLength(); 66 GetHeadWaiter()67 Waiter *GetHeadWaiter() 68 { 69 return reinterpret_cast<Waiter *>(waiter_); 70 } 71 SetHeadWaiter(Waiter * waiter)72 void SetHeadWaiter(Waiter *waiter) 73 { 74 waiter_ = reinterpret_cast<EtsLong>(waiter); 75 } 76 77 void LinkWaiter(Waiter &waiter); 78 void UnlinkWaiter(Waiter &waiter); 79 80 template <typename T> 81 T GetElement(uint32_t index); 82 template <typename T> 83 void SetElement(uint32_t index, T element); 84 85 template <typename T, typename F> 86 std::pair<T, T> ReadModifyWrite(int32_t index, const F &f); 87 88 enum class WaitResult { OK = 0, NOT_EQUAL = 1, TIMED_OUT = 2 }; 89 90 WaitResult WaitI32(uint32_t offset, int32_t expectedValue, std::optional<uint64_t> timeout); 91 92 WaitResult WaitI64(uint32_t offset, int64_t expectedValue, std::optional<uint64_t> timeout); 93 94 int32_t NotifyI32(uint32_t offset, std::optional<uint32_t> count); 95 96 class Waiter { 97 public: Waiter(uint32_t offset)98 explicit Waiter(uint32_t offset) : offset_(offset) {} 99 100 bool Wait(std::optional<uint64_t> timeout); 101 102 void SignalAll(); 103 IsNotified()104 bool IsNotified() 105 { 106 // Atomic with seq_cst order reason: strong synchronization 107 return notified_.load(std::memory_order_seq_cst); 108 } 109 SetNotified()110 void SetNotified() 111 { 112 // Atomic with seq_cst order reason: strong synchronization 113 notified_.store(true, std::memory_order_seq_cst); 114 } 115 GetOffset()116 uint32_t GetOffset() 117 { 118 return offset_; 119 } 120 GetNext()121 Waiter *GetNext() 122 { 123 return next_; 124 } 125 SetNext(Waiter * next)126 void SetNext(Waiter *next) 127 { 128 next_ = next; 129 } 130 GetPrev()131 Waiter *GetPrev() 132 { 133 return prev_; 134 } 135 SetPrev(Waiter * prev)136 void SetPrev(Waiter *prev) 137 { 138 prev_ = prev; 139 } 140 141 private: 142 os::memory::ConditionVariable cv_ {os::memory::ConditionVariable()}; 143 std::atomic<bool> notified_ {std::atomic<bool>(false)}; 144 uint32_t offset_; 145 146 Waiter *prev_ {nullptr}; 147 Waiter *next_ {nullptr}; 148 }; 149 150 private: 151 ObjectPointer<EtsByteArray> array_; 152 EtsLong waiter_; 153 }; 154 155 } // namespace ark::ets 156 157 #endif // PANDA_PLUGINS_ETS_RUNTIME_FFI_CLASSES_ETS_SHAREDMEM_H 158