1 /* 2 * Copyright (c) 2025 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 COMMON_COMPONENTS_COMMON_SCOPED_SAFEREGION_H 17 #define COMMON_COMPONENTS_COMMON_SCOPED_SAFEREGION_H 18 19 #include "common_components/mutator/mutator.inline.h" 20 21 namespace common { 22 // Scoped guard for saferegion. 23 class ScopedEnterSaferegion { 24 public: 25 ScopedEnterSaferegion() = delete; 26 explicit ScopedEnterSaferegion(bool onlyForMutator = false) 27 { 28 Mutator* mutator = Mutator::GetMutator(); 29 ThreadType threadType = ThreadLocal::GetThreadType(); 30 if (onlyForMutator && 31 (threadType == ThreadType::FP_THREAD || threadType == ThreadType::GC_THREAD)) { 32 stateChanged = false; 33 } else { 34 stateChanged = (mutator != nullptr) ? mutator->EnterSaferegion(true) : false; 35 } 36 } 37 ~ScopedEnterSaferegion()38 ~ScopedEnterSaferegion() 39 { 40 if (LIKELY_CC(stateChanged)) { 41 Mutator* mutator = Mutator::GetMutator(); // state changed, mutator must be not null 42 (void)mutator->LeaveSaferegion(); 43 } 44 } 45 46 private: 47 bool stateChanged; 48 }; 49 50 class ScopedObjectAccess { 51 public: ScopedObjectAccess()52 ScopedObjectAccess() : mutator(*Mutator::GetMutator()), leavedSafeRegion(mutator.LeaveSaferegion()) {} 53 ~ScopedObjectAccess()54 ~ScopedObjectAccess() 55 { 56 if (LIKELY_CC(leavedSafeRegion)) { 57 // qemu use c++ thread local, it has issue with some cases for ZRT annotation, if reload again 58 // fail on O3 and pass on O0 if load mutator again, not figureout why yet 59 (void)mutator.EnterSaferegion(false); 60 } 61 } 62 63 private: 64 Mutator& mutator; 65 bool leavedSafeRegion; 66 }; 67 } // namespace common 68 69 #endif // COMMON_COMPONENTS_COMMON_SCOPED_SAFEREGION_H 70