106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci */ 1506f6ba60Sopenharmony_ci 1606f6ba60Sopenharmony_ci#include "plugin_session_manager.h" 1706f6ba60Sopenharmony_ci 1806f6ba60Sopenharmony_cinamespace { 1906f6ba60Sopenharmony_ciconstexpr uint32_t MAX_BUFFER_PAGES = 512 * 1024 * 1024 / 4096; 2006f6ba60Sopenharmony_ci} 2106f6ba60Sopenharmony_ci 2206f6ba60Sopenharmony_ciPluginSessionManager::PluginSessionManager(const PluginServiceWeakPtr& pluginService) : pluginService_(pluginService) {} 2306f6ba60Sopenharmony_ci 2406f6ba60Sopenharmony_ciPluginSessionManager::~PluginSessionManager() {} 2506f6ba60Sopenharmony_ci 2606f6ba60Sopenharmony_cibool PluginSessionManager::CheckBufferConfig(const ProfilerSessionConfig::BufferConfig& bufferConfig) 2706f6ba60Sopenharmony_ci{ 2806f6ba60Sopenharmony_ci const uint32_t pages = bufferConfig.pages(); 2906f6ba60Sopenharmony_ci const auto policy = bufferConfig.policy(); 3006f6ba60Sopenharmony_ci return pages > 0 && pages <= MAX_BUFFER_PAGES && 3106f6ba60Sopenharmony_ci (policy == ProfilerSessionConfig::BufferConfig::RECYCLE || 3206f6ba60Sopenharmony_ci policy == ProfilerSessionConfig::BufferConfig::FLATTEN); 3306f6ba60Sopenharmony_ci} 3406f6ba60Sopenharmony_ci 3506f6ba60Sopenharmony_cibool PluginSessionManager::CheckPluginSha256(const ProfilerPluginConfig& pluginConfig) 3606f6ba60Sopenharmony_ci{ 3706f6ba60Sopenharmony_ci std::string reqSha = pluginConfig.plugin_sha256(); 3806f6ba60Sopenharmony_ci if (reqSha.size() > 0) { // only check when SHA256 provided in request 3906f6ba60Sopenharmony_ci auto pluginSvc = pluginService_.lock(); 4006f6ba60Sopenharmony_ci CHECK_NOTNULL(pluginSvc, false, "plugin service null!"); 4106f6ba60Sopenharmony_ci 4206f6ba60Sopenharmony_ci PluginInfo info = {}; 4306f6ba60Sopenharmony_ci std::string name = pluginConfig.name(); 4406f6ba60Sopenharmony_ci CHECK_TRUE(pluginSvc->GetPluginInfo(name, info), false, "get plugin info %s failed!", name.c_str()); 4506f6ba60Sopenharmony_ci 4606f6ba60Sopenharmony_ci std::string devSha = info.sha256; 4706f6ba60Sopenharmony_ci CHECK_TRUE(devSha == reqSha, false, "SHA256 mismatch: %s, %s!", devSha.c_str(), reqSha.c_str()); 4806f6ba60Sopenharmony_ci } 4906f6ba60Sopenharmony_ci return true; 5006f6ba60Sopenharmony_ci} 5106f6ba60Sopenharmony_ci 5206f6ba60Sopenharmony_ciPluginSessionPtr PluginSessionManager::CreatePluginSession(const ProfilerPluginConfig& pluginConfig, 5306f6ba60Sopenharmony_ci const ProfilerSessionConfig::BufferConfig& bufferConfig, 5406f6ba60Sopenharmony_ci const ProfilerDataRepeaterPtr& dataRepeater) 5506f6ba60Sopenharmony_ci{ 5606f6ba60Sopenharmony_ci auto name = pluginConfig.name(); 5706f6ba60Sopenharmony_ci CHECK_TRUE(pluginSessions_.count(name) == 0, nullptr, "plugin name %s exists!", name.c_str()); 5806f6ba60Sopenharmony_ci CHECK_TRUE(CheckBufferConfig(bufferConfig), nullptr, "buffer config invalid!"); 5906f6ba60Sopenharmony_ci CHECK_TRUE(CheckPluginSha256(pluginConfig), nullptr, "SHA256 check failed!"); 6006f6ba60Sopenharmony_ci 6106f6ba60Sopenharmony_ci auto session = std::make_shared<PluginSession>(pluginConfig, bufferConfig, pluginService_, dataRepeater); 6206f6ba60Sopenharmony_ci CHECK_NOTNULL(session, nullptr, "allocate plugin session for %s failed!", name.c_str()); 6306f6ba60Sopenharmony_ci CHECK_TRUE(session->IsAvailable(), nullptr, "config plugin for %s failed!", name.c_str()); 6406f6ba60Sopenharmony_ci return session; 6506f6ba60Sopenharmony_ci} 6606f6ba60Sopenharmony_ci 6706f6ba60Sopenharmony_ciPluginSessionPtr PluginSessionManager::CreatePluginSession(const ProfilerPluginConfig& pluginConfig, 6806f6ba60Sopenharmony_ci const ProfilerDataRepeaterPtr& dataRepeater) 6906f6ba60Sopenharmony_ci{ 7006f6ba60Sopenharmony_ci auto name = pluginConfig.name(); 7106f6ba60Sopenharmony_ci CHECK_TRUE(pluginSessions_.count(name) == 0, nullptr, "plugin name %s exists!", name.c_str()); 7206f6ba60Sopenharmony_ci CHECK_TRUE(CheckPluginSha256(pluginConfig), nullptr, "SHA256 check failed!"); 7306f6ba60Sopenharmony_ci 7406f6ba60Sopenharmony_ci auto session = std::make_shared<PluginSession>(pluginConfig, pluginService_, dataRepeater); 7506f6ba60Sopenharmony_ci CHECK_NOTNULL(session, nullptr, "allocate plugin session for %s failed!", name.c_str()); 7606f6ba60Sopenharmony_ci CHECK_TRUE(session->IsAvailable(), nullptr, "config plugin for %s failed!", name.c_str()); 7706f6ba60Sopenharmony_ci return session; 7806f6ba60Sopenharmony_ci} 7906f6ba60Sopenharmony_ci 8006f6ba60Sopenharmony_cibool PluginSessionManager::CreatePluginSessions(const std::vector<ProfilerPluginConfig>& pluginConfigs, 8106f6ba60Sopenharmony_ci const std::vector<ProfilerSessionConfig::BufferConfig>& bufferConfigs, 8206f6ba60Sopenharmony_ci const ProfilerDataRepeaterPtr& dataRepeater) 8306f6ba60Sopenharmony_ci{ 8406f6ba60Sopenharmony_ci CHECK_TRUE(pluginConfigs.size() == bufferConfigs.size(), false, "buffer and config vector size mismatch %zu, %zu", 8506f6ba60Sopenharmony_ci bufferConfigs.size(), pluginConfigs.size()); 8606f6ba60Sopenharmony_ci 8706f6ba60Sopenharmony_ci std::map<std::string, PluginSessionPtr> tmpPluginSessions; 8806f6ba60Sopenharmony_ci for (size_t i = 0; i < pluginConfigs.size(); i++) { 8906f6ba60Sopenharmony_ci auto session = CreatePluginSession(pluginConfigs[i], bufferConfigs[i], dataRepeater); 9006f6ba60Sopenharmony_ci 9106f6ba60Sopenharmony_ci // tmpPluginSessions will released if some plugin session create failed 9206f6ba60Sopenharmony_ci CHECK_NOTNULL(session, false, "create plugin-%zu session failed!", i); 9306f6ba60Sopenharmony_ci tmpPluginSessions[pluginConfigs[i].name()] = session; 9406f6ba60Sopenharmony_ci } 9506f6ba60Sopenharmony_ci 9606f6ba60Sopenharmony_ci // insert all plugin session to pluginSessions_ map 9706f6ba60Sopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 9806f6ba60Sopenharmony_ci for (auto& entry : tmpPluginSessions) { 9906f6ba60Sopenharmony_ci pluginSessions_.insert(entry); 10006f6ba60Sopenharmony_ci } 10106f6ba60Sopenharmony_ci return true; 10206f6ba60Sopenharmony_ci} 10306f6ba60Sopenharmony_ci 10406f6ba60Sopenharmony_cibool PluginSessionManager::CreatePluginSessions(const std::vector<ProfilerPluginConfig>& pluginConfigs, 10506f6ba60Sopenharmony_ci const ProfilerDataRepeaterPtr& dataRepeater) 10606f6ba60Sopenharmony_ci{ 10706f6ba60Sopenharmony_ci std::map<std::string, PluginSessionPtr> tmpPluginSessions; 10806f6ba60Sopenharmony_ci for (size_t i = 0; i < pluginConfigs.size(); i++) { 10906f6ba60Sopenharmony_ci auto session = CreatePluginSession(pluginConfigs[i], dataRepeater); 11006f6ba60Sopenharmony_ci 11106f6ba60Sopenharmony_ci // tmpPluginSessions will released if some plugin session create failed 11206f6ba60Sopenharmony_ci CHECK_NOTNULL(session, false, "create plugin-%zu session without shmem buffer failed!", i); 11306f6ba60Sopenharmony_ci tmpPluginSessions[pluginConfigs[i].name()] = session; 11406f6ba60Sopenharmony_ci } 11506f6ba60Sopenharmony_ci 11606f6ba60Sopenharmony_ci // insert all plugin session to pluginSessions_ map 11706f6ba60Sopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 11806f6ba60Sopenharmony_ci for (auto& entry : tmpPluginSessions) { 11906f6ba60Sopenharmony_ci pluginSessions_.insert(entry); 12006f6ba60Sopenharmony_ci } 12106f6ba60Sopenharmony_ci return true; 12206f6ba60Sopenharmony_ci} 12306f6ba60Sopenharmony_ci 12406f6ba60Sopenharmony_cibool PluginSessionManager::RemovePluginSessions(const std::vector<std::string>& nameList) 12506f6ba60Sopenharmony_ci{ 12606f6ba60Sopenharmony_ci CHECK_TRUE(nameList.size() > 0, false, "nameList empty!"); 12706f6ba60Sopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 12806f6ba60Sopenharmony_ci for (auto& name : nameList) { 12906f6ba60Sopenharmony_ci auto it = pluginSessions_.find(name); 13006f6ba60Sopenharmony_ci if (it == pluginSessions_.end()) { 13106f6ba60Sopenharmony_ci continue; 13206f6ba60Sopenharmony_ci } 13306f6ba60Sopenharmony_ci pluginSessions_.erase(it); 13406f6ba60Sopenharmony_ci } 13506f6ba60Sopenharmony_ci return true; 13606f6ba60Sopenharmony_ci} 13706f6ba60Sopenharmony_ci 13806f6ba60Sopenharmony_cibool PluginSessionManager::InvalidatePluginSessions(const std::vector<std::string>& nameList) 13906f6ba60Sopenharmony_ci{ 14006f6ba60Sopenharmony_ci CHECK_TRUE(nameList.size() > 0, false, "nameList empty!"); 14106f6ba60Sopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 14206f6ba60Sopenharmony_ci for (auto& name : nameList) { 14306f6ba60Sopenharmony_ci auto it = pluginSessions_.find(name); 14406f6ba60Sopenharmony_ci if (it == pluginSessions_.end()) { 14506f6ba60Sopenharmony_ci continue; 14606f6ba60Sopenharmony_ci } 14706f6ba60Sopenharmony_ci it->second->Invalidate(); 14806f6ba60Sopenharmony_ci } 14906f6ba60Sopenharmony_ci return true; 15006f6ba60Sopenharmony_ci} 15106f6ba60Sopenharmony_ci 15206f6ba60Sopenharmony_cibool PluginSessionManager::StartPluginSessions(const std::vector<std::string>& nameList) 15306f6ba60Sopenharmony_ci{ 15406f6ba60Sopenharmony_ci CHECK_TRUE(nameList.size() > 0, false, "nameList empty!"); 15506f6ba60Sopenharmony_ci pluginNameList_ = std::move(nameList); 15606f6ba60Sopenharmony_ci // start each plugin sessions 15706f6ba60Sopenharmony_ci size_t failureCount = 0; 15806f6ba60Sopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 15906f6ba60Sopenharmony_ci for (auto& name : nameList) { 16006f6ba60Sopenharmony_ci auto it = pluginSessions_.find(name); 16106f6ba60Sopenharmony_ci if (it == pluginSessions_.end()) { 16206f6ba60Sopenharmony_ci continue; 16306f6ba60Sopenharmony_ci } 16406f6ba60Sopenharmony_ci if (!it->second->Start()) { 16506f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "start session %s FAILED!", it->first.c_str()); 16606f6ba60Sopenharmony_ci failureCount++; 16706f6ba60Sopenharmony_ci } 16806f6ba60Sopenharmony_ci } 16906f6ba60Sopenharmony_ci return failureCount == 0; 17006f6ba60Sopenharmony_ci} 17106f6ba60Sopenharmony_ci 17206f6ba60Sopenharmony_cibool PluginSessionManager::StopPluginSessions(const std::vector<std::string>& nameList) 17306f6ba60Sopenharmony_ci{ 17406f6ba60Sopenharmony_ci // stop each plugin sessions 17506f6ba60Sopenharmony_ci size_t failureCount = 0; 17606f6ba60Sopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 17706f6ba60Sopenharmony_ci for (auto& name : nameList) { 17806f6ba60Sopenharmony_ci auto it = pluginSessions_.find(name); 17906f6ba60Sopenharmony_ci if (it == pluginSessions_.end()) { 18006f6ba60Sopenharmony_ci continue; 18106f6ba60Sopenharmony_ci } 18206f6ba60Sopenharmony_ci if (!it->second->Stop()) { 18306f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "stop session %s FAILED!", it->first.c_str()); 18406f6ba60Sopenharmony_ci failureCount++; 18506f6ba60Sopenharmony_ci } 18606f6ba60Sopenharmony_ci } 18706f6ba60Sopenharmony_ci return failureCount == 0; 18806f6ba60Sopenharmony_ci} 18906f6ba60Sopenharmony_ci 19006f6ba60Sopenharmony_cibool PluginSessionManager::RefreshPluginSession() 19106f6ba60Sopenharmony_ci{ 19206f6ba60Sopenharmony_ci size_t failureCount = 0; 19306f6ba60Sopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 19406f6ba60Sopenharmony_ci for (auto& name : pluginNameList_) { 19506f6ba60Sopenharmony_ci auto it = pluginSessions_.find(name); 19606f6ba60Sopenharmony_ci if (it == pluginSessions_.end()) { 19706f6ba60Sopenharmony_ci continue; 19806f6ba60Sopenharmony_ci } 19906f6ba60Sopenharmony_ci if (!it->second->Refresh()) { 20006f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "refresh data %s FAILED!", it->first.c_str()); 20106f6ba60Sopenharmony_ci failureCount++; 20206f6ba60Sopenharmony_ci } 20306f6ba60Sopenharmony_ci } 20406f6ba60Sopenharmony_ci return failureCount == 0; 20506f6ba60Sopenharmony_ci} 20606f6ba60Sopenharmony_ci 20706f6ba60Sopenharmony_cibool PluginSessionManager::CheckStatus(const std::vector<std::string>& nameList, PluginSession::State state) 20806f6ba60Sopenharmony_ci{ 20906f6ba60Sopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 21006f6ba60Sopenharmony_ci for (auto& name : nameList) { 21106f6ba60Sopenharmony_ci auto it = pluginSessions_.find(name); 21206f6ba60Sopenharmony_ci if (it == pluginSessions_.end()) { 21306f6ba60Sopenharmony_ci continue; 21406f6ba60Sopenharmony_ci } 21506f6ba60Sopenharmony_ci auto actualState = it->second->GetState(); 21606f6ba60Sopenharmony_ci if (actualState != state) { 21706f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "plugin %s state is %d not %d!", it->first.c_str(), actualState, state); 21806f6ba60Sopenharmony_ci return false; 21906f6ba60Sopenharmony_ci } 22006f6ba60Sopenharmony_ci } 22106f6ba60Sopenharmony_ci return true; 22206f6ba60Sopenharmony_ci} 22306f6ba60Sopenharmony_ci 22406f6ba60Sopenharmony_cistd::vector<PluginSession::State> PluginSessionManager::GetStatus(const std::vector<std::string>& nameList) 22506f6ba60Sopenharmony_ci{ 22606f6ba60Sopenharmony_ci std::vector<PluginSession::State> status; 22706f6ba60Sopenharmony_ci std::unique_lock<std::mutex> lock(mutex_); 22806f6ba60Sopenharmony_ci for (auto& name : nameList) { 22906f6ba60Sopenharmony_ci auto it = pluginSessions_.find(name); 23006f6ba60Sopenharmony_ci if (it == pluginSessions_.end()) { 23106f6ba60Sopenharmony_ci continue; 23206f6ba60Sopenharmony_ci } 23306f6ba60Sopenharmony_ci status.push_back(it->second->GetState()); 23406f6ba60Sopenharmony_ci } 23506f6ba60Sopenharmony_ci return status; 23606f6ba60Sopenharmony_ci} 237