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