• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
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 #include "plugin_session_manager.h"
17 
18 namespace {
19 constexpr uint32_t MAX_BUFFER_PAGES = 512 * 1024 * 1024 / 4096;
20 }
21 
PluginSessionManager(const PluginServiceWeakPtr & pluginService)22 PluginSessionManager::PluginSessionManager(const PluginServiceWeakPtr& pluginService) : pluginService_(pluginService) {}
23 
~PluginSessionManager()24 PluginSessionManager::~PluginSessionManager() {}
25 
CheckBufferConfig(const ProfilerSessionConfig::BufferConfig & bufferConfig)26 bool PluginSessionManager::CheckBufferConfig(const ProfilerSessionConfig::BufferConfig& bufferConfig)
27 {
28     const uint32_t pages = bufferConfig.pages();
29     const auto policy = bufferConfig.policy();
30     return pages > 0 && pages <= MAX_BUFFER_PAGES &&
31            (policy == ProfilerSessionConfig::BufferConfig::RECYCLE ||
32             policy == ProfilerSessionConfig::BufferConfig::FLATTEN);
33 }
34 
CheckPluginSha256(const ProfilerPluginConfig & pluginConfig)35 bool PluginSessionManager::CheckPluginSha256(const ProfilerPluginConfig& pluginConfig)
36 {
37     std::string reqSha = pluginConfig.plugin_sha256();
38     if (reqSha.size() > 0) { // only check when SHA256 provided in request
39         auto pluginSvc = pluginService_.lock();
40         CHECK_NOTNULL(pluginSvc, false, "plugin service null!");
41 
42         PluginInfo info = {};
43         std::string name = pluginConfig.name();
44         CHECK_TRUE(pluginSvc->GetPluginInfo(name, info), false, "get plugin info %s failed!", name.c_str());
45 
46         std::string devSha = info.sha256;
47         CHECK_TRUE(devSha == reqSha, false, "SHA256 mismatch: %s, %s!", devSha.c_str(), reqSha.c_str());
48     }
49     return true;
50 }
51 
CreatePluginSession(const ProfilerPluginConfig & pluginConfig,const ProfilerSessionConfig::BufferConfig & bufferConfig,const ProfilerDataRepeaterPtr & dataRepeater,const ProfilerStateRepeaterPtr & stateRepeater)52 PluginSessionPtr PluginSessionManager::CreatePluginSession(const ProfilerPluginConfig& pluginConfig,
53                                                            const ProfilerSessionConfig::BufferConfig& bufferConfig,
54                                                            const ProfilerDataRepeaterPtr& dataRepeater,
55                                                            const ProfilerStateRepeaterPtr& stateRepeater)
56 {
57     auto name = pluginConfig.name();
58     CHECK_TRUE(pluginSessions_.count(name) == 0, nullptr, "plugin name %s exists!", name.c_str());
59     CHECK_TRUE(CheckBufferConfig(bufferConfig), nullptr, "buffer config invalid!");
60     CHECK_TRUE(CheckPluginSha256(pluginConfig), nullptr, "SHA256 check failed!");
61 
62     auto session = std::make_shared<PluginSession>(pluginConfig, bufferConfig, pluginService_,
63                                                    dataRepeater, stateRepeater);
64     CHECK_NOTNULL(session, nullptr, "allocate plugin session for %s failed!", name.c_str());
65     CHECK_TRUE(session->IsAvailable(), nullptr, "config plugin for %s failed!", name.c_str());
66     return session;
67 }
68 
CreatePluginSession(const ProfilerPluginConfig & pluginConfig,const ProfilerDataRepeaterPtr & dataRepeater,const ProfilerStateRepeaterPtr & stateRepeater)69 PluginSessionPtr PluginSessionManager::CreatePluginSession(const ProfilerPluginConfig& pluginConfig,
70                                                            const ProfilerDataRepeaterPtr& dataRepeater,
71                                                            const ProfilerStateRepeaterPtr& stateRepeater)
72 {
73     auto name = pluginConfig.name();
74     CHECK_TRUE(pluginSessions_.count(name) == 0, nullptr, "plugin name %s exists!", name.c_str());
75     CHECK_TRUE(CheckPluginSha256(pluginConfig), nullptr, "SHA256 check failed!");
76 
77     auto session = std::make_shared<PluginSession>(pluginConfig, pluginService_, dataRepeater, stateRepeater);
78     CHECK_NOTNULL(session, nullptr, "allocate plugin session for %s failed!", name.c_str());
79     CHECK_TRUE(session->IsAvailable(), nullptr, "config plugin for %s failed!", name.c_str());
80     return session;
81 }
82 
CreatePluginSessions(const std::vector<ProfilerPluginConfig> & pluginConfigs,const std::vector<ProfilerSessionConfig::BufferConfig> & bufferConfigs,const ProfilerDataRepeaterPtr & dataRepeater,const ProfilerStateRepeaterPtr & stateRepeater)83 bool PluginSessionManager::CreatePluginSessions(const std::vector<ProfilerPluginConfig>& pluginConfigs,
84                                                 const std::vector<ProfilerSessionConfig::BufferConfig>& bufferConfigs,
85                                                 const ProfilerDataRepeaterPtr& dataRepeater,
86                                                 const ProfilerStateRepeaterPtr& stateRepeater)
87 {
88     CHECK_TRUE(pluginConfigs.size() == bufferConfigs.size(), false, "buffer and config vector size mismatch %zu, %zu",
89                bufferConfigs.size(), pluginConfigs.size());
90 
91     std::map<std::string, PluginSessionPtr> tmpPluginSessions;
92     for (size_t i = 0; i < pluginConfigs.size(); i++) {
93         auto session = CreatePluginSession(pluginConfigs[i], bufferConfigs[i], dataRepeater, stateRepeater);
94 
95         // tmpPluginSessions will released if some plugin session create failed
96         CHECK_NOTNULL(session, false, "create plugin-%zu session failed!", i);
97         tmpPluginSessions[pluginConfigs[i].name()] = session;
98     }
99 
100     // insert all plugin session to pluginSessions_ map
101     std::unique_lock<std::mutex> lock(mutex_);
102     for (auto& entry : tmpPluginSessions) {
103         pluginSessions_.insert(entry);
104     }
105     return true;
106 }
107 
CreatePluginSessions(const std::vector<ProfilerPluginConfig> & pluginConfigs,const ProfilerDataRepeaterPtr & dataRepeater,const ProfilerStateRepeaterPtr & stateRepeater)108 bool PluginSessionManager::CreatePluginSessions(const std::vector<ProfilerPluginConfig>& pluginConfigs,
109                                                 const ProfilerDataRepeaterPtr& dataRepeater,
110                                                 const ProfilerStateRepeaterPtr& stateRepeater)
111 {
112     std::map<std::string, PluginSessionPtr> tmpPluginSessions;
113     for (size_t i = 0; i < pluginConfigs.size(); i++) {
114         auto session = CreatePluginSession(pluginConfigs[i], dataRepeater, stateRepeater);
115 
116         // tmpPluginSessions will released if some plugin session create failed
117         CHECK_NOTNULL(session, false, "create plugin-%zu session without shmem buffer failed!", i);
118         tmpPluginSessions[pluginConfigs[i].name()] = session;
119     }
120 
121     // insert all plugin session to pluginSessions_ map
122     std::unique_lock<std::mutex> lock(mutex_);
123     for (auto& entry : tmpPluginSessions) {
124         pluginSessions_.insert(entry);
125     }
126     return true;
127 }
128 
RemovePluginSessions(const std::vector<std::string> & nameList)129 bool PluginSessionManager::RemovePluginSessions(const std::vector<std::string>& nameList)
130 {
131     CHECK_TRUE(nameList.size() > 0, false, "nameList empty!");
132     std::unique_lock<std::mutex> lock(mutex_);
133     for (auto& name : nameList) {
134         auto it = pluginSessions_.find(name);
135         if (it == pluginSessions_.end()) {
136             continue;
137         }
138         pluginSessions_.erase(it);
139     }
140     return true;
141 }
142 
InvalidatePluginSessions(const std::vector<std::string> & nameList)143 bool PluginSessionManager::InvalidatePluginSessions(const std::vector<std::string>& nameList)
144 {
145     CHECK_TRUE(nameList.size() > 0, false, "nameList empty!");
146     std::unique_lock<std::mutex> lock(mutex_);
147     for (auto& name : nameList) {
148         auto it = pluginSessions_.find(name);
149         if (it == pluginSessions_.end()) {
150             continue;
151         }
152         it->second->Invalidate();
153     }
154     return true;
155 }
156 
StartPluginSessions(const std::vector<std::string> & nameList)157 bool PluginSessionManager::StartPluginSessions(const std::vector<std::string>& nameList)
158 {
159     CHECK_TRUE(nameList.size() > 0, false, "nameList empty!");
160     pluginNameList_ = std::move(nameList);
161     // start each plugin sessions
162     size_t failureCount = 0;
163     std::unique_lock<std::mutex> lock(mutex_);
164     for (auto& name : nameList) {
165         auto it = pluginSessions_.find(name);
166         if (it == pluginSessions_.end()) {
167             continue;
168         }
169         if (!it->second->Start()) {
170             PROFILER_LOG_INFO(LOG_CORE, "start session %s FAILED!", it->first.c_str());
171             failureCount++;
172         }
173     }
174     return failureCount == 0;
175 }
176 
StopPluginSessions(const std::vector<std::string> & nameList)177 bool PluginSessionManager::StopPluginSessions(const std::vector<std::string>& nameList)
178 {
179     // stop each plugin sessions
180     size_t failureCount = 0;
181     std::unique_lock<std::mutex> lock(mutex_);
182     for (auto& name : nameList) {
183         auto it = pluginSessions_.find(name);
184         if (it == pluginSessions_.end()) {
185             continue;
186         }
187         if (!it->second->Stop()) {
188             PROFILER_LOG_INFO(LOG_CORE, "stop session %s FAILED!", it->first.c_str());
189             failureCount++;
190         }
191     }
192     return failureCount == 0;
193 }
194 
RefreshPluginSession()195 bool PluginSessionManager::RefreshPluginSession()
196 {
197     size_t failureCount = 0;
198     std::unique_lock<std::mutex> lock(mutex_);
199     for (auto& name : pluginNameList_) {
200         auto it = pluginSessions_.find(name);
201         if (it == pluginSessions_.end()) {
202             continue;
203         }
204         if (!it->second->Refresh()) {
205             PROFILER_LOG_INFO(LOG_CORE, "refresh data %s FAILED!", it->first.c_str());
206             failureCount++;
207         }
208     }
209     return failureCount == 0;
210 }
211 
CheckStatus(const std::vector<std::string> & nameList,PluginSession::State state)212 bool PluginSessionManager::CheckStatus(const std::vector<std::string>& nameList, PluginSession::State state)
213 {
214     std::unique_lock<std::mutex> lock(mutex_);
215     for (auto& name : nameList) {
216         auto it = pluginSessions_.find(name);
217         if (it == pluginSessions_.end()) {
218             continue;
219         }
220         auto actualState = it->second->GetState();
221         if (actualState != state) {
222             PROFILER_LOG_INFO(LOG_CORE, "plugin %s state is %d not %d!", it->first.c_str(), actualState, state);
223             return false;
224         }
225     }
226     return true;
227 }
228 
GetStatus(const std::vector<std::string> & nameList)229 std::vector<PluginSession::State> PluginSessionManager::GetStatus(const std::vector<std::string>& nameList)
230 {
231     std::vector<PluginSession::State> status;
232     std::unique_lock<std::mutex> lock(mutex_);
233     for (auto& name : nameList) {
234         auto it = pluginSessions_.find(name);
235         if (it == pluginSessions_.end()) {
236             continue;
237         }
238         status.push_back(it->second->GetState());
239     }
240     return status;
241 }
242