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