• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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