1/*
2 * Copyright (c) 2021 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#include "ecmascript/dfx/vm_thread_control.h"
17
18namespace panda::ecmascript {
19constexpr int32_t TIME_OUT_MS = 1500;
20
21bool VmThreadControl::NotifyVMThreadSuspension() // block caller thread
22{
23    if (VMNeedSuspension()) { // only enable one thread to post suspension
24        return false;
25    }
26    SetVMNeedSuspension(true);
27    thread_->SetCheckSafePointStatus();
28    LockHolder lock(vmThreadSuspensionMutex_);
29    while (!IsSuspended()) {
30        if (vmThreadNeedSuspensionCV_.TimedWait(&vmThreadSuspensionMutex_, TIME_OUT_MS)) {
31            SetVMNeedSuspension(false);
32            thread_->ResetCheckSafePointStatus();
33            return false;
34        }
35    }
36    return true;
37}
38
39void VmThreadControl::RequestTerminateExecution()
40{
41    SetTerminationRequest(true);
42    thread_->SetCheckSafePointStatus();
43}
44
45void VmThreadControl::SetVMNeedSuspension(bool flag)
46{
47    thread_->SetVMNeedSuspension(flag);
48}
49
50bool VmThreadControl::VMNeedSuspension() const
51{
52    return thread_->VMNeedSuspension();
53}
54
55void VmThreadControl::SetTerminationRequest(bool flag)
56{
57    thread_->SetTerminationRequest(flag);
58}
59
60void VmThreadControl::SetVMSuspended(bool flag)
61{
62    thread_->SetVMSuspended(flag);
63}
64
65bool VmThreadControl::IsSuspended() const
66{
67    return thread_->IsVMSuspended();
68}
69
70void VmThreadControl::SuspendVM() // block vm thread
71{
72    LockHolder lock(vmThreadSuspensionMutex_);
73    SetVMSuspended(true);
74    vmThreadNeedSuspensionCV_.Signal(); // wake up the thread who needs suspend vmthread
75    while (VMNeedSuspension()) {
76        vmThreadHasSuspendedCV_.Wait(&vmThreadSuspensionMutex_);
77    }
78    SetVMSuspended(false);
79}
80
81void VmThreadControl::ResumeVM()
82{
83    LockHolder lock(vmThreadSuspensionMutex_);
84    SetVMNeedSuspension(false);
85    vmThreadHasSuspendedCV_.Signal();
86}
87}  // namespace panda::ecmascript