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_INTERFACES_THREAD_THREAD_STATE_TRANSITION_H 17 #define COMMON_INTERFACES_THREAD_THREAD_STATE_TRANSITION_H 18 19 #include "thread/thread_holder-inl.h" 20 #include "thread/thread_holder_manager.h" 21 #include "base_runtime.h" 22 23 namespace common { 24 25 // Fixme: T is a temporary mock impl to adapt the current JSThread callback when transfer to RUNNING, 26 // actually it should always be ThreadHolder, and need to be removed later. 27 template <typename T, ThreadState newState> 28 class ThreadStateTransitionScope final { 29 static_assert(std::is_base_of_v<ThreadHolder, T>); 30 31 public: ThreadStateTransitionScope(T * self)32 explicit ThreadStateTransitionScope(T *self) : self_(self) 33 { 34 DCHECK_CC(self_ != nullptr); 35 if constexpr (newState == ThreadState::RUNNING) { 36 hasSwitchState_ = self_->TransferToRunningIfInNative(); 37 } else { 38 hasSwitchState_ = self_->TransferToNativeIfInRunning(); 39 } 40 } 41 ~ThreadStateTransitionScope()42 ~ThreadStateTransitionScope() 43 { 44 if (hasSwitchState_) { 45 if constexpr (newState == ThreadState::RUNNING) { 46 self_->TransferToNative(); 47 } else { 48 self_->TransferToRunning(); 49 } 50 } 51 } 52 53 private: 54 T *self_; 55 ThreadState oldState_; 56 bool hasSwitchState_ {false}; 57 NO_COPY_SEMANTIC_CC(ThreadStateTransitionScope); 58 }; 59 60 class ThreadSuspensionScope final { 61 public: ThreadSuspensionScope(ThreadHolder * self)62 explicit ThreadSuspensionScope(ThreadHolder *self) : scope_(self) 63 { 64 DCHECK_CC(!self->IsInRunningState()); 65 } 66 67 ~ThreadSuspensionScope() = default; 68 69 private: 70 ThreadStateTransitionScope<ThreadHolder, ThreadState::IS_SUSPENDED> scope_; 71 NO_COPY_SEMANTIC_CC(ThreadSuspensionScope); 72 }; 73 74 class ThreadNativeScope final { 75 public: ThreadNativeScope(ThreadHolder * self)76 explicit ThreadNativeScope(ThreadHolder *self) : scope_(self) 77 { 78 DCHECK_CC(!self->IsInRunningState()); 79 } 80 81 ~ThreadNativeScope() = default; 82 83 private: 84 ThreadStateTransitionScope<ThreadHolder, ThreadState::NATIVE> scope_; 85 NO_COPY_SEMANTIC_CC(ThreadNativeScope); 86 }; 87 88 // Fixme: T is a temporary mock impl to adapt the current JSThread callback when transfer to RUNNING, 89 // actually it should always be ThreadHolder, and need to be removed later. 90 template <typename T> 91 class ThreadManagedScope final { 92 static_assert(std::is_base_of_v<ThreadHolder, T>); 93 94 public: ThreadManagedScope(T * self)95 explicit ThreadManagedScope(T *self) : scope_(self) {} 96 97 ~ThreadManagedScope() = default; 98 99 private: 100 ThreadStateTransitionScope<T, ThreadState::RUNNING> scope_; 101 NO_COPY_SEMANTIC_CC(ThreadManagedScope); 102 }; 103 104 // Fixme: T is a temporary mock impl to adapt the current JSThread callback when transfer to RUNNING, 105 // actually it should always be ThreadHolder, and need to be removed later. 106 template <typename T> 107 class SuspendAllScope final { 108 static_assert(std::is_base_of_v<ThreadHolder, T>); 109 110 public: SuspendAllScope(T * self)111 explicit SuspendAllScope(T *self) : self_(self), scope_(self) 112 { 113 #if defined(TODO_MACRO) 114 TRACE_GC(GCStats::Scope::ScopeId::SuspendAll, SharedHeap::GetInstance()->GetEcmaGCStats()); 115 ECMA_BYTRACE_NAME(HITRACE_LEVEL_COMMERCIAL, HITRACE_TAG_ARK, "SuspendAll", ""); 116 #endif 117 BaseRuntime::GetInstance()->GetThreadHolderManager().SuspendAll(self_); 118 } 119 ~SuspendAllScope()120 ~SuspendAllScope() 121 { 122 #if defined(TODO_MACRO) 123 TRACE_GC(GCStats::Scope::ScopeId::ResumeAll, SharedHeap::GetInstance()->GetEcmaGCStats()); 124 ECMA_BYTRACE_NAME(HITRACE_LEVEL_COMMERCIAL, HITRACE_TAG_ARK, "ResumeAll", ""); 125 #endif 126 BaseRuntime::GetInstance()->GetThreadHolderManager().ResumeAll(self_); 127 } 128 129 private: 130 T *self_; 131 ThreadStateTransitionScope<T, ThreadState::IS_SUSPENDED> scope_; 132 NO_COPY_SEMANTIC_CC(SuspendAllScope); 133 }; 134 } // namespace common 135 #endif // COMMON_INTERFACES_THREAD_THREAD_STATE_TRANSITION_H 136