1 /** 2 * Copyright (c) 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_RUNTIME_COROUTINES_LOCAL_STORAGE_H 17 #define PANDA_RUNTIME_COROUTINES_LOCAL_STORAGE_H 18 19 #include <cstddef> 20 #include <cstdint> 21 #include <array> 22 #include <functional> 23 #include "libpandabase/macros.h" 24 #include "runtime/coroutines/utils.h" 25 26 namespace ark { 27 28 template <class IndexType> 29 class StaticLocalStorage { 30 public: 31 static constexpr size_t NUM_ENTRIES = static_cast<size_t>(IndexType::LAST_ID); 32 using Finalizer = std::function<void(void *)>; 33 struct Entry { 34 union { 35 void *ptr = nullptr; 36 uintptr_t uint; 37 } data; 38 Finalizer finalizer = nullptr; 39 }; 40 41 NO_MOVE_SEMANTIC(StaticLocalStorage); 42 NO_COPY_SEMANTIC(StaticLocalStorage); 43 44 StaticLocalStorage() = default; 45 ~StaticLocalStorage()46 ~StaticLocalStorage() 47 { 48 for (auto &entry : entries_) { 49 if (entry.finalizer != nullptr) { 50 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access) 51 entry.finalizer(entry.data.ptr); 52 } 53 } 54 } 55 56 template <IndexType IDX> 57 void Set(void *pointer, const Finalizer &finalizer = nullptr) 58 { 59 static_assert((ToIndex(IDX) < NUM_ENTRIES), "idx should be correct"); 60 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access) 61 entries_[ToIndex(IDX)].data.ptr = pointer; 62 entries_[ToIndex(IDX)].finalizer = finalizer; 63 } 64 65 template <IndexType IDX> Set(uintptr_t data)66 void Set(uintptr_t data) 67 { 68 static_assert((ToIndex(IDX) < NUM_ENTRIES), "idx should be correct"); 69 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access) 70 entries_[ToIndex(IDX)].data.uint = data; 71 entries_[ToIndex(IDX)].finalizer = nullptr; 72 } 73 74 template <IndexType IDX, class T> Get()75 T Get() 76 { 77 static_assert((ToIndex(IDX) < NUM_ENTRIES), "idx should be correct"); 78 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access) 79 return reinterpret_cast<T>(entries_[ToIndex(IDX)].data.ptr); 80 } 81 82 private: 83 std::array<Entry, NUM_ENTRIES> entries_; 84 }; 85 86 } // namespace ark 87 88 #endif /* PANDA_RUNTIME_COROUTINES_LOCAL_STORAGE_H */ 89