• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 ARK_RUNTIME_GC_HUNG_H
17 #define ARK_RUNTIME_GC_HUNG_H
18 
19 #include <sys/syscall.h>
20 #include <unistd.h>
21 #include <string>
22 #include "libpandabase/utils/time.h"
23 #include "libpandabase/os/library_loader.h"
24 #include "runtime/include/gc_task.h"
25 #include "runtime/include/mtmanaged_thread.h"
26 #include "runtime/include/gc_task.h"
27 
28 namespace panda::mem {
29 
30 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
31 const char LIB_IMONITOR[] = "libimonitor.so";
32 const unsigned int ZRHUNG_WP_GC = 8;
33 const uint64_t INTERVAL_LIMIT_MS_INIT = 50;
34 const uint64_t OVER_TIME_LIMIT_INIT_MS = 2000;
35 const uint64_t WATER_MARK_LIMIT = 20;
36 
37 // zrhung functions type define
38 using ZRHUNG_SEND_EVENT = int (*)(int16_t, const char *, const char *);
39 using ZRHUNG_GET_CONFIG = int (*)(int16_t, char *, uint32_t);
40 
41 enum GcPara {
42     GC_PARA_ENABLE,
43     GC_PARA_INTERVAL,  // ms
44     GC_PARA_WATERMARK,
45     GC_PARA_OVERTIME,  // ms
46     GC_PARA_COUNT
47 };
48 
49 // Functions of the Hung Check Function in the Ark VM,record gc's anomalous behavior
50 class GcHung {
51 public:
52     GcHung();
53     ~GcHung();
54     GcHung(const GcHung &) = delete;
55     GcHung &operator=(GcHung const &) = delete;
56     GcHung(GcHung &&) = delete;
57     GcHung &operator=(GcHung &&) = delete;
58     void SendZerohungEvent(const PandaString &error, int pid, PandaString msg);
IsConfigReady()59     bool IsConfigReady() const
60     {
61         return config_ready_;
62     }
IsEnabled()63     bool IsEnabled() const
64     {
65         return enabled_;
66     }
SetEnabled(bool enabled)67     void SetEnabled(bool enabled)
68     {
69         enabled_ = enabled;
70     }
IsReady()71     bool IsReady() const
72     {
73         return ready_;
74     }
75     static void InitPreFork(bool enabled);
76     static void InitPostFork(bool is_systemserver);
77     static GcHung *Current();
78     static void Start();
79     static void Check(const GCTask &task);
80     // NOLINTNEXTLINE(google-runtime-references)
81     static void Check(const PandaList<MTManagedThread *> &threads, uint64_t start_time);
82     static bool UpdateConfig();
83 
84 private:
85     static GcHung *instance_;
86     pid_t pid_ {-1};
87     bool enabled_ {false};
88     bool ready_ {false};
89     uint64_t interval_limit_ms_ {0};
90     uint64_t over_time_limit_ms_ {0};
91     uint64_t last_gc_time_ns_ {0};
92     uint64_t congestion_duration_ns_ {0};
93     int water_mark_limit_ {0};
94     int water_mark_ {0};
95     int report_count_ {0};
96     bool config_ready_ {false};
97     bool is_systemserver_ {false};
98     uint64_t start_time_ns_ {0};
99     os::library_loader::LibraryHandle libimonitor_dl_handler_ {nullptr};
100     ZRHUNG_SEND_EVENT zrhung_send_event_ {nullptr};
101     ZRHUNG_GET_CONFIG zrhung_get_config_ {nullptr};
102 
103     int GetConfig();
104     int LoadLibimonitor();
105     void ReportGcCongestion();
106     void ReportSuspendTimedout();
107     void InitInternal(bool is_systemserver);
108     void CheckSuspend(const PandaList<MTManagedThread *> &threads, uint64_t start_time);
109     void CheckFrequency();
110     void CheckOvertime(const GCTask &task);
111     void UpdateStartTime();
112 };
113 
114 class ScopedGcHung {
115 public:
ScopedGcHung(const GCTask * task_start)116     explicit ScopedGcHung(const GCTask *task_start)
117     {
118         GcHung::Start();
119         task = task_start;
120     }
121 
~ScopedGcHung()122     ~ScopedGcHung()
123     {
124         GcHung::Check(*task);
125     }
126 
127 private:
128     const GCTask *task;
129 
130     NO_COPY_SEMANTIC(ScopedGcHung);
131     NO_MOVE_SEMANTIC(ScopedGcHung);
132 };
133 
134 }  // namespace panda::mem
135 #endif  // ARK_RUNTIME_GC_HUNG_H