diff --git a/adapter/uhdf2/host/src/devhost_dump.c b/adapter/uhdf2/host/src/devhost_dump.c index 7fb9ab93f21f276139dd55b3689298933b037b23..75e9fa52c4264032846981b72e3bf987afc25acb 100644 --- a/adapter/uhdf2/host/src/devhost_dump.c +++ b/adapter/uhdf2/host/src/devhost_dump.c @@ -21,6 +21,7 @@ #include "hdf_log.h" #include "osal_mem.h" #include "osal_mutex.h" +#include "hdf_dump_reg.h" #define HDF_LOG_TAG devhost_dump @@ -157,6 +158,15 @@ void DevHostDump(struct HdfSBuf *data, struct HdfSBuf *reply) if (!dumpFlag) { (void)HdfSbufWriteString(reply, "The service does not register dump function\n"); } + } else if (strcmp(option, "--ipc")) { + int32_t fd = -1; + HdfSbufReadInt32(data, &fd); + HDF_LOGI("%{public}s %{public}d", option, fd); + const char *dumpCmd = HdfSbufReadString(data); + if (dumpCmd == NULL) { + return; + } + HdfDumpIpcStat(fd, dumpCmd); } else { HDF_LOGE("%{public}s invalid parameter %{public}s", __func__, option); } diff --git a/adapter/uhdf2/ipc/src/hdf_dump.cpp b/adapter/uhdf2/ipc/src/hdf_dump.cpp index 082becd47c4b1a4f2575a313f908ef3c6d496a13..642d13458b960112215231a119e2a2b242616c63 100644 --- a/adapter/uhdf2/ipc/src/hdf_dump.cpp +++ b/adapter/uhdf2/ipc/src/hdf_dump.cpp @@ -15,21 +15,123 @@ #include "hdf_dump.h" +#include "ipc_payload_statistics.h" + #include "file_ex.h" #include "string_ex.h" +#include "unistd.h" #include "hdf_base.h" #include "hdf_dump_reg.h" #include "hdf_log.h" #include "hdf_sbuf.h" +#include "securec.h" #define HDF_LOG_TAG hdf_dump +using namespace OHOS; + static DevHostDumpFunc g_dump = nullptr; +const char *HDF_DUMP_SUCCESS_STR = "success\n"; +const char *HDF_DUMP_FAIL_STR = "fail\n"; + // The maximum parameter is the parameter sent to the host, including public(num=2) and private(mux_num=20) parameters static constexpr int32_t MAX_PARA_NUM = 22; +static bool HdfDumpIpcStatStart(std::string& result) +{ + result = std::string("HdfDumperIpcStatStart pid:") + std::to_string(getpid()); + bool ret = IPCPayloadStatistics::StartStatistics(); + result += ret ? HDF_DUMP_SUCCESS_STR : HDF_DUMP_FAIL_STR; + return ret; +} + +static int32_t HdfDumpIpcStatStop(std::string& result) +{ + result = std::string("HdfDumperIpcStatStop pid:") + std::to_string(getpid()); + bool ret = IPCPayloadStatistics::StopStatistics(); + result += ret ? HDF_DUMP_SUCCESS_STR : HDF_DUMP_FAIL_STR; + return ret; +} + +static int32_t HdfDumpIpcStatGet(std::string& result) +{ + result += "********************************GlobalStatisticsInfo********************************"; + result += "\nCurrentPid:"; + result += std::to_string(getpid()); + result += "\nTotalCount:"; + result += std::to_string(IPCPayloadStatistics::GetTotalCount()); + result += "\nTotalTimeCost:"; + result += std::to_string(IPCPayloadStatistics::GetTotalCost()); + std::vector pids; + pids = IPCPayloadStatistics::GetPids(); + for (unsigned int i = 0; i < pids.size(); i++) { + result += "\n--------------------------------ProcessStatisticsInfo-------------------------------"; + result += "\nCallingPid:"; + result += std::to_string(pids[i]); + result += "\nCallingPidTotalCount:"; + result += std::to_string(IPCPayloadStatistics::GetCount(pids[i])); + result += "\nCallingPidTotalTimeCost:"; + result += std::to_string(IPCPayloadStatistics::GetCost(pids[i])); + std::vector intfs; + intfs = IPCPayloadStatistics::GetDescriptorCodes(pids[i]); + for (unsigned int j = 0; j < intfs.size(); j++) { + result += "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~InterfaceStatisticsInfo~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; + result += "\nDescriptorCode:"; + result += Str16ToStr8(intfs[j].desc) + std::string("_") + std::to_string(intfs[j].code); + result += "\nDescriptorCodeCount:"; + result += std::to_string( + IPCPayloadStatistics::GetDescriptorCodeCount(pids[i], intfs[j].desc, intfs[j].code)); + result += "\nDescriptorCodeTimeCost:"; + result += "\nTotal:"; + result += std::to_string( + IPCPayloadStatistics::GetDescriptorCodeCost(pids[i], intfs[j].desc, intfs[j].code).totalCost); + result += " | Max:"; + result += std::to_string( + IPCPayloadStatistics::GetDescriptorCodeCost(pids[i], intfs[j].desc, intfs[j].code).maxCost); + result += " | Min:"; + result += std::to_string( + IPCPayloadStatistics::GetDescriptorCodeCost(pids[i], intfs[j].desc, intfs[j].code).minCost); + result += " | Avg:"; + result += std::to_string( + IPCPayloadStatistics::GetDescriptorCodeCost(pids[i], intfs[j].desc, intfs[j].code).averCost); + result += "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; + } + result += "\n------------------------------------------------------------------------------------"; + } + result += "\n************************************************************************************\n"; + + return true; +} + +bool HdfDumpIpcStat(int32_t fd, const char *cmd) +{ + if (cmd == NULL) { + HDF_LOGE("%{public}s cmd is null", __func__); + return HDF_FAILURE; + } + + bool ret = false; + std::string result; + HDF_LOGI("%{public}s %{public}d", cmd, fd); + if (strcmp(cmd, "--start-stat") == 0) { + ret = HdfDumpIpcStatStart(result); + } else if (strcmp(cmd, "--stop-stat") == 0) { + ret = HdfDumpIpcStatStop(result); + } else if (strcmp(cmd, "--stat") == 0) { + ret = HdfDumpIpcStatGet(result); + } else { + return ret; + } + + if (!OHOS::SaveStringToFd(fd, result)) { + ret = false; + } + + return ret; +} + void HdfRegisterDumpFunc(DevHostDumpFunc dump) { g_dump = dump; @@ -64,6 +166,10 @@ int32_t HdfDump(int32_t fd, const std::vector &args) goto FINISHED; } + if (!HdfSbufWriteInt32(data, fd)) { + goto FINISHED; + } + if (!HdfSbufWriteUint32(data, argv)) { goto FINISHED; } diff --git a/adapter/uhdf2/manager/src/devmgr_dump.c b/adapter/uhdf2/manager/src/devmgr_dump.c index 8a0b7bfdb6bbe08f00b76c392aa6c375658905b3..69b9f1e03e2100283aeba8bcbd5d47e764fb0596 100644 --- a/adapter/uhdf2/manager/src/devmgr_dump.c +++ b/adapter/uhdf2/manager/src/devmgr_dump.c @@ -29,7 +29,7 @@ #include "devmgr_dump.h" #define HDF_LOG_TAG devmgr_dump - + static const char *HELP_COMMENT = " usage:\n" " -help :display help information\n" @@ -192,6 +192,79 @@ static int32_t DevMgrDumpService(uint32_t argv, struct HdfSBuf *data, struct Hdf return ret; } +static int32_t DevMgrDumpAllHostIpcStats(struct HdfSBuf *data, struct HdfSBuf *reply) +{ + struct DevmgrService *devMgrSvc = (struct DevmgrService *)DevmgrServiceGetInstance(); + if (devMgrSvc == NULL) { + return HDF_FAILURE; + } + + struct DevHostServiceClnt *hostClnt = NULL; + int32_t ret = HDF_FAILURE; + DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) { + HDF_LOGI("%{public}s hostName:%{public}s", __func__, hostClnt->hostName); + if (hostClnt->hostService == NULL || hostClnt->hostService->Dump == NULL) { + (void)HdfSbufWriteString(reply, "The host does not start\n"); + continue; + } + ret = hostClnt->hostService->Dump(hostClnt->hostService, data, reply); + } + + return ret; +} + +static int32_t DevMgrDumpAllHostIpcStat(int32_t fd, const char *cmd, struct HdfSBuf *reply) +{ + struct HdfSBuf *ipcData = HdfSbufTypedObtain(SBUF_IPC); + if (ipcData == NULL) { + return HDF_FAILURE; + } + + if (!HdfSbufWriteString(ipcData, "--ipc")) { + HdfSbufRecycle(ipcData); + return HDF_FAILURE; + } + + if (!HdfSbufWriteInt32(ipcData, fd)) { + HdfSbufRecycle(ipcData); + return HDF_FAILURE; + } + + if (!HdfSbufWriteString(ipcData, cmd)) { + HdfSbufRecycle(ipcData); + return HDF_FAILURE; + } + + int32_t ret = DevMgrDumpAllHostIpcStats(ipcData, reply); + HdfSbufRecycle(ipcData); + return ret; +} + +static int32_t DevMgrDumpIpc(int32_t fd, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + const char *value = HdfSbufReadString(data); + if (value == NULL) { + HDF_LOGE("%{public}s value is null", __func__); + return HDF_FAILURE; + } + + const char *dumpCmd = HdfSbufReadString(data); + if (dumpCmd == NULL) { + HDF_LOGE("%{public}s dumpCmd is null", __func__); + return HDF_FAILURE; + } + + HDF_LOGI("%{public}s %{public}s fd:%{public}d", value, dumpCmd, fd); + if (strcmp(value, "all") == 0) { + HdfDumpIpcStat(fd, dumpCmd); + return DevMgrDumpAllHostIpcStat(fd, dumpCmd, reply); + } else { + (void)HdfSbufWriteString(reply, HELP_COMMENT); + } + + return HDF_SUCCESS; +} + static int32_t DevMgrFillDeviceHostInfo(struct HdfSBuf *data, struct HdfSBuf *reply) { const char *name = HdfSbufReadString(data); @@ -470,6 +543,9 @@ static int32_t DevMgrDump(struct HdfSBuf *data, struct HdfSBuf *reply) return HDF_FAILURE; } + int32_t fd = -1; + HdfSbufReadInt32(data, &fd); + uint32_t argv = 0; HdfSbufReadUint32(data, &argv); @@ -501,6 +577,8 @@ static int32_t DevMgrDump(struct HdfSBuf *data, struct HdfSBuf *reply) return DevMgrDumpHost(argv - 1, data, reply); } else if (strcmp(value, "-service") == 0) { return DevMgrDumpService(argv - 1, data, reply); + } else if (strcmp(value, "--ipc") == 0) { + return DevMgrDumpIpc(fd, data, reply); } else { (void)HdfSbufWriteString(reply, HELP_COMMENT); return HDF_SUCCESS; diff --git a/interfaces/inner_api/ipc/hdf_dump_reg.h b/interfaces/inner_api/ipc/hdf_dump_reg.h index 4bec261301a5088bb9e1e04c26d7d8a79c88a322..d59d5929308dd90d335f9bcdea4fc2a24c42d811 100644 --- a/interfaces/inner_api/ipc/hdf_dump_reg.h +++ b/interfaces/inner_api/ipc/hdf_dump_reg.h @@ -44,6 +44,8 @@ extern "C" { #endif /* __cplusplus */ +bool HdfDumpIpcStat(int32_t fd, const char *cmd); + /** * @brief Implements IPC dump. *