diff --git a/services/ui/driver/graphic_engine.cpp b/services/ui/driver/graphic_engine.cpp index 58fa48b52b77ac9ee8ed7f0588018ee7e31a3a0a..35aeb24bd935f1cbbe67e52a11b78157e51144b3 100644 --- a/services/ui/driver/graphic_engine.cpp +++ b/services/ui/driver/graphic_engine.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "graphic_engine.h" +#include #include "common/graphic_startup.h" #include "common/image_decode_ability.h" #include "common/task_manager.h" @@ -91,10 +92,17 @@ void GraphicEngine::InitImageDecodeAbility() const void GraphicEngine::InitFlushThread() { flushStop_ = false; + monitorStop_ = false; + curTick_ = Utils::GetCurrentTickMs(); flushLoop_ = std::thread([this] { + flushTid_ = gettid(); this->FlushThreadLoop(); }); + monitorThread_ = std::thread([this] { + this->MonitorThreadLoop(); + }); flushLoop_.detach(); + monitorThread_.detach(); LOG(INFO) << "init flush thread"; } @@ -102,11 +110,16 @@ __attribute__((weak)) void InitFlushBatteryStatusExt(void) { } +__attribute__((weak)) void UiFreezeCallback(pid_t pid) +{ +} + void GraphicEngine::FlushThreadLoop() const { while (!flushStop_) { OHOS::TaskManager::GetInstance()->TaskHandler(); InitFlushBatteryStatusExt(); + curTick_ = Utils::GetCurrentTickMs(); Utils::UsSleep(sleepTime_); } // clear screen after stop @@ -116,6 +129,22 @@ void GraphicEngine::FlushThreadLoop() const sfDev_->Flip(reinterpret_cast(buffInfo_->virAddr)); } +void GraphicEngine::MonitorThreadLoop() const +{ + static int64_t lastFreezedTick = 0; + while (!monitorStop_ && !flushStop_) { + if (std::abs(Utils::GetCurrentTickMs() - currentTick_) > MONITOR_THRESHOLD_TICK && + lastFreezedTick != curTick_) { + LOG(INFO) << "ui thread freezed"; + UiFreezeCallback(flushTid_); + lastFreezedTick = curTick_; + Utils::UsSleep(MONITOR_PRERIOD_TIME); + continue; + } + Utils::UsSleep(MONITOR_PRERIOD_TIME); + } +} + void GraphicEngine::StopEngine(void) { flushStop_ = true; diff --git a/services/ui/driver/graphic_engine.h b/services/ui/driver/graphic_engine.h index 523425d7209d3f4469bcafa22026536576649791..47f1f413eec6aa6f2e62af35fd0c2e948e90e04d 100644 --- a/services/ui/driver/graphic_engine.h +++ b/services/ui/driver/graphic_engine.h @@ -28,6 +28,8 @@ class GraphicEngine : public OHOS::SoftEngine { DISALLOW_COPY_MOVE(GraphicEngine); public: static constexpr uint32_t THREAD_USLEEP_TIME = 10000; + static constexpr uint32_t MONITOR_PRERIOD_TIME = 1000000; + static constexpr uint32_t MONITOR_THRESHOLD_TICK = 10000; GraphicEngine() = default; virtual ~GraphicEngine() = default; static GraphicEngine &GetInstance(); @@ -40,18 +42,23 @@ public: void SetSleepTime(uint32_t sleepTime); private: void FlushThreadLoop() const; + void MonitorThreadLoop() const; void InitFontEngine(const char *fontPath) const; void InitImageDecodeAbility() const; void InitFlushThread(); std::thread flushLoop_; + std::thread monitorThread_; std::unique_ptr buffInfo_ = nullptr; std::unique_ptr virAddr_ = nullptr; std::unique_ptr sfDev_ = nullptr; uint32_t bkgColor_ = 0; uint16_t height_ = 0; uint16_t width_ = 0; + int64_t curTick_ = -1; uint8_t colorMode_ = 0; bool flushStop_ = true; + bool monitorStop_ = true; + pid_t flushTid_ = -1; uint32_t sleepTime_ = THREAD_USLEEP_TIME; std::mutex mtx_ {}; }; @@ -63,6 +70,7 @@ extern "C" { #endif /* __cplusplus */ void InitFlushBatteryStatusExt(void); void PostInitSurfDev(std::unique_ptr &surfDev, GrSurface &surface); +void UiFreezeCallback(pid_t pid); #ifdef __cplusplus #if __cplusplus } diff --git a/utils/include/utils.h b/utils/include/utils.h index 928277294d5c8dd37dfac0d5b61cdb93ef6c5edb..a6197621810fdb48d7636ba2d36738deff7c3392 100644 --- a/utils/include/utils.h +++ b/utils/include/utils.h @@ -18,6 +18,7 @@ #include "utils_fs.h" #include "utils_common.h" #include +#include #include #include #include @@ -60,6 +61,7 @@ T String2Int(const std::string &str, int base = N_HEX) } return result; } +int64_t GetCurrentTickMs(void); int32_t DeleteFile(const std::string& filename); std::vector SplitString(const std::string &str, const std::string del = " \t"); std::string Trim(const std::string &str); diff --git a/utils/utils.cpp b/utils/utils.cpp index eb953fcf37430d5a4948f402ba77b15c24001f0e..c8a36e114f11462c267f8f8b6ccdb18f6b1ef268 100644 --- a/utils/utils.cpp +++ b/utils/utils.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,8 @@ constexpr int MAX_TIME_SIZE = 20; constexpr size_t PARAM_SIZE = 32; constexpr const char *PREFIX_PARTITION_NODE = "/dev/block/by-name/"; constexpr mode_t DEFAULT_DIR_MODE = 0775; +constexpr int64_t SEC_TO_NANOSEC = 1000000000; +constexpr int64_t SEC_TO_MICROSEC = 1000000; namespace { void UpdateInfoInMisc(const std::string headInfo, const std::optional message, bool isRemove) @@ -127,7 +130,16 @@ void SaveLogs() } } -int32_t DeleteFile(const std::string& filename) +int64_t GetCurrentTickMs(void) +{ + struct timespec t; + t.tv_sec = 0; + t.tv_nsec = 0; + clock_gettime(CLOCK_MONOTONIC, &t); + return static_cast((t.tv_sec) * SEC_TO_NANOSEC + t.tv_nsec_) / SEC_TO_MICROSEC; +} + +int32_t DeleteFile(const std::string &filename) { if (filename.empty()) { LOG(ERROR) << "Invalid filename";