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