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