• 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     // start each plugin sessions
156     size_t failureCount = 0;
157     std::unique_lock<std::mutex> lock(mutex_);
158     for (auto& name : nameList) {
159         auto it = pluginSessions_.find(name);
160         if (it == pluginSessions_.end()) {
161             continue;
162         }
163         if (!it->second->Start()) {
164             HILOG_INFO(LOG_CORE, "start session %s FAILED!", it->first.c_str());
165             failureCount++;
166         }
167     }
168     return failureCount == 0;
169 }
170 
StopPluginSessions(const std::vector<std::string> & nameList)171 bool PluginSessionManager::StopPluginSessions(const std::vector<std::string>& nameList)
172 {
173     // stop each plugin sessions
174     size_t failureCount = 0;
175     std::unique_lock<std::mutex> lock(mutex_);
176     for (auto& name : nameList) {
177         auto it = pluginSessions_.find(name);
178         if (it == pluginSessions_.end()) {
179             continue;
180         }
181         if (!it->second->Stop()) {
182             HILOG_INFO(LOG_CORE, "stop session %s FAILED!", it->first.c_str());
183             failureCount++;
184         }
185     }
186     return failureCount == 0;
187 }
188 
CheckStatus(const std::vector<std::string> & nameList,PluginSession::State state)189 bool PluginSessionManager::CheckStatus(const std::vector<std::string>& nameList, PluginSession::State state)
190 {
191     std::unique_lock<std::mutex> lock(mutex_);
192     for (auto& name : nameList) {
193         auto it = pluginSessions_.find(name);
194         if (it == pluginSessions_.end()) {
195             continue;
196         }
197         auto actualState = it->second->GetState();
198         if (actualState != state) {
199             HILOG_INFO(LOG_CORE, "plugin %s state is %d not %d!", it->first.c_str(), actualState, state);
200             return false;
201         }
202     }
203     return true;
204 }
205 
GetStatus(const std::vector<std::string> & nameList)206 std::vector<PluginSession::State> PluginSessionManager::GetStatus(const std::vector<std::string>& nameList)
207 {
208     std::vector<PluginSession::State> status;
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         status.push_back(it->second->GetState());
216     }
217     return status;
218 }
219