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 * Description: ftrace plugin module implements
16 */
17#include "ftrace_module.h"
18#include <memory>
19#include <mutex>
20
21#include "flow_controller.h"
22#include "logging.h"
23
24namespace {
25constexpr uint32_t MAX_BUFFER_SIZE = 4 * 1024 * 1024;
26
27std::mutex g_mutex;
28std::unique_ptr<FTRACE_NS::FlowController> g_mainController;
29} // namespace
30
31int TracePluginRegisterWriter(const WriterStruct* writer)
32{
33    std::unique_lock<std::mutex> lock(g_mutex);
34    g_mainController = std::make_unique<FTRACE_NS::FlowController>();
35
36    int result = g_mainController->SetWriter(const_cast<WriterStructPtr>(writer));
37    PROFILER_LOG_INFO(LOG_CORE, "%s: %d", __func__, __LINE__);
38    return result;
39}
40
41int TracePluginStartSession(const uint8_t configData[], const uint32_t configSize)
42{
43    std::unique_lock<std::mutex> lock(g_mutex);
44    CHECK_NOTNULL(g_mainController, -1, "%s: no FlowController created!", __func__);
45
46    PROFILER_LOG_INFO(LOG_CORE, "%s: %d", __func__, __LINE__);
47    int retval = g_mainController->LoadConfig(configData, configSize);
48    CHECK_TRUE(retval == 0, retval, "LoadConfig failed!");
49
50    PROFILER_LOG_INFO(LOG_CORE, "%s: %d", __func__, __LINE__);
51    int result = g_mainController->StartCapture();
52    PROFILER_LOG_INFO(LOG_CORE, "%s: %d", __func__, __LINE__);
53    return result;
54}
55
56int TracePluginReportBasicData()
57{
58    std::unique_lock<std::mutex> lock(g_mutex);
59    CHECK_NOTNULL(g_mainController, -1, "%s: no FlowController created!", __func__);
60
61    PROFILER_LOG_INFO(LOG_CORE, "%s: %d", __func__, __LINE__);
62    g_mainController->SetReportBasicData(true);
63    PROFILER_LOG_INFO(LOG_CORE, "%s: %d", __func__, __LINE__);
64    return 0;
65}
66
67int TracePluginStopSession()
68{
69    std::unique_lock<std::mutex> lock(g_mutex);
70    CHECK_NOTNULL(g_mainController, -1, "%s: no FlowController created!", __func__);
71
72    PROFILER_LOG_INFO(LOG_CORE, "%s: %d", __func__, __LINE__);
73    int result = g_mainController->StopCapture();
74    PROFILER_LOG_INFO(LOG_CORE, "%s: %d", __func__, __LINE__);
75
76    g_mainController.reset();
77    return result;
78}
79
80static PluginModuleCallbacks moduleCallbacks = {
81    .onPluginSessionStart = TracePluginStartSession,
82    .onPluginReportResult = 0,
83    .onPluginSessionStop = TracePluginStopSession,
84    .onRegisterWriterStruct = TracePluginRegisterWriter,
85    .onReportBasicDataCallback = TracePluginReportBasicData, // report ftrace_plugin basic data
86};
87
88EXPORT_API PluginModuleStruct g_pluginModule = {
89    .callbacks = &moduleCallbacks,
90    .name = "ftrace-plugin",
91    .version = "1.02",
92    .resultBufferSizeHint = MAX_BUFFER_SIZE,
93};
94