From 9fb0aa74fece1deea72ef7c8eef5e45da2113b21 Mon Sep 17 00:00:00 2001 From: fly_1997 Date: Tue, 26 Nov 2024 15:59:15 +0800 Subject: [PATCH 2/5] add data free and fix unsubscribe error --- src/common/CMakeLists.txt | 7 + src/common/data_register.cpp | 247 +++++++++++++++---- src/common/data_register.h | 20 +- src/plugin/collect/include/command_data.h | 2 +- src/plugin_mgr/event/unsubscribe_handler.cpp | 7 +- src/plugin_mgr/instance_run_handler.cpp | 2 +- src/sdk/oe_client.cpp | 1 + 7 files changed, 227 insertions(+), 59 deletions(-) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 2d49b3e..46084e5 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -22,6 +22,13 @@ target_link_libraries(${PROJECT_NAME} log4cplus) target_link_libraries(${PROJECT_NAME} yaml-cpp) target_link_libraries(${PROJECT_NAME} curl boundscheck) +if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") +target_link_directories(${PROJECT_NAME} PUBLIC + ${LIB_KPERF_LIBPATH} +) +target_link_libraries(${PROJECT_NAME} kperf) +endif() + file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/data_list.h" DESTINATION "${CMAKE_BINARY_DIR}/output/include") diff --git a/src/common/data_register.cpp b/src/common/data_register.cpp index 89e660e..cdf6d97 100644 --- a/src/common/data_register.cpp +++ b/src/common/data_register.cpp @@ -16,68 +16,107 @@ namespace oeaware { -int TopicSerialize(const void *topic, OutStream &out) +void TopicFree(CTopic *topic) { - auto tmpTopic = static_cast(topic); - std::string instanceName(tmpTopic->instanceName); - std::string topicName(tmpTopic->topicName); - std::string params(tmpTopic->params); + if (topic == nullptr) { + return; + } + if (topic->instanceName != nullptr) { + delete[] topic->instanceName; + topic->instanceName = nullptr; + } + if (topic->topicName != nullptr) { + delete[] topic->topicName; + topic->topicName = nullptr; + } + if (topic->params != nullptr) { + delete[] topic->params; + topic->params = nullptr; + } +} + +int TopicSerialize(const CTopic *topic, OutStream &out) +{ + std::string instanceName(topic->instanceName); + std::string topicName(topic->topicName); + std::string params(topic->params); out << instanceName << topicName << params; return 0; } -int TopicDeserialize(void *topic, InStream &in) +int TopicDeserialize(CTopic *topic, InStream &in) { std::string instanceName; std::string topicName; std::string params; in >> instanceName >> topicName >> params; - ((CTopic*)topic)->instanceName = new char[instanceName.size() + 1]; - ((CTopic*)topic)->topicName = new char[topicName.size() + 1]; - ((CTopic*)topic)->params = new char[params.size() + 1]; + topic->instanceName = new char[instanceName.size() + 1]; + topic->topicName = new char[topicName.size() + 1]; + topic->params = new char[params.size() + 1]; - auto ret = strcpy_s(((CTopic*)topic)->instanceName, instanceName.size() + 1, instanceName.data()); + auto ret = strcpy_s(topic->instanceName, instanceName.size() + 1, instanceName.data()); if (ret != EOK) return ret; - ret = strcpy_s(((CTopic*)topic)->topicName, topicName.size() + 1, topicName.data()); + ret = strcpy_s(topic->topicName, topicName.size() + 1, topicName.data()); if (ret != EOK) return ret; - ret = strcpy_s(((CTopic*)topic)->params, params.size() + 1, params.data()); + ret = strcpy_s(topic->params, params.size() + 1, params.data()); if (ret != EOK) return ret; return 0; } -int DataListSerialize(const void *dataList, OutStream &out) +void DataListFree(DataList *dataList) +{ + if (dataList == nullptr) { + return; + } + auto ® = Register::GetInstance(); + DataFreeFunc free = reg.GetDataFreeFunc(Concat({dataList->topic.instanceName, dataList->topic.topicName}, "::")); + if (free == nullptr) { + free = reg.GetDataFreeFunc(dataList->topic.instanceName); + } + if (free != nullptr) { + for (uint64_t i = 0; i < dataList->len; ++i) { + free(dataList->data[i]); + } + } + TopicFree(&dataList->topic); + if (dataList->data != nullptr) { + delete[] dataList->data; + dataList->data = nullptr; + } +} + +int DataListSerialize(const DataList *dataList, OutStream &out) { - auto tmpList = static_cast(dataList); - TopicSerialize(&tmpList->topic, out); - out << tmpList->len; + TopicSerialize(&dataList->topic, out); + out << dataList->len; auto ® = Register::GetInstance(); - auto func = reg.GetDataSerialize(Concat({tmpList->topic.instanceName, tmpList->topic.topicName}, "::")); + auto func = reg.GetDataSerialize(Concat({dataList->topic.instanceName, dataList->topic.topicName}, "::")); if (func == nullptr) { - func = reg.GetDataSerialize(tmpList->topic.instanceName); + func = reg.GetDataSerialize(dataList->topic.instanceName); } - for (uint64_t i = 0; i < tmpList->len; ++i) { - func(tmpList->data[i], out); + for (uint64_t i = 0; i < dataList->len; ++i) { + func(dataList->data[i], out); } return 0; } -int DataListDeserialize(void *dataList, InStream &in) +int DataListDeserialize(DataList *dataList, InStream &in) { CTopic topic; TopicDeserialize(&topic, in); uint64_t size; in >> size; - ((DataList*)dataList)->topic = topic; - ((DataList*)dataList)->len = size; - ((DataList*)dataList)->data = new void* [size]; + dataList->topic = topic; + dataList->len = size; + dataList->data = new void* [size]; auto ® = Register::GetInstance(); auto func = reg.GetDataDeserialize(Concat({topic.instanceName, topic.topicName}, "::")); if (func == nullptr) { func = reg.GetDataDeserialize(topic.instanceName); } for (uint64_t i = 0; i < size; ++i) { - ((DataList*)dataList)->data[i] = nullptr; - auto ret = func(&(((DataList*)dataList)->data[i]), in); + dataList->data[i] = nullptr; + auto ret = func(&(dataList->data[i]), in); if (ret) { return ret; } @@ -85,6 +124,16 @@ int DataListDeserialize(void *dataList, InStream &in) return 0; } +void ResultFree(Result *result) +{ + if (result == nullptr) { + return; + } + if (result->payload != nullptr) { + delete[] result->payload; + result->payload = nullptr; + } +} int ResultDeserialize(void *data, InStream &in) { @@ -96,6 +145,17 @@ int ResultDeserialize(void *data, InStream &in) return ret; } #if defined(__arm__) || defined(__aarch64__) +void PmuBaseDataFree(void *data) +{ + auto tmpData = static_cast(data); + if (tmpData == nullptr) { + return; + } + PmuDataFree(tmpData->pmuData); + tmpData->pmuData = nullptr; + tmpData->len = 0; +} + int PmuCountingDataSerialize(const void *data, OutStream &out) { auto tmpData = static_cast(data); @@ -456,6 +516,19 @@ int PmuUncoreDataDeserialize(void **data, InStream &in) } #endif +void ThreadInfoFree(void *data) +{ + auto threadInfo = static_cast(data); + if (threadInfo == nullptr) { + return; + } + if (threadInfo->name != nullptr) { + delete[] threadInfo->name; + threadInfo->name = nullptr; + } + delete threadInfo; +} + int ThreadInfoSerialize(const void *data, OutStream &out) { auto threadInfo = static_cast(data); @@ -476,6 +549,32 @@ int ThreadInfoDeserialize(void **data, InStream &in) return 0; } +void KernelDataFree(void *data) +{ + auto tmpData = static_cast(data); + if (tmpData == nullptr) { + return; + } + KernelDataNode *node = tmpData->kernelData; + for (int i = 0; i < tmpData->len; ++i) { + auto tmp = node->next; + if (node == nullptr) { + break; + } + if (node->key != nullptr) { + delete[] node->key; + node->key = nullptr; + } + if (node->value != nullptr) { + delete[] node->value; + node->value = nullptr; + } + delete node; + node = tmp; + } + delete tmpData; +} + int KernelDataSerialize(const void *data, OutStream &out) { auto tmpData = static_cast(data); @@ -523,17 +622,47 @@ int KernelDataDeserialize(void **data, InStream &in) return 0; } +void CommandDataFree(void *data) +{ + CommandData *commandData = (CommandData*)data; + if (commandData == nullptr) { + return; + } + for (int i = 0; i < commandData->attrLen; ++i) { + if (commandData->itemAttr[i] != nullptr) { + delete[] commandData->itemAttr[i]; + commandData->itemAttr[i] = nullptr; + } + } + if (commandData->items == nullptr) { + delete commandData; + return; + } + for (int i = 0; i < commandData->itemLen; ++i) { + for (int j = 0; j < commandData->attrLen; ++j) { + if (commandData->items[i].value[j] != nullptr) { + delete[] commandData->items[i].value[j]; + commandData->items[i].value[j] = nullptr; + } + } + } + delete[] commandData->items; + commandData->items = nullptr; + + delete commandData; +} + int CommandDataSerialize(const void *data, OutStream &out) { - auto sarData = (SarData*)data; - out << sarData->attrLen << sarData->itemLen; - for (int i = 0; i < sarData->attrLen; ++i) { - std::string attr(sarData->itemAttr[i]); + auto commandData = (CommandData*)data; + out << commandData->attrLen << commandData->itemLen; + for (int i = 0; i < commandData->attrLen; ++i) { + std::string attr(commandData->itemAttr[i]); out << attr; } - for (int i = 0; i < sarData->itemLen; ++i) { - for (int j = 0; j < sarData->attrLen; ++j) { - std::string item(sarData->items[i].value[j]); + for (int i = 0; i < commandData->itemLen; ++i) { + for (int j = 0; j < commandData->attrLen; ++j) { + std::string item(commandData->items[i].value[j]); out << item; } } @@ -542,8 +671,8 @@ int CommandDataSerialize(const void *data, OutStream &out) int CommandDataDeserialize(void **data, InStream &in) { - *data = new SarData(); - auto sarData = static_cast(*data); + *data = new CommandData(); + auto sarData = static_cast(*data); in >> sarData->attrLen >> sarData->itemLen; int ret; for (int i = 0; i < sarData->attrLen; ++i) { @@ -570,6 +699,15 @@ int CommandDataDeserialize(void **data, InStream &in) return 0; } +void AnalysisDataFree(void *data) +{ + auto analysisData = static_cast(data); + if (analysisData == nullptr) { + return; + } + delete analysisData; +} + int AnalysisDataSerialize(const void *data, OutStream &out) { auto analysisData = static_cast(data); @@ -600,44 +738,55 @@ int AnalysisDataDeserialize(void **data, InStream &in) void Register::RegisterData(const std::string &name, const RegisterEntry &entry) { - deserializeFuncs[name] = entry; + registerEntry[name] = entry; } void Register::InitRegisterData() { #if defined(__arm__) || defined(__aarch64__) - RegisterData("pmu_counting_collector", RegisterEntry(PmuCountingDataSerialize, PmuCountingDataDeserialize)); + RegisterData("pmu_counting_collector", RegisterEntry(PmuCountingDataSerialize, PmuCountingDataDeserialize, + PmuBaseDataFree)); - RegisterData("pmu_sampling_collector", RegisterEntry(PmuSamplingDataSerialize, PmuSamplingDataDeserialize)); + RegisterData("pmu_sampling_collector", RegisterEntry(PmuSamplingDataSerialize, PmuSamplingDataDeserialize, + PmuBaseDataFree)); - RegisterData("pmu_spe_collector", RegisterEntry(PmuSpeDataSerialize, PmuSpeDataDeserialize)); + RegisterData("pmu_spe_collector", RegisterEntry(PmuSpeDataSerialize, PmuSpeDataDeserialize, PmuBaseDataFree)); - RegisterData("pmu_uncore_collector", RegisterEntry(PmuUncoreDataSerialize, PmuUncoreDataDeserialize)); + RegisterData("pmu_uncore_collector", RegisterEntry(PmuUncoreDataSerialize, PmuUncoreDataDeserialize, + PmuBaseDataFree)); #endif - RegisterData("thread_collector", RegisterEntry(ThreadInfoSerialize, ThreadInfoDeserialize)); + RegisterData("thread_collector", RegisterEntry(ThreadInfoSerialize, ThreadInfoDeserialize, ThreadInfoFree)); + + RegisterData("kernel_config", RegisterEntry(KernelDataSerialize, KernelDataDeserialize, KernelDataFree)); - RegisterData("kernel_config", RegisterEntry(KernelDataSerialize, KernelDataDeserialize)); + RegisterData("thread_scenario", RegisterEntry(ThreadInfoSerialize, ThreadInfoDeserialize, ThreadInfoFree)); - RegisterData("thread_scenario", RegisterEntry(ThreadInfoSerialize, ThreadInfoDeserialize)); + RegisterData("command_collector", RegisterEntry(CommandDataSerialize, CommandDataDeserialize, CommandDataFree)); - RegisterData("command_collector", RegisterEntry(CommandDataSerialize, CommandDataDeserialize)); - RegisterData("command_collector", RegisterEntry(CommandDataSerialize, CommandDataDeserialize)); RegisterData("analysis_aware", RegisterEntry(AnalysisDataSerialize, AnalysisDataDeserialize)); } SerializeFunc Register::GetDataSerialize(const std::string &name) { - if (!deserializeFuncs.count(name)) { + if (!registerEntry.count(name)) { return nullptr; } - return deserializeFuncs[name].se; + return registerEntry[name].se; } DeserializeFunc Register::GetDataDeserialize(const std::string &name) { - if (!deserializeFuncs.count(name)) { + if (!registerEntry.count(name)) { + return nullptr; + } + return registerEntry[name].de; +} + +DataFreeFunc Register::GetDataFreeFunc(const std::string &name) +{ + if (!registerEntry.count(name)) { return nullptr; } - return deserializeFuncs[name].de; + return registerEntry[name].free; } } diff --git a/src/common/data_register.h b/src/common/data_register.h index 5e1ae4a..b72cd97 100644 --- a/src/common/data_register.h +++ b/src/common/data_register.h @@ -13,18 +13,21 @@ #define COMMON_DATA_REGISTER_H #include #include "serialize.h" +#include "data_list.h" namespace oeaware { using DeserializeFunc = int(*)(void**, InStream &in); using SerializeFunc = int(*)(const void*, OutStream &out); -using FreeData = void(*)(void *); +using DataFreeFunc = void(*)(void *); struct RegisterEntry { RegisterEntry() { } RegisterEntry(const SerializeFunc &se, const DeserializeFunc &de) : se(se), de(de) { } + RegisterEntry(const SerializeFunc &se, const DeserializeFunc &de, const DataFreeFunc &free) : se(se), + de(de), free(free) { } SerializeFunc se; DeserializeFunc de; - FreeData free; + DataFreeFunc free; }; class Register { @@ -40,17 +43,20 @@ public: void InitRegisterData(); DeserializeFunc GetDataDeserialize(const std::string &name); SerializeFunc GetDataSerialize(const std::string &name); + DataFreeFunc GetDataFreeFunc(const std::string &name); void RegisterData(const std::string &name, const RegisterEntry &func); private: Register() { }; - std::unordered_map deserializeFuncs; + std::unordered_map registerEntry; }; - -int DataListSerialize(const void *data, OutStream &out); -int DataListDeserialize(void *data, InStream &in); +void DataListFree(DataList *dataList); +int DataListSerialize(const DataList *dataList, OutStream &out); +int DataListDeserialize(DataList *dataList, InStream &in); int ResultDeserialize(void *data, InStream &in); -int TopicSerialize(const void *topic, OutStream &out); +int TopicSerialize(const CTopic *topic, OutStream &out); +int TopicDeserialize(CTopic *topic, InStream &in); +void TopicFree(CTopic *topic); } #endif diff --git a/src/plugin/collect/include/command_data.h b/src/plugin/collect/include/command_data.h index f466bd3..e7a8540 100644 --- a/src/plugin/collect/include/command_data.h +++ b/src/plugin/collect/include/command_data.h @@ -26,7 +26,7 @@ typedef struct { int attrLen; char *itemAttr[ATTR_MAX_LENGTH]; CommandIter *items; -} SarData, CommandData; +} CommandData; #ifdef __cplusplus } #endif diff --git a/src/plugin_mgr/event/unsubscribe_handler.cpp b/src/plugin_mgr/event/unsubscribe_handler.cpp index 72b53bf..749a683 100644 --- a/src/plugin_mgr/event/unsubscribe_handler.cpp +++ b/src/plugin_mgr/event/unsubscribe_handler.cpp @@ -23,7 +23,12 @@ EventResult UnsubscribeHandler::Handle(const Event &event) INFO(logger, "sdk " << event.payload[0] << " disconnected and has been unsubscribed related topics."); return eventResult; } - auto msg = std::make_shared(RunType::UNSUBSCRIBE, event.payload); + CTopic cTopic; + InStream in(event.payload[0]); + TopicDeserialize(&cTopic, in); + Topic topic{cTopic.instanceName, cTopic.topicName, cTopic.params}; + auto msg = std::make_shared(RunType::UNSUBSCRIBE, + std::vector{topic.GetType(), event.payload[1]}); instanceRunHandler->RecvQueuePush(msg); msg->Wait(); result = msg->result; diff --git a/src/plugin_mgr/instance_run_handler.cpp b/src/plugin_mgr/instance_run_handler.cpp index 2e11d0d..30dc886 100644 --- a/src/plugin_mgr/instance_run_handler.cpp +++ b/src/plugin_mgr/instance_run_handler.cpp @@ -181,7 +181,7 @@ void InstanceRunHandler::PublishData(std::shared_ptr &msg) auto instance = memoryStore->GetInstance(subscriber); instance->interface->UpdateData(msg->dataList); } - // free dataList + DataListFree(&msg->dataList); } bool InstanceRunHandler::HandleMessage() diff --git a/src/sdk/oe_client.cpp b/src/sdk/oe_client.cpp index 4eb04ae..9452a37 100644 --- a/src/sdk/oe_client.cpp +++ b/src/sdk/oe_client.cpp @@ -70,6 +70,7 @@ void Impl::HandleRecv() for (auto handle : topicHandle[key]) { handle(&dataList); } + DataListFree(&dataList); break; } default: -- 2.33.0