mirror of
https://gitee.com/openharmony/developtools_profiler
synced 2024-11-23 06:50:12 +00:00
add cpu and application trace profiler
Signed-off-by: chuxuezhe11 <hanjixiao@huawei.com>
This commit is contained in:
parent
a9c998f416
commit
7490667f64
11
OAT.xml
Executable file → Normal file
11
OAT.xml
Executable file → Normal file
@ -59,9 +59,13 @@ Note:If the text contains special characters, please escape them according to th
|
||||
<filefilterlist>
|
||||
<filefilter name="defaultPolicyFilter" desc="Filters for compatibility,license header policies">
|
||||
<filteritem type="filepath" name="device/plugins/memory_plugin/test/utresources/proc/.*" desc="test resource file, no license header"/>
|
||||
<filteritem type="filepath" name="device/plugins/cpu_plugin/test/resources/.*" desc="test resource file, no license header"/>
|
||||
<filteritem type="filepath" name="trace_analyzer/prebuilts/mac/trace_streamer.app/Contents/Resources/empty.lproj" desc="auto generated resource file for mac app, no license header"/>
|
||||
</filefilter>
|
||||
<filefilter name="copyrightPolicyFilter" desc="Filters for copyright header policies" >
|
||||
<filteritem type="filepath" name="device/plugins/memory_plugin/test/utresources/proc/.*" desc="test resource file, no copyright header"/>
|
||||
<filteritem type="filepath" name="device/plugins/cpu_plugin/test/resources/.*" desc="test resource file, no copyright header"/>
|
||||
<filteritem type="filepath" name="trace_analyzer/prebuilts/mac/trace_streamer.app/Contents/Resources/empty.lproj" desc="auto generated resource file for mac app, no copyright header"/>
|
||||
</filefilter>
|
||||
<filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies" >
|
||||
<filteritem type="filepath" name="host/ohosprofiler/src/main/resources/trace.db" desc="the binary file for host, the file is self-developed"/>
|
||||
@ -70,6 +74,13 @@ Note:If the text contains special characters, please escape them according to th
|
||||
<filteritem type="filepath" name="host/ohosprofiler/src/main/resources/.*.png" desc="the png file for host, the file is self-developed"/>
|
||||
<filteritem type="filepath" name="host/ohosprofiler/src/main/resources/.*.gif" desc="the gif file for host, the file is self-developed"/>
|
||||
<filteritem type="filepath" name="figures/zh-cn_image_0000001162598155.png" desc="the png file for readme, the file is self-developed"/>
|
||||
<filteritem type="filepath" name="trace_analyzer/prebuilts/trace_streamer.exe" desc="the trace_streamer.exe executable file, the file is self-developed"/>
|
||||
<filteritem type="filepath" name="trace_analyzer/test/resource/htrace.bin" desc="the trace_streamer test file, the file is self-developed"/>
|
||||
<filteritem type="filepath" name="trace_analyzer/prebuilts/windows/trace_streamer.exe" desc="the trace_streamer.exe executable file, the file is self-developed"/>
|
||||
<filteritem type="filepath" name="trace_analyzer/test/resource/htrace_gold.db" desc="the trace_streamer test file, the file is self-developed"/>
|
||||
<filteritem type="filepath" name="trace_analyzer/prebuilts/mac/trace_streamer.app/Contents/MacOS/trace_streamer" desc="the trace_streamer executable file for mac, the file is self-developed"/>
|
||||
<filteritem type="filepath" name="trace_analyzer/test/resource/ut_bytrace_input_thread_gold.db" desc="the trace_streamer test file, the file is self-developed"/>
|
||||
<filteritem type="filepath" name="trace_analyzer/test/resource/ut_bytrace_input_full_gold.db" desc="the trace_streamer test file, the file is self-developed"/>
|
||||
</filefilter>
|
||||
</filefilterlist>
|
||||
</oatconfig>
|
||||
|
@ -14,8 +14,7 @@
|
||||
OHOS_PROFILER_DIR = get_path_info("..", "abspath")
|
||||
OHOS_PROFILER_3RDPARTY_DIR = get_path_info("../../../third_party/", "abspath")
|
||||
OHOS_PROFILER_3RDPARTY_GRPC_DIR = "${OHOS_PROFILER_3RDPARTY_DIR}/grpc"
|
||||
OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR =
|
||||
"${OHOS_PROFILER_3RDPARTY_DIR}/protobuf"
|
||||
OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR = "${OHOS_PROFILER_3RDPARTY_DIR}/protobuf"
|
||||
OHOS_PROFILER_3RDPARTY_GOOGLETEST_DIR =
|
||||
"${OHOS_PROFILER_3RDPARTY_DIR}/googletest"
|
||||
|
||||
@ -31,5 +30,7 @@ print("build_l2 =", build_l2)
|
||||
print("OHOS_PROFILER_DIR = ", OHOS_PROFILER_DIR)
|
||||
print("OHOS_PROFILER_3RDPARTY_DIR = ", OHOS_PROFILER_3RDPARTY_DIR)
|
||||
print("OHOS_PROFILER_3RDPARTY_GRPC_DIR = ", OHOS_PROFILER_3RDPARTY_GRPC_DIR)
|
||||
print("OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR = ", OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR)
|
||||
print("OHOS_PROFILER_3RDPARTY_GOOGLETEST_DIR", OHOS_PROFILER_3RDPARTY_GOOGLETEST_DIR)
|
||||
print("OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR = ",
|
||||
OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR)
|
||||
print("OHOS_PROFILER_3RDPARTY_GOOGLETEST_DIR",
|
||||
OHOS_PROFILER_3RDPARTY_GOOGLETEST_DIR)
|
||||
|
5
device/BUILD.gn
Executable file → Normal file
5
device/BUILD.gn
Executable file → Normal file
@ -17,10 +17,12 @@ group("hiprofiler_targets") {
|
||||
deps = [
|
||||
"cmds:hiprofiler_cmd",
|
||||
"plugins/api:hiprofiler_plugins",
|
||||
"plugins/bytrace_plugin:bytraceplugin",
|
||||
"plugins/cpu_plugin:cpudataplugin",
|
||||
"plugins/cpu_plugin:cpudataplugintest",
|
||||
"plugins/memory_plugin:memdataplugin",
|
||||
"services/profiler_service:hiprofilerd",
|
||||
"services/shared_memory:shared_memory",
|
||||
"plugins/bytrace_plugin:bytraceplugin",
|
||||
]
|
||||
}
|
||||
|
||||
@ -29,6 +31,7 @@ group("unittest") {
|
||||
deps = [
|
||||
"base/test:unittest",
|
||||
"plugins/api/test:unittest",
|
||||
"plugins/cpu_plugin/test:unittest",
|
||||
"plugins/memory_plugin/test:unittest",
|
||||
"services/ipc/test:unittest",
|
||||
"services/plugin_service/test:unittest",
|
||||
|
11
device/base/BUILD.gn
Executable file → Normal file
11
device/base/BUILD.gn
Executable file → Normal file
@ -21,7 +21,7 @@ config("hiprofiler_test_config") {
|
||||
cflags += [ "-g" ]
|
||||
}
|
||||
|
||||
if (enable_coverage && current_toolchain == host_toolchain) {
|
||||
if (enable_coverage) {
|
||||
cflags += [
|
||||
# clang coverage options:
|
||||
"--coverage",
|
||||
@ -36,19 +36,26 @@ config("hiprofiler_test_config") {
|
||||
config("hiprofiler_base_config") {
|
||||
include_dirs = [
|
||||
"include",
|
||||
"//utils/native/base/include"
|
||||
"//utils/native/base/include",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_source_set("hiprofiler_base") {
|
||||
sources = [
|
||||
"src/epoll_event_poller.cpp",
|
||||
"src/event_notifier.cpp",
|
||||
"src/i_semaphore.cpp",
|
||||
"src/posix_semaphore.cpp",
|
||||
"src/pthread_semaphore.cpp",
|
||||
"src/schedule_task_manager.cpp",
|
||||
"src/std_semaphore.cpp",
|
||||
]
|
||||
|
||||
public_configs = [
|
||||
":hiprofiler_test_config",
|
||||
":hiprofiler_base_config",
|
||||
]
|
||||
public_deps = [ "//utils/native/base:utilsecurec" ]
|
||||
if (current_toolchain != host_toolchain) {
|
||||
defines = [ "HAVE_HILOG" ]
|
||||
if (build_l2) {
|
||||
|
0
device/base/config.gni
Executable file → Normal file
0
device/base/config.gni
Executable file → Normal file
83
device/base/include/epoll_event_poller.h
Normal file
83
device/base/include/epoll_event_poller.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef EPOLL_EVENT_POLLER_H
|
||||
#define EPOLL_EVENT_POLLER_H
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include "nocopyable.h"
|
||||
|
||||
class EpollEventPoller {
|
||||
public:
|
||||
explicit EpollEventPoller(int timeOut);
|
||||
~EpollEventPoller();
|
||||
|
||||
using OnReadableCallback = std::function<void(void)>;
|
||||
using OnWritableCallback = std::function<void(void)>;
|
||||
|
||||
bool AddFileDescriptor(int fd, const OnReadableCallback& onReadable, const OnWritableCallback& onWritable = {});
|
||||
|
||||
bool RemoveFileDescriptor(int fd);
|
||||
|
||||
bool Init();
|
||||
bool Start();
|
||||
bool Stop();
|
||||
bool Finalize();
|
||||
|
||||
private:
|
||||
enum State {
|
||||
INITIAL,
|
||||
INITIED,
|
||||
STARTED,
|
||||
};
|
||||
static constexpr int INVALID_FD = -1;
|
||||
struct EventContext {
|
||||
int fd = INVALID_FD;
|
||||
OnReadableCallback onReadable;
|
||||
OnWritableCallback onWritable;
|
||||
};
|
||||
using EventContextPtr = std::shared_ptr<EventContext>;
|
||||
|
||||
void Run();
|
||||
bool UpdateEvent(int op, const EventContextPtr& ctx);
|
||||
void HandleEvent(int events, const EventContext& ctx);
|
||||
|
||||
bool AddContextLocked(const EventContextPtr& ctx);
|
||||
bool RemoveContextLocked(const EventContextPtr& ctx);
|
||||
|
||||
void OnNotify();
|
||||
bool Notify(uint64_t value = 1);
|
||||
|
||||
private:
|
||||
std::mutex mutex_;
|
||||
std::mutex vecMutex_;
|
||||
std::thread pollThread_;
|
||||
int timeOut_ = 0;
|
||||
int epollFd_ = INVALID_FD;
|
||||
int eventFd_ = INVALID_FD;
|
||||
std::atomic<int> state_ = INITIAL;
|
||||
std::atomic<bool> running_ = false;
|
||||
std::vector<int> fileDescriptors_;
|
||||
std::unordered_map<int, EventContextPtr> context_;
|
||||
|
||||
DISALLOW_COPY_AND_MOVE(EpollEventPoller);
|
||||
};
|
||||
#endif // EPOLL_EVENT_POLLER_H
|
55
device/base/include/event_notifier.h
Normal file
55
device/base/include/event_notifier.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef EVENT_NOTIFIER_H
|
||||
#define EVENT_NOTIFIER_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include "nocopyable.h"
|
||||
|
||||
class EventNotifier;
|
||||
|
||||
using EventNotifierPtr = std::shared_ptr<EventNotifier>;
|
||||
|
||||
class EventNotifier {
|
||||
public:
|
||||
enum {
|
||||
NONBLOCK = (1u << 0),
|
||||
SEMAPHORE = (1u << 1),
|
||||
};
|
||||
|
||||
static EventNotifierPtr Create(unsigned int initValue = 0, unsigned int mask = 0);
|
||||
static EventNotifierPtr CreateWithFd(int fd);
|
||||
|
||||
int GetFd() const;
|
||||
|
||||
bool IsNonBlocking() const;
|
||||
bool IsSemaphore() const;
|
||||
|
||||
uint64_t Take() const;
|
||||
bool Post(uint64_t value) const;
|
||||
|
||||
EventNotifier(unsigned int initValue, unsigned int mask);
|
||||
EventNotifier(int fd);
|
||||
~EventNotifier();
|
||||
|
||||
private:
|
||||
int fd_;
|
||||
int flags_;
|
||||
|
||||
DISALLOW_COPY_AND_MOVE(EventNotifier);
|
||||
};
|
||||
|
||||
#endif // EVENT_NOTIFIER_H
|
45
device/base/include/i_semaphore.h
Normal file
45
device/base/include/i_semaphore.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef OHOS_PROFILER_ABSTRACT_SEMAPHORE_H
|
||||
#define OHOS_PROFILER_ABSTRACT_SEMAPHORE_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class ISemaphore {
|
||||
public:
|
||||
virtual ~ISemaphore() {}
|
||||
virtual bool Wait() = 0;
|
||||
virtual bool TryWait() = 0;
|
||||
bool TimedWait(int seconds)
|
||||
{
|
||||
return TimedWait(seconds, 0);
|
||||
}
|
||||
virtual bool TimedWait(int seconds, int nanoSeconds) = 0;
|
||||
virtual bool Post() = 0;
|
||||
virtual unsigned int Value() const = 0;
|
||||
};
|
||||
using SemaphorePtr = std::shared_ptr<ISemaphore>;
|
||||
|
||||
enum SemaphoreFactoryType : int { STD_SEMAPHORE_FACTORY, POSIX_SEMAPHORE_FACTORY, PTHREAD_SEMAPHORE_FACTORY };
|
||||
|
||||
class ISemaphoreFactory {
|
||||
public:
|
||||
virtual SemaphorePtr Create(unsigned int value) = 0;
|
||||
};
|
||||
|
||||
ISemaphoreFactory& GetSemaphoreFactory(SemaphoreFactoryType type = STD_SEMAPHORE_FACTORY);
|
||||
|
||||
#endif // OHOS_PROFILER_ABSTRACT_SEMAPHORE_H
|
168
device/base/include/logging.h
Executable file → Normal file
168
device/base/include/logging.h
Executable file → Normal file
@ -13,44 +13,52 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef LOGGING_H
|
||||
#define LOGGING_H
|
||||
#ifndef OHOS_PROFILER_LOGGING_H
|
||||
#define OHOS_PROFILER_LOGGING_H
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
#ifndef LOG_TAG
|
||||
#define LOG_TAG ""
|
||||
#define LOG_TAG "Hiprofiler"
|
||||
#endif
|
||||
|
||||
#define PROFILER_SUBSYSTEM 0x0000
|
||||
#ifndef LOG_DOMAIN
|
||||
#define LOG_DOMAIN PROFILER_SUBSYSTEM
|
||||
#endif
|
||||
|
||||
#ifndef UNUSED_PARAMETER
|
||||
#define UNUSED_PARAMETER(x) ((void)x)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HILOG
|
||||
#include "hilog/log.h"
|
||||
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "Hiprofiler"
|
||||
|
||||
#else
|
||||
#include <string>
|
||||
#else // HAVE_HILOG
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <securec.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
static inline long GetTid()
|
||||
static inline long GetTid(void)
|
||||
{
|
||||
return syscall(SYS_gettid);
|
||||
}
|
||||
|
||||
enum {
|
||||
HILOG_UNKNOWN = 0,
|
||||
HILOG_DEFAULT,
|
||||
HILOG_VERBOSE,
|
||||
HILOG_DEBUG,
|
||||
HILOG_INFO,
|
||||
HILOG_WARN,
|
||||
HILOG_ERROR,
|
||||
HILOG_FATAL,
|
||||
HILOG_SILENT,
|
||||
LOG_UNKNOWN = 0,
|
||||
LOG_DEFAULT,
|
||||
LOG_VERBOSE,
|
||||
LOG_DEBUG,
|
||||
LOG_INFO,
|
||||
LOG_WARN,
|
||||
LOG_ERROR,
|
||||
LOG_FATAL,
|
||||
LOG_SILENT,
|
||||
};
|
||||
|
||||
namespace {
|
||||
@ -66,60 +74,136 @@ static inline std::string GetTimeStr()
|
||||
localtime_r(&ts.tv_sec, &tmStruct);
|
||||
size_t used = strftime(timeStr, sizeof(timeStr), "%m-%d %H:%M:%S", &tmStruct);
|
||||
snprintf_s(&timeStr[used], sizeof(timeStr) - used, sizeof(timeStr) - used - 1, ".%03ld",
|
||||
ts.tv_nsec / NS_PER_MS_LOG);
|
||||
ts.tv_nsec / NS_PER_MS_LOG);
|
||||
return timeStr;
|
||||
}
|
||||
|
||||
typedef const char *ConstCharPtr;
|
||||
typedef const char* ConstCharPtr;
|
||||
|
||||
static inline int HiLogPrintArgs(int prio, ConstCharPtr tag, ConstCharPtr fmt, va_list vargs)
|
||||
static inline int HiLogPrintArgs(int prio, int domain, ConstCharPtr tag, ConstCharPtr fmt, va_list vargs)
|
||||
{
|
||||
static std::mutex mtx;
|
||||
static std::vector<std::string> prioNames = {"U", " ", "V", "D", "I", "W", "E", "F", "S"};
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
int count =
|
||||
fprintf(stderr, "%s %7d %7ld %5s %s ", GetTimeStr().c_str(), getpid(), GetTid(), prioNames[prio].c_str(), tag);
|
||||
int count = fprintf(stderr, "%04x %s %7d %7ld %5s %s ", domain, GetTimeStr().c_str(), getpid(), GetTid(),
|
||||
prioNames[prio].c_str(), tag);
|
||||
if (count < 0) {
|
||||
return 0;
|
||||
}
|
||||
count += vfprintf(stderr, fmt, vargs);
|
||||
count += fprintf(stderr, "\n");
|
||||
fflush(stderr);
|
||||
return count;
|
||||
}
|
||||
|
||||
static inline int __hilog_log_print(int prio, ConstCharPtr tag, ConstCharPtr fmt, ...)
|
||||
static inline int HiLogPrint(int type, int prio, int domain, ConstCharPtr tag, ConstCharPtr fmt, ...)
|
||||
{
|
||||
int count;
|
||||
int count = 0;
|
||||
va_list vargs;
|
||||
|
||||
UNUSED_PARAMETER(type);
|
||||
va_start(vargs, fmt);
|
||||
count = HiLogPrintArgs(prio, tag, fmt, vargs);
|
||||
count = HiLogPrintArgs(prio, domain, tag, fmt, vargs);
|
||||
va_end(vargs);
|
||||
return count;
|
||||
}
|
||||
|
||||
#define HILOG_DEBUG(LOG_CORE, fmt, ...) __hilog_log_print(HILOG_DEBUG, LOG_TAG, fmt, ##__VA_ARGS__)
|
||||
#define HILOG_INFO(LOG_CORE, fmt, ...) __hilog_log_print(HILOG_INFO, LOG_TAG, fmt, ##__VA_ARGS__)
|
||||
#define HILOG_WARN(LOG_CORE, fmt, ...) __hilog_log_print(HILOG_WARN, LOG_TAG, fmt, ##__VA_ARGS__)
|
||||
#define HILOG_ERROR(LOG_CORE, fmt, ...) __hilog_log_print(HILOG_ERROR, LOG_TAG, fmt, ##__VA_ARGS__)
|
||||
|
||||
#ifndef LOG_CORE
|
||||
#define LOG_CORE 0
|
||||
#endif
|
||||
|
||||
#define HILOG_DEBUG(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_DEBUG, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
|
||||
#define HILOG_INFO(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_INFO, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
|
||||
#define HILOG_WARN(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_WARN, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
|
||||
#define HILOG_ERROR(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_ERROR, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
|
||||
|
||||
#endif // HAVE_HILOG
|
||||
|
||||
#ifndef NDEBUG
|
||||
#include <securec.h>
|
||||
namespace logging {
|
||||
inline void StringReplace(std::string& str, const std::string& oldStr, const std::string& newStr)
|
||||
{
|
||||
std::string::size_type pos = 0u;
|
||||
while ((pos = str.find(oldStr, pos)) != std::string::npos) {
|
||||
str.replace(pos, oldStr.length(), newStr);
|
||||
pos += newStr.length();
|
||||
}
|
||||
}
|
||||
|
||||
static inline std::string StringFormat(const char* fmt, ...)
|
||||
{
|
||||
va_list vargs;
|
||||
char buf[1024] = {0};
|
||||
std::string format(fmt);
|
||||
StringReplace(format, "%{public}", "%");
|
||||
|
||||
va_start(vargs, fmt);
|
||||
if (vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format.c_str(), vargs) < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
va_end(vargs);
|
||||
return buf;
|
||||
}
|
||||
} // logging
|
||||
|
||||
#ifdef HILOG_DEBUG
|
||||
#undef HILOG_DEBUG
|
||||
#endif
|
||||
|
||||
#ifdef HILOG_INFO
|
||||
#undef HILOG_INFO
|
||||
#endif
|
||||
|
||||
#ifdef HILOG_WARN
|
||||
#undef HILOG_WARN
|
||||
#endif
|
||||
|
||||
#ifdef HILOG_ERROR
|
||||
#undef HILOG_ERROR
|
||||
#endif
|
||||
|
||||
#ifdef HILOG_PRINT
|
||||
#undef HILOG_PRINT
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HILOG
|
||||
#define HILOG_PRINT(type, level, fmt, ...) \
|
||||
HiLogPrint(type, level, LOG_DOMAIN, LOG_TAG, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str())
|
||||
#else
|
||||
#define HILOG_PRINT(type, level, fmt, ...) \
|
||||
HiLogPrint(type, level, LOG_DOMAIN, LOG_TAG, "%s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str())
|
||||
#endif
|
||||
|
||||
#define HILOG_DEBUG(type, fmt, ...) HILOG_PRINT(type, LOG_DEBUG, fmt, ##__VA_ARGS__)
|
||||
#define HILOG_INFO(type, fmt, ...) HILOG_PRINT(type, LOG_INFO, fmt, ##__VA_ARGS__)
|
||||
#define HILOG_WARN(type, fmt, ...) HILOG_PRINT(type, LOG_WARN, fmt, ##__VA_ARGS__)
|
||||
#define HILOG_ERROR(type, fmt, ...) HILOG_PRINT(type, LOG_ERROR, fmt, ##__VA_ARGS__)
|
||||
#endif // NDEBUG
|
||||
|
||||
#define STD_PTR(K, T) std::K##_ptr<T>
|
||||
|
||||
#define CHECK_NOTNULL(ptr, retval, fmt, ...) \
|
||||
do { \
|
||||
if (ptr == nullptr) { \
|
||||
HILOG_WARN(LOG_CORE, "CHECK_NOTNULL(%s) in %s:%d FAILED, " fmt, #ptr, __func__, __LINE__, ##__VA_ARGS__); \
|
||||
return retval; \
|
||||
} \
|
||||
} while (0)
|
||||
#define NO_RETVAL /* retval */
|
||||
|
||||
#define CHECK_TRUE(expr, retval, fmt, ...) \
|
||||
#define CHECK_NOTNULL(ptr, retval, fmt, ...) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
HILOG_WARN(LOG_CORE, "CHECK_TRUE(%s) in %s:%d FAILED, " fmt, #expr, __func__, __LINE__, ##__VA_ARGS__); \
|
||||
if (ptr == nullptr) { \
|
||||
HILOG_WARN(LOG_CORE, "CHECK_NOTNULL(%{public}s) in %{public}s:%{public}d FAILED, " fmt, #ptr, __func__, \
|
||||
__LINE__, ##__VA_ARGS__); \
|
||||
return retval; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_TRUE(expr, retval, fmt, ...) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
HILOG_WARN(LOG_CORE, "CHECK_TRUE(%{public}s) in %{public}s:%{public}d FAILED, " fmt, #expr, __func__, \
|
||||
__LINE__, ##__VA_ARGS__); \
|
||||
return retval; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RETURN_IF(expr, retval, fmt, ...) \
|
||||
do { \
|
||||
if ((expr)) { \
|
||||
|
@ -13,11 +13,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SCHEDULE_TASK_MANAGER_H
|
||||
#define SCHEDULE_TASK_MANAGER_H
|
||||
#ifndef OHOS_PROFILER_SCHEDULE_TASK_MANAGER_H
|
||||
#define OHOS_PROFILER_SCHEDULE_TASK_MANAGER_H
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@ -26,6 +27,7 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "logging.h"
|
||||
#include "nocopyable.h"
|
||||
|
||||
class ScheduleTaskManager {
|
||||
public:
|
||||
@ -58,7 +60,7 @@ private:
|
||||
std::function<void(void)> callback;
|
||||
std::chrono::milliseconds repeatInterval;
|
||||
std::chrono::milliseconds initialDelay;
|
||||
TimePoint lastRunTime;
|
||||
TimePoint nextRunTime;
|
||||
};
|
||||
using SharedTask = STD_PTR(shared, Task);
|
||||
using WeakTask = STD_PTR(weak, Task);
|
||||
@ -69,15 +71,17 @@ private:
|
||||
|
||||
void ScheduleThread();
|
||||
|
||||
bool TakeFront(TimePoint& time, WeakTask& task);
|
||||
WeakTask TakeFront();
|
||||
|
||||
private:
|
||||
mutable std::mutex taskMutex_;
|
||||
std::condition_variable taskCv_;
|
||||
std::atomic<bool> runScheduleThread_ = true;
|
||||
std::multimap<TimePoint, WeakTask> timeMap_;
|
||||
std::unordered_map<std::string, SharedTask> taskMap_;
|
||||
std::multimap<TimePoint, WeakTask> timeMap_; // schedule list
|
||||
std::unordered_map<std::string, SharedTask> taskMap_; // task details
|
||||
std::thread scheduleThread_;
|
||||
|
||||
DISALLOW_COPY_AND_MOVE(ScheduleTaskManager);
|
||||
};
|
||||
|
||||
#endif // !SCHEDULE_TASK_MANAGER_H
|
||||
#endif // !OHOS_PROFILER_SCHEDULE_TASK_MANAGER_H
|
248
device/base/src/epoll_event_poller.cpp
Normal file
248
device/base/src/epoll_event_poller.cpp
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "epoll_event_poller.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
EpollEventPoller::EpollEventPoller(int timeOut) : timeOut_(timeOut), epollFd_(INVALID_FD), eventFd_(INVALID_FD) {}
|
||||
|
||||
EpollEventPoller::~EpollEventPoller()
|
||||
{
|
||||
if (state_ == STARTED) {
|
||||
HILOG_INFO(LOG_CORE, "need Stop in destructor!");
|
||||
Stop();
|
||||
}
|
||||
if (state_ == INITIED) {
|
||||
HILOG_INFO(LOG_CORE, "need Finalize in dtor!");
|
||||
Finalize();
|
||||
}
|
||||
}
|
||||
|
||||
bool EpollEventPoller::AddFileDescriptor(int fd,
|
||||
const OnReadableCallback& onReadable,
|
||||
const OnWritableCallback& onWritable)
|
||||
{
|
||||
auto ctx = std::make_shared<EventContext>();
|
||||
CHECK_NOTNULL(ctx, false, "create EventContext FAILED!");
|
||||
ctx->fd = fd;
|
||||
ctx->onReadable = onReadable;
|
||||
ctx->onWritable = onWritable;
|
||||
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
CHECK_TRUE(AddContextLocked(ctx), false, "add context for %d failed!", fd);
|
||||
return Notify();
|
||||
}
|
||||
|
||||
bool EpollEventPoller::RemoveFileDescriptor(int fd)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
auto it = context_.find(fd);
|
||||
CHECK_TRUE(it != context_.end(), false, "fd %d not found in poll set!", fd);
|
||||
|
||||
auto ctx = it->second;
|
||||
CHECK_NOTNULL(ctx, false, "ctx null!");
|
||||
CHECK_TRUE(RemoveContextLocked(ctx), false, "remove context for %d failed!", fd);
|
||||
return Notify();
|
||||
}
|
||||
|
||||
bool EpollEventPoller::AddContextLocked(const EventContextPtr& ctx)
|
||||
{
|
||||
context_[ctx->fd] = ctx;
|
||||
return UpdateEvent(EPOLL_CTL_ADD, ctx);
|
||||
}
|
||||
|
||||
bool EpollEventPoller::RemoveContextLocked(const EventContextPtr& ctx)
|
||||
{
|
||||
context_.erase(ctx->fd);
|
||||
CHECK_TRUE(UpdateEvent(EPOLL_CTL_DEL, ctx), false, "update fd %d ctx FAILED!", ctx->fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string EpollOpName(int op)
|
||||
{
|
||||
if (op == EPOLL_CTL_ADD) {
|
||||
return "ADD";
|
||||
}
|
||||
if (op == EPOLL_CTL_DEL) {
|
||||
return "DEL";
|
||||
}
|
||||
if (op == EPOLL_CTL_MOD) {
|
||||
return "MOD";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool EpollEventPoller::UpdateEvent(int op, const EventContextPtr& ctx)
|
||||
{
|
||||
struct epoll_event event = {};
|
||||
if (ctx->onReadable) {
|
||||
event.events |= EPOLLIN;
|
||||
}
|
||||
if (ctx->onWritable) {
|
||||
event.events |= EPOLLOUT;
|
||||
}
|
||||
event.data.ptr = ctx.get();
|
||||
|
||||
std::string name = EpollOpName(op).c_str();
|
||||
HILOG_DEBUG(LOG_CORE, "poll set %s %d %x start!", name.c_str(), ctx->fd, event.events);
|
||||
int retval = epoll_ctl(epollFd_, op, ctx->fd, &event);
|
||||
CHECK_TRUE(retval == 0, false, "epoll_ctl %s failed, %s", name.c_str(), strerror(errno));
|
||||
HILOG_DEBUG(LOG_CORE, "poll set %s %d %x done!", name.c_str(), ctx->fd, event.events);
|
||||
return true;
|
||||
}
|
||||
|
||||
void EpollEventPoller::Run()
|
||||
{
|
||||
pthread_setname_np(pthread_self(), "EventPoller");
|
||||
std::vector<struct epoll_event> eventVec;
|
||||
while (running_) {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
eventVec.resize(context_.size());
|
||||
}
|
||||
int retval = TEMP_FAILURE_RETRY(epoll_wait(epollFd_, eventVec.data(), eventVec.size(), timeOut_));
|
||||
CHECK_TRUE(retval >= 0, NO_RETVAL, "epoll_wait failed, %s!", strerror(errno));
|
||||
if (retval == 0) {
|
||||
HILOG_INFO(LOG_CORE, "epoll_wait %dms timeout!", timeOut_);
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < retval; i++) {
|
||||
auto ctx = reinterpret_cast<EventContext*>(eventVec[i].data.ptr);
|
||||
if (ctx != nullptr) {
|
||||
HandleEvent(eventVec[i].events, *ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EpollEventPoller::HandleEvent(int events, const EventContext& ctx)
|
||||
{
|
||||
if (events & EPOLLIN) {
|
||||
if (ctx.onReadable) {
|
||||
ctx.onReadable();
|
||||
}
|
||||
} else if (events & EPOLLOUT) {
|
||||
if (ctx.onWritable) {
|
||||
ctx.onWritable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EpollEventPoller::OnNotify()
|
||||
{
|
||||
uint64_t value = 0;
|
||||
CHECK_TRUE(read(eventFd_, &value, sizeof(value)) == sizeof(value), NO_RETVAL, "read eventfd FAILED!");
|
||||
HILOG_DEBUG(LOG_CORE, "OnNotify %llu done!", static_cast<unsigned long long>(value));
|
||||
}
|
||||
|
||||
bool EpollEventPoller::Notify(uint64_t value)
|
||||
{
|
||||
auto nbytes = write(eventFd_, &value, sizeof(value));
|
||||
CHECK_TRUE(static_cast<size_t>(nbytes) == sizeof(value), false, "write eventfd FAILED!");
|
||||
HILOG_DEBUG(LOG_CORE, "Notify %llu done!", static_cast<unsigned long long>(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EpollEventPoller::Init()
|
||||
{
|
||||
HILOG_INFO(LOG_CORE, "Init %d", state_.load());
|
||||
CHECK_TRUE(state_ == INITIAL, false, "Init FAIL %d", state_.load());
|
||||
|
||||
int epollFd = epoll_create1(EPOLL_CLOEXEC);
|
||||
CHECK_TRUE(epollFd >= 0, false, "epoll_create failed, %s!", strerror(errno));
|
||||
fileDescriptors_.push_back(epollFd);
|
||||
|
||||
int eventFd = eventfd(0, O_CLOEXEC | O_NONBLOCK);
|
||||
CHECK_TRUE(eventFd >= 0, false, "create event fd failed, %s", strerror(errno));
|
||||
fileDescriptors_.push_back(eventFd);
|
||||
|
||||
auto eventFdCtx = std::make_shared<EventContext>();
|
||||
CHECK_NOTNULL(eventFdCtx, false, "create EventContext failed!");
|
||||
eventFdCtx->fd = eventFd;
|
||||
eventFdCtx->onReadable = std::bind(&EpollEventPoller::OnNotify, this);
|
||||
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
epollFd_ = epollFd;
|
||||
eventFd_ = eventFd;
|
||||
AddContextLocked(eventFdCtx);
|
||||
HILOG_INFO(LOG_CORE, "EpollEventPoller::Init %d done!", state_.load());
|
||||
state_ = INITIED;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EpollEventPoller::Finalize()
|
||||
{
|
||||
if (state_ == STARTED) {
|
||||
HILOG_INFO(LOG_CORE, "need Stop in Finalize!");
|
||||
Stop();
|
||||
}
|
||||
|
||||
HILOG_INFO(LOG_CORE, "Finalize %d", state_.load());
|
||||
CHECK_TRUE(state_ == INITIED, false, "Finalize FAIL %d", state_.load());
|
||||
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
std::vector<EventContextPtr> contextVec;
|
||||
for (auto& ctxPair : context_) {
|
||||
contextVec.push_back(ctxPair.second);
|
||||
}
|
||||
for (auto ctxPtr : contextVec) {
|
||||
HILOG_DEBUG(LOG_CORE, "remove context for %d", ctxPtr->fd);
|
||||
RemoveContextLocked(ctxPtr);
|
||||
}
|
||||
|
||||
for (int fd : fileDescriptors_) {
|
||||
close(fd);
|
||||
}
|
||||
fileDescriptors_.clear();
|
||||
|
||||
epollFd_ = INVALID_FD;
|
||||
eventFd_ = INVALID_FD;
|
||||
state_ = INITIAL;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EpollEventPoller::Start()
|
||||
{
|
||||
HILOG_INFO(LOG_CORE, "%s %d", __func__, state_.load());
|
||||
CHECK_TRUE(state_ == INITIED, false, "Start FAIL %d", state_.load());
|
||||
|
||||
running_ = true;
|
||||
pollThread_ = std::thread(&EpollEventPoller::Run, this);
|
||||
state_ = STARTED;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EpollEventPoller::Stop()
|
||||
{
|
||||
CHECK_TRUE(state_ == STARTED, false, "Stop FAIL %d", state_.load());
|
||||
|
||||
running_ = false;
|
||||
Notify();
|
||||
if (pollThread_.joinable()) {
|
||||
pollThread_.join();
|
||||
}
|
||||
state_ = INITIED;
|
||||
return true;
|
||||
}
|
94
device/base/src/event_notifier.cpp
Normal file
94
device/base/src/event_notifier.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "event_notifier.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <climits>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
#ifndef EFD_SEMAPHORE
|
||||
#define EFD_SEMAPHORE 1
|
||||
#endif
|
||||
|
||||
EventNotifierPtr EventNotifier::Create(unsigned int initValue, unsigned int mask)
|
||||
{
|
||||
return std::make_shared<EventNotifier>(initValue, mask);
|
||||
}
|
||||
|
||||
EventNotifierPtr EventNotifier::CreateWithFd(int fd)
|
||||
{
|
||||
return std::make_shared<EventNotifier>(fd);
|
||||
}
|
||||
|
||||
EventNotifier::EventNotifier(unsigned int initValue, unsigned int mask) : fd_(-1), flags_(O_CLOEXEC)
|
||||
{
|
||||
if (mask & NONBLOCK) {
|
||||
flags_ |= O_NONBLOCK;
|
||||
}
|
||||
if (mask & SEMAPHORE) {
|
||||
flags_ |= EFD_SEMAPHORE;
|
||||
}
|
||||
fd_ = eventfd(initValue, flags_);
|
||||
CHECK_TRUE(fd_ >= 0, NO_RETVAL, "create eventfd FAILED, %s", strerror(errno));
|
||||
HILOG_DEBUG(LOG_CORE, "EventNotifier create eventfd %d done!", fd_);
|
||||
}
|
||||
|
||||
EventNotifier::EventNotifier(int fd) : fd_(fd)
|
||||
{
|
||||
int flags = fcntl(fd_, F_GETFL);
|
||||
CHECK_TRUE(flags >= 0, NO_RETVAL, "get flags of fd %d FAILED, %s", fd, strerror(errno));
|
||||
HILOG_DEBUG(LOG_CORE, "EventNotifier bind eventfd %d done!", fd_);
|
||||
}
|
||||
|
||||
EventNotifier::~EventNotifier()
|
||||
{
|
||||
HILOG_DEBUG(LOG_CORE, "EventNotifier close eventfd %d", fd_);
|
||||
close(fd_);
|
||||
}
|
||||
|
||||
int EventNotifier::GetFd() const
|
||||
{
|
||||
return fd_;
|
||||
}
|
||||
|
||||
bool EventNotifier::IsNonBlocking() const
|
||||
{
|
||||
return flags_ & O_NONBLOCK;
|
||||
}
|
||||
|
||||
bool EventNotifier::IsSemaphore() const
|
||||
{
|
||||
return flags_ & EFD_SEMAPHORE;
|
||||
}
|
||||
|
||||
uint64_t EventNotifier::Take() const
|
||||
{
|
||||
uint64_t value = UINT64_MAX;
|
||||
int retval = TEMP_FAILURE_RETRY(read(fd_, &value, sizeof(value)));
|
||||
CHECK_TRUE(retval == sizeof(value), false, "read value from eventfd %d failed, %s!", fd_, strerror(errno));
|
||||
return value;
|
||||
}
|
||||
|
||||
bool EventNotifier::Post(uint64_t value) const
|
||||
{
|
||||
int retval = TEMP_FAILURE_RETRY(write(fd_, &value, sizeof(value)));
|
||||
CHECK_TRUE(retval == sizeof(value), false, "write value to eventfd %d failed, %s!", fd_, strerror(errno));
|
||||
return true;
|
||||
}
|
33
device/base/src/i_semaphore.cpp
Normal file
33
device/base/src/i_semaphore.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "i_semaphore.h"
|
||||
#include "posix_semaphore.h"
|
||||
#include "pthread_semaphore.h"
|
||||
#include "std_semaphore.h"
|
||||
|
||||
ISemaphoreFactory& GetSemaphoreFactory(SemaphoreFactoryType type)
|
||||
{
|
||||
static StdSemaphoreFactory stdFactory;
|
||||
if (type == STD_SEMAPHORE_FACTORY) {
|
||||
return stdFactory;
|
||||
} else if (type == POSIX_SEMAPHORE_FACTORY) {
|
||||
static PosixSemaphoreFactory posxiFactory;
|
||||
return posxiFactory;
|
||||
} else if (type == PTHREAD_SEMAPHORE_FACTORY) {
|
||||
// static PthreadSemaphoreFactory pthreadFactory;
|
||||
return stdFactory;
|
||||
}
|
||||
return stdFactory;
|
||||
}
|
69
device/base/src/posix_semaphore.cpp
Normal file
69
device/base/src/posix_semaphore.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "posix_semaphore.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
namespace {
|
||||
constexpr int NS_PER_SEC = 1000 * 1000 * 1000;
|
||||
}
|
||||
|
||||
PosixSemaphore::PosixSemaphore(unsigned int value)
|
||||
{
|
||||
sem_init(&sem_, 0, value);
|
||||
}
|
||||
|
||||
PosixSemaphore::~PosixSemaphore()
|
||||
{
|
||||
sem_destroy(&sem_);
|
||||
}
|
||||
|
||||
bool PosixSemaphore::Wait()
|
||||
{
|
||||
return sem_wait(&sem_) == 0;
|
||||
}
|
||||
|
||||
bool PosixSemaphore::TryWait()
|
||||
{
|
||||
return sem_trywait(&sem_) == 0;
|
||||
}
|
||||
|
||||
bool PosixSemaphore::TimedWait(int seconds, int nanoSeconds)
|
||||
{
|
||||
struct timespec ts = { 0, 0 };
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
ts.tv_sec += seconds;
|
||||
ts.tv_nsec += nanoSeconds;
|
||||
ts.tv_sec += ts.tv_nsec / NS_PER_SEC;
|
||||
ts.tv_nsec %= NS_PER_SEC;
|
||||
return sem_timedwait(&sem_, &ts) == 0;
|
||||
}
|
||||
|
||||
bool PosixSemaphore::Post()
|
||||
{
|
||||
return sem_post(&sem_) == 0;
|
||||
}
|
||||
|
||||
unsigned PosixSemaphore::Value() const
|
||||
{
|
||||
int value = 0;
|
||||
sem_getvalue(&sem_, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
SemaphorePtr PosixSemaphoreFactory::Create(unsigned int value)
|
||||
{
|
||||
return std::make_shared<PosixSemaphore>(value);
|
||||
}
|
43
device/base/src/posix_semaphore.h
Normal file
43
device/base/src/posix_semaphore.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef OHOS_PROFILER_POSIX_SEMAPHORE_H
|
||||
#define OHOS_PROFILER_POSIX_SEMAPHORE_H
|
||||
|
||||
#include <memory>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include "i_semaphore.h"
|
||||
|
||||
class PosixSemaphore : public ISemaphore {
|
||||
public:
|
||||
explicit PosixSemaphore(unsigned int value);
|
||||
~PosixSemaphore();
|
||||
|
||||
bool Wait() override;
|
||||
bool TryWait() override;
|
||||
bool TimedWait(int seconds, int nanoSeconds) override;
|
||||
bool Post() override;
|
||||
unsigned Value() const override;
|
||||
|
||||
private:
|
||||
mutable sem_t sem_ = {};
|
||||
};
|
||||
|
||||
class PosixSemaphoreFactory : public ISemaphoreFactory {
|
||||
public:
|
||||
SemaphorePtr Create(unsigned int value) override;
|
||||
};
|
||||
|
||||
#endif // OHOS_PROFILER_POSIX_SEMAPHORE_H
|
100
device/base/src/pthread_semaphore.cpp
Normal file
100
device/base/src/pthread_semaphore.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pthread_semaphore.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
namespace {
|
||||
constexpr int NS_PER_SEC = 1000 * 1000 * 1000;
|
||||
}
|
||||
|
||||
PthreadSemaphore::PthreadSemaphore(unsigned int value) : value_(value)
|
||||
{
|
||||
pthread_mutex_init(&mutex_, nullptr);
|
||||
pthread_cond_init(&cond_, nullptr);
|
||||
}
|
||||
|
||||
PthreadSemaphore::~PthreadSemaphore()
|
||||
{
|
||||
pthread_cond_destroy(&cond_);
|
||||
pthread_mutex_destroy(&mutex_);
|
||||
}
|
||||
|
||||
bool PthreadSemaphore::Wait()
|
||||
{
|
||||
pthread_mutex_lock(&mutex_);
|
||||
while (value_ == 0) {
|
||||
pthread_cond_wait(&cond_, &mutex_);
|
||||
}
|
||||
--value_;
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PthreadSemaphore::TryWait()
|
||||
{
|
||||
pthread_mutex_lock(&mutex_);
|
||||
bool retval = TryWaitLocked();
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool PthreadSemaphore::TimedWait(int seconds, int nanoSeconds)
|
||||
{
|
||||
pthread_mutex_lock(&mutex_);
|
||||
if (value_) {
|
||||
struct timespec ts = { 0, 0 };
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
ts.tv_sec += seconds;
|
||||
ts.tv_nsec += nanoSeconds;
|
||||
ts.tv_sec += ts.tv_nsec / NS_PER_SEC;
|
||||
ts.tv_nsec %= NS_PER_SEC;
|
||||
pthread_cond_timedwait(&cond_, &mutex_, &ts);
|
||||
}
|
||||
bool retval = TryWaitLocked();
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool PthreadSemaphore::TryWaitLocked()
|
||||
{
|
||||
if (value_ == 0) {
|
||||
return false;
|
||||
}
|
||||
--value_;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PthreadSemaphore::Post()
|
||||
{
|
||||
pthread_mutex_lock(&mutex_);
|
||||
++value_;
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
pthread_cond_broadcast(&cond_);
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int PthreadSemaphore::Value() const
|
||||
{
|
||||
pthread_mutex_lock(&mutex_);
|
||||
unsigned int val = value_;
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
return val;
|
||||
}
|
||||
|
||||
SemaphorePtr PthreadSemaphoreFactory::Create(unsigned int value)
|
||||
{
|
||||
return std::make_shared<PthreadSemaphore>(value);
|
||||
}
|
46
device/base/src/pthread_semaphore.h
Normal file
46
device/base/src/pthread_semaphore.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef OHOS_PROFILER_PTHREAD_SEMAPHORE_H
|
||||
#define OHOS_PROFILER_PTHREAD_SEMAPHORE_H
|
||||
|
||||
#include <memory>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "i_semaphore.h"
|
||||
|
||||
class PthreadSemaphore : public ISemaphore {
|
||||
public:
|
||||
explicit PthreadSemaphore(unsigned int value);
|
||||
~PthreadSemaphore();
|
||||
|
||||
bool Wait() override;
|
||||
bool TryWait() override;
|
||||
bool TimedWait(int seconds, int nanoSeconds) override;
|
||||
bool Post() override;
|
||||
unsigned int Value() const override;
|
||||
|
||||
private:
|
||||
bool TryWaitLocked();
|
||||
mutable pthread_mutex_t mutex_ {};
|
||||
mutable pthread_cond_t cond_ {};
|
||||
volatile unsigned int value_ = 0;
|
||||
};
|
||||
|
||||
class PthreadSemaphoreFactory : public ISemaphoreFactory {
|
||||
public:
|
||||
SemaphorePtr Create(unsigned int value) override;
|
||||
};
|
||||
|
||||
#endif // OHOS_PROFILER_PTHREAD_SEMAPHORE_H
|
@ -18,6 +18,7 @@
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "logging.h"
|
||||
#include "securec.h"
|
||||
@ -36,22 +37,27 @@ ScheduleTaskManager& ScheduleTaskManager::GetInstance()
|
||||
|
||||
ScheduleTaskManager::ScheduleTaskManager()
|
||||
{
|
||||
runScheduleThread_ = true;
|
||||
scheduleThread_ = std::thread(&ScheduleTaskManager::ScheduleThread, this);
|
||||
}
|
||||
|
||||
ScheduleTaskManager::~ScheduleTaskManager()
|
||||
{
|
||||
Shutdown();
|
||||
if (scheduleThread_.joinable()) {
|
||||
scheduleThread_.join();
|
||||
}
|
||||
}
|
||||
|
||||
void ScheduleTaskManager::Shutdown()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(taskMutex_);
|
||||
runScheduleThread_ = false;
|
||||
bool expect = true;
|
||||
if (!runScheduleThread_.compare_exchange_strong(expect, false)) {
|
||||
return;
|
||||
}
|
||||
taskCv_.notify_one();
|
||||
if (scheduleThread_.joinable()) {
|
||||
scheduleThread_.join();
|
||||
}
|
||||
taskMap_.clear();
|
||||
timeMap_.clear();
|
||||
}
|
||||
|
||||
std::chrono::milliseconds ScheduleTaskManager::NormalizeInterval(std::chrono::milliseconds interval)
|
||||
@ -77,12 +83,14 @@ bool ScheduleTaskManager::ScheduleTask(const std::string& name,
|
||||
const std::chrono::milliseconds& repeatInterval,
|
||||
std::chrono::milliseconds initialDelay)
|
||||
{
|
||||
auto currentTime = Clock::now();
|
||||
auto task = std::make_shared<Task>();
|
||||
|
||||
task->name = name;
|
||||
task->callback = callback;
|
||||
task->initialDelay = initialDelay;
|
||||
task->repeatInterval = NormalizeInterval(repeatInterval);
|
||||
task->nextRunTime = currentTime + initialDelay;
|
||||
|
||||
std::lock_guard<std::mutex> guard(taskMutex_);
|
||||
if (taskMap_.count(name) > 0) {
|
||||
@ -91,26 +99,28 @@ bool ScheduleTaskManager::ScheduleTask(const std::string& name,
|
||||
}
|
||||
|
||||
taskMap_[name] = task;
|
||||
timeMap_.insert(std::make_pair(Clock::now() + initialDelay, task));
|
||||
timeMap_.insert(std::make_pair(task->nextRunTime, task));
|
||||
taskCv_.notify_one();
|
||||
|
||||
HILOG_DEBUG(LOG_CORE, "add schedule %s, total: %zu ", name.c_str(), taskMap_.size());
|
||||
HILOG_DEBUG(LOG_CORE, "add schedule %s done, total: %zu", name.c_str(), taskMap_.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScheduleTaskManager::UnscheduleTask(const std::string& name)
|
||||
{
|
||||
HILOG_DEBUG(LOG_CORE, "del schedule %s, total: %zu", name.c_str(), taskMap_.size());
|
||||
std::unique_lock<std::mutex> lck(taskMutex_);
|
||||
HILOG_DEBUG(LOG_CORE, "del schedule %s start, total: %zu", name.c_str(), taskMap_.size());
|
||||
auto it = taskMap_.find(name);
|
||||
if (it != taskMap_.end()) {
|
||||
taskMap_.erase(it);
|
||||
HILOG_DEBUG(LOG_CORE, "del schedule %s done, remain: %zu", name.c_str(), taskMap_.size());
|
||||
return true;
|
||||
}
|
||||
HILOG_DEBUG(LOG_CORE, "del schedule %s pass, total: %zu", name.c_str(), taskMap_.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScheduleTaskManager::TakeFront(TimePoint& time, WeakTask& task)
|
||||
ScheduleTaskManager::WeakTask ScheduleTaskManager::TakeFront()
|
||||
{
|
||||
std::unique_lock<std::mutex> lck(taskMutex_);
|
||||
|
||||
@ -120,54 +130,68 @@ bool ScheduleTaskManager::TakeFront(TimePoint& time, WeakTask& task)
|
||||
}
|
||||
|
||||
if (!runScheduleThread_) {
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
time = timeMap_.begin()->first;
|
||||
task = timeMap_.begin()->second;
|
||||
auto task = timeMap_.begin()->second;
|
||||
timeMap_.erase(timeMap_.begin());
|
||||
return true;
|
||||
return task;
|
||||
}
|
||||
|
||||
void ScheduleTaskManager::DumpTask(const SharedTask& task)
|
||||
{
|
||||
if (task) {
|
||||
long msecs = std::chrono::duration_cast<ms>(task->lastRunTime.time_since_epoch()).count();
|
||||
HILOG_DEBUG(LOG_CORE, "{name = %s, interval = %lld, delay = %lld, lastRun = %ld}",
|
||||
task->name.c_str(), task->repeatInterval.count(), task->initialDelay.count(), msecs);
|
||||
long msecs = std::chrono::duration_cast<ms>(task->nextRunTime.time_since_epoch()).count();
|
||||
HILOG_DEBUG(LOG_CORE,
|
||||
"{name = %{public}s, interval = %{public}lld, delay = %{public}lld, nextRunTime = %{public}ld}",
|
||||
task->name.c_str(), task->repeatInterval.count(), task->initialDelay.count(), msecs);
|
||||
}
|
||||
}
|
||||
|
||||
void ScheduleTaskManager::ScheduleThread()
|
||||
{
|
||||
while (true) {
|
||||
pthread_setname_np(pthread_self(), "SchedTaskMgr");
|
||||
while (runScheduleThread_) {
|
||||
// take front task from task queue
|
||||
TimePoint targetTime;
|
||||
WeakTask targetTask;
|
||||
if (!TakeFront(targetTime, targetTask)) {
|
||||
WeakTask weakTask = TakeFront();
|
||||
if (!runScheduleThread_) {
|
||||
break;
|
||||
}
|
||||
|
||||
TimePoint targetTime;
|
||||
{
|
||||
auto taskTime = weakTask.lock(); // promote to shared_ptr
|
||||
if (!taskTime) {
|
||||
// task cancelled with UnschduleTask or not a repeat task
|
||||
continue;
|
||||
}
|
||||
targetTime = taskTime->nextRunTime;
|
||||
}
|
||||
|
||||
// delay to target time
|
||||
auto currentTime = Clock::now();
|
||||
if (targetTime >= currentTime) {
|
||||
std::this_thread::sleep_for(targetTime - currentTime);
|
||||
}
|
||||
|
||||
// promote to shared_ptr
|
||||
auto task = targetTask.lock();
|
||||
DumpTask(task);
|
||||
auto taskRepeat = weakTask.lock();
|
||||
if (!taskRepeat) {
|
||||
// task cancelled with UnschduleTask or not a repeat task
|
||||
continue;
|
||||
}
|
||||
|
||||
if (task != nullptr) {
|
||||
// call task callback
|
||||
task->callback();
|
||||
task->lastRunTime = currentTime;
|
||||
// call task callback
|
||||
taskRepeat->callback();
|
||||
taskRepeat->nextRunTime = targetTime + taskRepeat->repeatInterval;
|
||||
|
||||
// re-insert task to map if it's a repeat task
|
||||
if (task->repeatInterval.count() != 0) {
|
||||
std::unique_lock<std::mutex> guard(taskMutex_);
|
||||
timeMap_.insert(std::make_pair(targetTime + task->repeatInterval, task));
|
||||
}
|
||||
if (taskRepeat->repeatInterval.count() != 0) {
|
||||
// repeat task, re-insert task to timeMap
|
||||
std::unique_lock<std::mutex> guard(taskMutex_);
|
||||
timeMap_.insert(std::make_pair(taskRepeat->nextRunTime, taskRepeat));
|
||||
} else {
|
||||
// not a repeat task.
|
||||
std::unique_lock<std::mutex> guard(taskMutex_);
|
||||
taskMap_.erase(taskRepeat->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
76
device/base/src/std_semaphore.cpp
Normal file
76
device/base/src/std_semaphore.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "std_semaphore.h"
|
||||
|
||||
StdSemaphore::StdSemaphore(unsigned int value) : value_(value) {}
|
||||
|
||||
StdSemaphore::~StdSemaphore() {}
|
||||
|
||||
bool StdSemaphore::Wait()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
while (value_ == 0) {
|
||||
condVar_.wait(lock);
|
||||
}
|
||||
--value_;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StdSemaphore::TryWait()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
return TryWaitLocked();
|
||||
}
|
||||
|
||||
bool StdSemaphore::TryWaitLocked()
|
||||
{
|
||||
if (value_ == 0) {
|
||||
return false;
|
||||
}
|
||||
--value_;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StdSemaphore::TimedWait(int seconds, int nanoSeconds)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
if (value_ == 0) {
|
||||
auto timePoint = std::chrono::steady_clock::now();
|
||||
timePoint += std::chrono::seconds(seconds);
|
||||
timePoint += std::chrono::nanoseconds(nanoSeconds);
|
||||
condVar_.wait_until(lock, timePoint);
|
||||
}
|
||||
return TryWaitLocked();
|
||||
}
|
||||
|
||||
bool StdSemaphore::Post()
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
++value_;
|
||||
}
|
||||
condVar_.notify_all();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned StdSemaphore::Value() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
SemaphorePtr StdSemaphoreFactory::Create(unsigned int value)
|
||||
{
|
||||
return std::make_shared<StdSemaphore>(value);
|
||||
}
|
48
device/base/src/std_semaphore.h
Normal file
48
device/base/src/std_semaphore.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef OHOS_PROFILER_STD_SEMAPHORE_H
|
||||
#define OHOS_PROFILER_STD_SEMAPHORE_H
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include "i_semaphore.h"
|
||||
#include "nocopyable.h"
|
||||
|
||||
class StdSemaphore : public ISemaphore {
|
||||
public:
|
||||
explicit StdSemaphore(unsigned int value);
|
||||
~StdSemaphore();
|
||||
bool Wait() override;
|
||||
bool TryWait() override;
|
||||
bool TimedWait(int seconds, int nanoSeconds) override;
|
||||
bool Post() override;
|
||||
unsigned int Value() const override;
|
||||
|
||||
private:
|
||||
bool TryWaitLocked();
|
||||
|
||||
mutable std::mutex mutex_;
|
||||
std::condition_variable condVar_;
|
||||
volatile unsigned int value_;
|
||||
|
||||
DISALLOW_COPY_AND_MOVE(StdSemaphore);
|
||||
};
|
||||
|
||||
class StdSemaphoreFactory : public ISemaphoreFactory {
|
||||
public:
|
||||
SemaphorePtr Create(unsigned int value) override;
|
||||
};
|
||||
|
||||
#endif // OHOS_PROFILER_STD_SEMAPHORE_H
|
18
device/base/test/BUILD.gn
Executable file → Normal file
18
device/base/test/BUILD.gn
Executable file → Normal file
@ -16,7 +16,7 @@ import("../../base/config.gni")
|
||||
|
||||
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
|
||||
config("module_private_config") {
|
||||
visibility = [":*"]
|
||||
visibility = [ ":*" ]
|
||||
if (current_toolchain != host_toolchain) {
|
||||
defines = [ "HAVE_HILOG" ]
|
||||
}
|
||||
@ -28,26 +28,22 @@ ohos_unittest("hiprofiler_base_ut") {
|
||||
"../:hiprofiler_base",
|
||||
"//third_party/googletest:gtest",
|
||||
]
|
||||
configs = [
|
||||
":module_private_config"
|
||||
]
|
||||
configs = [ ":module_private_config" ]
|
||||
include_dirs = [ "//third_party/googletest/googletest/include/gtest" ]
|
||||
sources = [
|
||||
"unittest/epoll_event_poller_test.cpp",
|
||||
"unittest/schedule_task_manager_test.cpp",
|
||||
"unittest/semaphore_test.cpp",
|
||||
]
|
||||
cflags = [
|
||||
"-Wno-inconsistent-missing-override",
|
||||
"-Dprivate=public", #allow test code access private members
|
||||
]
|
||||
external_deps = [
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
"-Dprivate=public", #allow test code access private members
|
||||
]
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}"
|
||||
}
|
||||
|
||||
group("unittest") {
|
||||
testonly = true
|
||||
deps = [
|
||||
":hiprofiler_base_ut",
|
||||
]
|
||||
deps = [ ":hiprofiler_base_ut" ]
|
||||
}
|
||||
|
217
device/base/test/unittest/epoll_event_poller_test.cpp
Normal file
217
device/base/test/unittest/epoll_event_poller_test.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cinttypes>
|
||||
#include <fcntl.h>
|
||||
#include <hwext/gtest-ext.h>
|
||||
#include <hwext/gtest-tag.h>
|
||||
#include <memory>
|
||||
#include <sys/eventfd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "epoll_event_poller.h"
|
||||
#include "event_notifier.h"
|
||||
#include "logging.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace {
|
||||
constexpr int DEFAULT_POLL_INTERVAL = 1000;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class EpollEventPollerTest : public testing::Test {
|
||||
protected:
|
||||
std::unique_ptr<EpollEventPoller> eventPoller;
|
||||
void SetUp() override
|
||||
{
|
||||
eventPoller = std::make_unique<EpollEventPoller>(DEFAULT_POLL_INTERVAL);
|
||||
}
|
||||
|
||||
void TearDown() override {}
|
||||
};
|
||||
|
||||
/**
|
||||
* @tc.name: EpollEventPollerTest
|
||||
* @tc.desc: CtorDtor.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(EpollEventPollerTest, CtorDtor, TestSize.Level1)
|
||||
{
|
||||
ASSERT_NE(eventPoller, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: EpollEventPollerTest
|
||||
* @tc.desc: InitFinalize.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(EpollEventPollerTest, InitFinalize, TestSize.Level1)
|
||||
{
|
||||
ASSERT_NE(eventPoller, nullptr);
|
||||
|
||||
HILOG_INFO(LOG_CORE, "EpollEventPollerTest.InitFinalize start!");
|
||||
EXPECT_TRUE(eventPoller->Init());
|
||||
EXPECT_TRUE(eventPoller->Finalize());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: EpollEventPollerTest
|
||||
* @tc.desc: InitFinalize.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(EpollEventPollerTest, InitOnly, TestSize.Level1)
|
||||
{
|
||||
ASSERT_NE(eventPoller, nullptr);
|
||||
HILOG_INFO(LOG_CORE, "EpollEventPollerTest.InitOnly start!");
|
||||
EXPECT_TRUE(eventPoller->Init());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: EpollEventPollerTest
|
||||
* @tc.desc: Init 2 times Finalize 1 time.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(EpollEventPollerTest, Init2Finalize1, TestSize.Level1)
|
||||
{
|
||||
ASSERT_NE(eventPoller, nullptr);
|
||||
|
||||
HILOG_INFO(LOG_CORE, "EpollEventPollerTest.Init2Finalize1 start!");
|
||||
EXPECT_TRUE(eventPoller->Init());
|
||||
EXPECT_FALSE(eventPoller->Init());
|
||||
EXPECT_TRUE(eventPoller->Finalize());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: EpollEventPollerTest
|
||||
* @tc.desc: InitStartStopFinalize.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(EpollEventPollerTest, InitStartStopFinalize, TestSize.Level1)
|
||||
{
|
||||
ASSERT_NE(eventPoller, nullptr);
|
||||
|
||||
HILOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStartStopFinalize start!");
|
||||
EXPECT_TRUE(eventPoller->Init());
|
||||
EXPECT_TRUE(eventPoller->Start());
|
||||
EXPECT_TRUE(eventPoller->Stop());
|
||||
EXPECT_TRUE(eventPoller->Finalize());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: EpollEventPollerTest
|
||||
* @tc.desc: InitStartStop.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(EpollEventPollerTest, InitStartStop, TestSize.Level1)
|
||||
{
|
||||
ASSERT_NE(eventPoller, nullptr);
|
||||
|
||||
HILOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStartStop start!");
|
||||
EXPECT_TRUE(eventPoller->Init());
|
||||
EXPECT_TRUE(eventPoller->Start());
|
||||
EXPECT_TRUE(eventPoller->Stop());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: EpollEventPollerTest
|
||||
* @tc.desc: InitStart.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(EpollEventPollerTest, InitStart, TestSize.Level1)
|
||||
{
|
||||
ASSERT_NE(eventPoller, nullptr);
|
||||
|
||||
HILOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStart start!");
|
||||
EXPECT_TRUE(eventPoller->Init());
|
||||
EXPECT_TRUE(eventPoller->Start());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: EpollEventPollerTest
|
||||
* @tc.desc: AddFd.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(EpollEventPollerTest, InitStartAddFd, TestSize.Level1)
|
||||
{
|
||||
ASSERT_NE(eventPoller, nullptr);
|
||||
|
||||
HILOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStartAddFd start!");
|
||||
EXPECT_TRUE(eventPoller->Init());
|
||||
EXPECT_TRUE(eventPoller->Start());
|
||||
|
||||
int eventFd = eventfd(0, O_CLOEXEC | O_NONBLOCK);
|
||||
uint64_t readValue = 0;
|
||||
auto onReadable = [&readValue, &eventFd]() {
|
||||
read(eventFd, &readValue, sizeof(readValue));
|
||||
HILOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStartAddFd read %" PRIu64, readValue);
|
||||
};
|
||||
EXPECT_TRUE(eventPoller->AddFileDescriptor(eventFd, onReadable));
|
||||
|
||||
uint64_t writeValue = 1234;
|
||||
int writeSize = sizeof(writeValue); // run -t UT -ss developtools
|
||||
EXPECT_EQ(write(eventFd, &writeValue, writeSize), writeSize);
|
||||
|
||||
std::this_thread::yield();
|
||||
usleep(15 * 1000);
|
||||
EXPECT_EQ(readValue, writeValue);
|
||||
|
||||
EXPECT_TRUE(eventPoller->Stop());
|
||||
EXPECT_TRUE(eventPoller->Finalize());
|
||||
|
||||
close(eventFd);
|
||||
}
|
||||
|
||||
HWTEST_F(EpollEventPollerTest, InitStartAddEventFd, TestSize.Level1)
|
||||
{
|
||||
ASSERT_NE(eventPoller, nullptr);
|
||||
|
||||
HILOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStartAddFd start!");
|
||||
EXPECT_TRUE(eventPoller->Init());
|
||||
EXPECT_TRUE(eventPoller->Start());
|
||||
|
||||
auto notifier = EventNotifier::Create(0, EventNotifier::NONBLOCK);
|
||||
uint64_t readValue = 0;
|
||||
auto onReadable = [&readValue, ¬ifier]() {
|
||||
readValue = notifier->Take();
|
||||
HILOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStartAddFd read %" PRIu64, readValue);
|
||||
};
|
||||
EXPECT_TRUE(eventPoller->AddFileDescriptor(notifier->GetFd(), onReadable));
|
||||
|
||||
uint64_t writeValue = 1234;
|
||||
pid_t pid = fork();
|
||||
EXPECT_GE(pid, 0);
|
||||
if (pid == 0) {
|
||||
int evFd = dup(notifier->GetFd());
|
||||
auto evNotifier = EventNotifier::CreateWithFd(evFd);
|
||||
evNotifier->Post(writeValue);
|
||||
_exit(0);
|
||||
} else if (pid > 0) {
|
||||
int wstatus = 0;
|
||||
waitpid(pid, &wstatus, 0);
|
||||
}
|
||||
|
||||
std::this_thread::yield();
|
||||
usleep(15 * 1000);
|
||||
EXPECT_EQ(readValue, writeValue);
|
||||
|
||||
EXPECT_TRUE(eventPoller->Stop());
|
||||
EXPECT_TRUE(eventPoller->Finalize());
|
||||
}
|
||||
} // namespace
|
0
device/base/test/unittest/event_notifier_test.cpp
Normal file
0
device/base/test/unittest/event_notifier_test.cpp
Normal file
36
device/base/test/unittest/schedule_task_manager_test.cpp
Executable file → Normal file
36
device/base/test/unittest/schedule_task_manager_test.cpp
Executable file → Normal file
@ -16,6 +16,7 @@
|
||||
#include <chrono>
|
||||
#include <hwext/gtest-ext.h>
|
||||
#include <hwext/gtest-tag.h>
|
||||
#include <sys/time.h>
|
||||
#include <thread>
|
||||
|
||||
#include "schedule_task_manager.h"
|
||||
@ -26,7 +27,10 @@ namespace {
|
||||
class ScheduleTaskManagerTest : public testing::Test {
|
||||
protected:
|
||||
static void SetUpTestCase() {}
|
||||
static void TearDownTestCase() {}
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
ScheduleTaskManager::GetInstance().Shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -55,6 +59,8 @@ HWTEST_F(ScheduleTaskManagerTest, ScheduleTaskOneshot, TestSize.Level1)
|
||||
|
||||
std::this_thread::sleep_for(initalDelay + initalDelay);
|
||||
EXPECT_EQ(count.load(), 1);
|
||||
|
||||
scheduleTaskManager.Shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,15 +78,27 @@ HWTEST_F(ScheduleTaskManagerTest, ScheduleTaskRepeated, TestSize.Level1)
|
||||
|
||||
ScheduleTaskManager scheduleTaskManager;
|
||||
EXPECT_TRUE(scheduleTaskManager.ScheduleTask(
|
||||
"task-2", [&]() { count++; }, repeatInterval, initalDelay));
|
||||
"task-2",
|
||||
[&]() {
|
||||
count++;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
printf("[%ld.%06ld] count: %d\n", tv.tv_sec, tv.tv_usec, count.load());
|
||||
},
|
||||
repeatInterval, initalDelay));
|
||||
|
||||
int expected = 0;
|
||||
std::this_thread::sleep_for(initalDelay + initalDelay);
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
expected++;
|
||||
struct timeval tv = { 0, 0 };
|
||||
gettimeofday(&tv, nullptr);
|
||||
printf("[%ld.%06ld] expected: %d\n", tv.tv_sec, tv.tv_usec, expected);
|
||||
EXPECT_EQ(count.load(), expected);
|
||||
std::this_thread::sleep_for(repeatInterval);
|
||||
}
|
||||
|
||||
scheduleTaskManager.Shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,19 +117,27 @@ HWTEST_F(ScheduleTaskManagerTest, UnscheduleTask, TestSize.Level1)
|
||||
|
||||
ScheduleTaskManager scheduleTaskManager;
|
||||
EXPECT_TRUE(scheduleTaskManager.ScheduleTask(
|
||||
taskName, [&]() { count++; }, repeatInterval));
|
||||
taskName,
|
||||
[&]() {
|
||||
count++;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
printf("[%ld.%06ld] count: %d\n", tv.tv_sec, tv.tv_usec, count.load());
|
||||
},
|
||||
repeatInterval));
|
||||
|
||||
int expected = 0;
|
||||
std::this_thread::sleep_for(initalDelay);
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
std::this_thread::sleep_for(repeatInterval);
|
||||
expected++;
|
||||
struct timeval tv = { 0, 0 };
|
||||
gettimeofday(&tv, nullptr);
|
||||
printf("[%ld.%06ld] expected: %d\n", tv.tv_sec, tv.tv_usec, expected);
|
||||
EXPECT_EQ(count.load(), expected);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(scheduleTaskManager.UnscheduleTask(taskName));
|
||||
scheduleTaskManager.Shutdown();
|
||||
|
||||
EXPECT_EQ(count.load(), expected);
|
||||
}
|
||||
} // namespace
|
95
device/base/test/unittest/semaphore_test.cpp
Normal file
95
device/base/test/unittest/semaphore_test.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <hwext/gtest-ext.h>
|
||||
#include <hwext/gtest-tag.h>
|
||||
#include <thread>
|
||||
|
||||
#include "i_semaphore.h"
|
||||
|
||||
namespace {
|
||||
using namespace testing::ext;
|
||||
|
||||
class SemaphoreTest : public testing::Test {
|
||||
protected:
|
||||
static void SetUpTestCase() {}
|
||||
static void TearDownTestCase() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* @tc.name: SemaphoreTest
|
||||
* @tc.desc: CtorDtor.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(SemaphoreTest, CtorDtor, TestSize.Level1)
|
||||
{
|
||||
auto semaphore = GetSemaphoreFactory().Create(0);
|
||||
EXPECT_NE(semaphore, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: SemaphoreTest
|
||||
* @tc.desc: Wait.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(SemaphoreTest, Wait, TestSize.Level1)
|
||||
{
|
||||
auto semaphore = GetSemaphoreFactory().Create(1);
|
||||
ASSERT_NE(semaphore, nullptr);
|
||||
EXPECT_TRUE(semaphore->Wait());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: SemaphoreTest
|
||||
* @tc.desc: Post.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(SemaphoreTest, Post, TestSize.Level1)
|
||||
{
|
||||
auto semaphore = GetSemaphoreFactory().Create(0);
|
||||
ASSERT_NE(semaphore, nullptr);
|
||||
EXPECT_TRUE(semaphore->Post());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: SemaphoreTest
|
||||
* @tc.desc: Post.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(SemaphoreTest, WaitPost, TestSize.Level1)
|
||||
{
|
||||
auto readySem = GetSemaphoreFactory().Create(0);
|
||||
auto finishSem = GetSemaphoreFactory().Create(0);
|
||||
ASSERT_NE(readySem, nullptr);
|
||||
ASSERT_NE(finishSem, nullptr);
|
||||
|
||||
auto done = std::make_shared<bool>(false);
|
||||
ASSERT_NE(done, nullptr);
|
||||
|
||||
std::thread bgThread([=]() {
|
||||
readySem->Wait();
|
||||
*done = true;
|
||||
finishSem->Post();
|
||||
});
|
||||
|
||||
EXPECT_TRUE(readySem->Post());
|
||||
EXPECT_TRUE(finishSem->Wait());
|
||||
EXPECT_TRUE(*done);
|
||||
|
||||
bgThread.join();
|
||||
}
|
||||
} // namespace
|
4
device/cmds/BUILD.gn
Executable file → Normal file
4
device/cmds/BUILD.gn
Executable file → Normal file
@ -24,9 +24,7 @@ ohos_source_set("command_line") {
|
||||
include_dirs = [ "include" ]
|
||||
}
|
||||
ohos_executable("hiprofiler_cmd") {
|
||||
sources = [
|
||||
"src/main.cpp",
|
||||
]
|
||||
sources = [ "src/main.cpp" ]
|
||||
include_dirs = [ "include" ]
|
||||
deps = [
|
||||
":command_line",
|
||||
|
0
device/cmds/include/command_param.h
Executable file → Normal file
0
device/cmds/include/command_param.h
Executable file → Normal file
0
device/cmds/include/command_param_switch.h
Executable file → Normal file
0
device/cmds/include/command_param_switch.h
Executable file → Normal file
0
device/cmds/include/command_param_text.h
Executable file → Normal file
0
device/cmds/include/command_param_text.h
Executable file → Normal file
2
device/cmds/src/command_param.cpp
Executable file → Normal file
2
device/cmds/src/command_param.cpp
Executable file → Normal file
@ -28,5 +28,5 @@ void CommandParam::AddFilter(const std::string& filterName)
|
||||
bool CommandParam::IsInFilter(const std::string& filterName)
|
||||
{
|
||||
return std::any_of(paramFilter_.begin(), paramFilter_.end(),
|
||||
[filterName](std::string s) { return s == filterName; });
|
||||
[filterName](const std::string& s) { return s == filterName; });
|
||||
}
|
0
device/cmds/src/command_param_switch.cpp
Executable file → Normal file
0
device/cmds/src/command_param_switch.cpp
Executable file → Normal file
0
device/cmds/src/command_param_text.cpp
Executable file → Normal file
0
device/cmds/src/command_param_text.cpp
Executable file → Normal file
@ -89,21 +89,30 @@ std::unique_ptr<CreateSessionRequest> MakeCreateRequest(const std::string& confi
|
||||
const std::string& keepSecond, const std::string& outputFileName)
|
||||
{
|
||||
auto request = std::make_unique<CreateSessionRequest>();
|
||||
auto sessionConfig = request->mutable_session_config();
|
||||
if (!request || !sessionConfig) {
|
||||
if (!request) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string content = ReadConfigContent(configFileName);
|
||||
if (content.empty()) {
|
||||
printf("config file empty!");
|
||||
return nullptr;
|
||||
}
|
||||
printf("================================\n");
|
||||
printf("CONFIG: read %zu bytes from %s:\n%s", content.size(), configFileName.c_str(), content.c_str());
|
||||
if (!google::protobuf::TextFormat::ParseFromString(content, request.get())) {
|
||||
printf("config file [%s] format error!\n", configFileName.c_str());
|
||||
printf("config file [%s] parse FAILED!\n", configFileName.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
request->set_request_id(0);
|
||||
auto sessionConfig = request->mutable_session_config();
|
||||
if (!sessionConfig) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
request->set_request_id(1);
|
||||
printf("--------------------------------\n");
|
||||
printf("keepSecond: %s,\noutputFileName: %s\n", keepSecond.c_str(), outputFileName.c_str());
|
||||
if (!keepSecond.empty()) {
|
||||
int ks = std::stoi(keepSecond);
|
||||
if (ks > 0) {
|
||||
@ -113,6 +122,15 @@ std::unique_ptr<CreateSessionRequest> MakeCreateRequest(const std::string& confi
|
||||
if (!outputFileName.empty()) {
|
||||
sessionConfig->set_result_file(outputFileName);
|
||||
}
|
||||
|
||||
content.clear();
|
||||
if (!google::protobuf::TextFormat::PrintToString(*request.get(), &content)) {
|
||||
printf("config message format FAILED!\n");
|
||||
return nullptr;
|
||||
}
|
||||
printf("--------------------------------\n");
|
||||
printf("CONFIG: final config content:\n%s", content.c_str());
|
||||
printf("================================\n");
|
||||
return request;
|
||||
}
|
||||
|
||||
@ -196,9 +214,6 @@ int main(int argc, char* argv[])
|
||||
bool isHelp = false;
|
||||
pCmdLine->AddParamSwitch("--help", "-h", isHelp, "make some help");
|
||||
|
||||
bool isBackground = false;
|
||||
pCmdLine->AddParamSwitch("--background", "-d", isBackground, "run in background");
|
||||
|
||||
std::vector<std::string> argvVector;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
argvVector.push_back(argv[i]);
|
||||
@ -207,7 +222,7 @@ int main(int argc, char* argv[])
|
||||
pCmdLine->PrintHelp();
|
||||
exit(0);
|
||||
}
|
||||
if (isGetGrpcAddr) {
|
||||
if (isGetGrpcAddr) { // handle get port
|
||||
auto profilerStub = GetProfilerServiceStub();
|
||||
if (profilerStub == nullptr) {
|
||||
printf("FAIL\nGet profiler service stub failed!\n");
|
||||
@ -229,13 +244,13 @@ int main(int argc, char* argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!configFileName.empty()) {
|
||||
// Read the configFileName,convert to protobuf object,structure 'CreateSession',Send 'StartSession' command to
|
||||
// profilerd
|
||||
if (StartSession(configFileName, traceKeepSecond, outputFileName)) {
|
||||
printf("OK\ntracing...\n");
|
||||
}
|
||||
exit(0);
|
||||
if (configFileName.empty()) { // normal case
|
||||
printf("FAIL\nconfig file argument must sepcified!");
|
||||
return 1;
|
||||
}
|
||||
// Read the configFileName, call 'CreateSession', and 'StartSession'
|
||||
if (StartSession(configFileName, traceKeepSecond, outputFileName)) {
|
||||
printf("OK\ntracing...\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
0
device/format-code.sh
Executable file → Normal file
0
device/format-code.sh
Executable file → Normal file
546
device/ohos_test.xml
Normal file
546
device/ohos_test.xml
Normal file
@ -0,0 +1,546 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<configuration ver="2.0">
|
||||
<target name="profiler_service_ut">
|
||||
<preparer>
|
||||
<option name="push" value="developtools/developtools/libabsl_base.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_civil_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_cord.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_debugging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_demangle_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_dynamic_annotations.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_graphcycles_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_int128.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_log_severity.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_malloc_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_raw_logging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_spinlock_wait.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_stacktrace.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_status.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_statusor.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_str_format_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_symbolize.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_synchronization.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_throw_delegate.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time_zone.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libaddress_sorting.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libagentplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libares.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libbytraceplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcrypto.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgpr.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpc.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpcxx.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libhiperf_call_plugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf_lite.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotoc_lib.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libre2.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/./libmemdataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libshared_memory.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libssl.z.so -> /system/lib/" src="out"/>
|
||||
</preparer>
|
||||
</target>
|
||||
<target name="plugin_service_module_test">
|
||||
<preparer>
|
||||
<option name="push" value="developtools/developtools/libabsl_base.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_civil_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_cord.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_debugging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_demangle_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_dynamic_annotations.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_graphcycles_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_int128.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_log_severity.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_malloc_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_raw_logging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_spinlock_wait.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_stacktrace.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_status.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_statusor.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_str_format_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_symbolize.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_synchronization.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_throw_delegate.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time_zone.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libaddress_sorting.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libagentplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libares.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libbytraceplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcrypto.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgpr.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpc.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpcxx.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libhiperf_call_plugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf_lite.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotoc_lib.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libre2.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/./libmemdataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libshared_memory.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libssl.z.so -> /system/lib/" src="out"/>
|
||||
</preparer>
|
||||
</target>
|
||||
<target name="plugin_service_ut">
|
||||
<preparer>
|
||||
<option name="push" value="developtools/developtools/libabsl_base.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_civil_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_cord.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_debugging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_demangle_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_dynamic_annotations.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_graphcycles_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_int128.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_log_severity.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_malloc_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_raw_logging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_spinlock_wait.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_stacktrace.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_status.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_statusor.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_str_format_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_symbolize.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_synchronization.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_throw_delegate.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time_zone.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libaddress_sorting.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libagentplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libares.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libbytraceplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcrypto.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgpr.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpc.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpcxx.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libhiperf_call_plugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf_lite.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotoc_lib.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libre2.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/./libmemdataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libshared_memory.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libssl.z.so -> /system/lib/" src="out"/>
|
||||
</preparer>
|
||||
</target>
|
||||
<target name="shared_memory_ut">
|
||||
<preparer>
|
||||
<option name="push" value="developtools/developtools/libabsl_base.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_civil_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_cord.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_debugging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_demangle_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_dynamic_annotations.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_graphcycles_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_int128.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_log_severity.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_malloc_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_raw_logging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_spinlock_wait.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_stacktrace.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_status.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_statusor.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_str_format_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_symbolize.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_synchronization.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_throw_delegate.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time_zone.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libaddress_sorting.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libagentplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libares.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libbytraceplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcrypto.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgpr.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpc.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpcxx.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libhiperf_call_plugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf_lite.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotoc_lib.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libre2.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/./libmemdataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libshared_memory.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libssl.z.so -> /system/lib/" src="out"/>
|
||||
</preparer>
|
||||
</target>
|
||||
<target name="ipc_ut">
|
||||
<preparer>
|
||||
<option name="push" value="developtools/developtools/libabsl_base.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_civil_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_cord.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_debugging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_demangle_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_dynamic_annotations.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_graphcycles_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_int128.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_log_severity.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_malloc_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_raw_logging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_spinlock_wait.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_stacktrace.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_status.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_statusor.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_str_format_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_symbolize.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_synchronization.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_throw_delegate.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time_zone.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libaddress_sorting.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libagentplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libares.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libbytraceplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcrypto.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgpr.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpc.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpcxx.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libhiperf_call_plugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf_lite.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotoc_lib.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libre2.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/./libmemdataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libshared_memory.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libssl.z.so -> /system/lib/" src="out"/>
|
||||
</preparer>
|
||||
</target>
|
||||
<target name="memdataplugin_ut">
|
||||
<preparer>
|
||||
<option name="push" value="plugins/memory_plugin/test/utresources/proc/1/oom_score_adj -> /data/local/tmp/utresources/proc/1/" src="res"/>
|
||||
<option name="push" value="plugins/memory_plugin/test/utresources/proc/1/smaps -> /data/local/tmp/utresources/proc/1/" src="res"/>
|
||||
<option name="push" value="plugins/memory_plugin/test/utresources/proc/1/status -> /data/local/tmp/utresources/proc/1/" src="res"/>
|
||||
<option name="push" value="plugins/memory_plugin/test/utresources/proc/2/oom_score_adj -> /data/local/tmp/utresources/proc/2/" src="res"/>
|
||||
<option name="push" value="plugins/memory_plugin/test/utresources/proc/2/smaps -> /data/local/tmp/utresources/proc/2/" src="res"/>
|
||||
<option name="push" value="plugins/memory_plugin/test/utresources/proc/2/status -> /data/local/tmp/utresources/proc/2/" src="res"/>
|
||||
<option name="push" value="plugins/memory_plugin/test/utresources/proc/11/oom_score_adj -> /data/local/tmp/utresources/proc/11/" src="res"/>
|
||||
<option name="push" value="plugins/memory_plugin/test/utresources/proc/11/smaps -> /data/local/tmp/utresources/proc/11/" src="res"/>
|
||||
<option name="push" value="plugins/memory_plugin/test/utresources/proc/11/status -> /data/local/tmp/utresources/proc/11/" src="res"/>
|
||||
<option name="push" value="plugins/memory_plugin/test/utresources/proc/cmdline -> /data/local/tmp/utresources/proc/" src="res"/>
|
||||
<option name="push" value="plugins/memory_plugin/test/utresources/proc/meminfo -> /data/local/tmp/utresources/proc/" src="res"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_base.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_civil_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_cord.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_debugging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_demangle_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_dynamic_annotations.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_graphcycles_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_int128.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_log_severity.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_malloc_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_raw_logging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_spinlock_wait.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_stacktrace.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_status.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_statusor.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_str_format_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_symbolize.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_synchronization.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_throw_delegate.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time_zone.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libaddress_sorting.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libagentplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libares.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libbytraceplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcrypto.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgpr.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpc.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpcxx.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libhiperf_call_plugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf_lite.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotoc_lib.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libre2.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/./libmemdataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libshared_memory.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libssl.z.so -> /system/lib/" src="out"/>
|
||||
</preparer>
|
||||
</target>
|
||||
<target name="hiprofiler_plugins_ut">
|
||||
<preparer>
|
||||
<option name="push" value="developtools/developtools/libabsl_base.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_civil_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_cord.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_debugging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_demangle_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_dynamic_annotations.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_graphcycles_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_int128.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_log_severity.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_malloc_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_raw_logging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_spinlock_wait.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_stacktrace.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_status.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_statusor.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_str_format_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_symbolize.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_synchronization.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_throw_delegate.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time_zone.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libaddress_sorting.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libagentplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libares.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libbytraceplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcrypto.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgpr.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpc.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpcxx.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libhiperf_call_plugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf_lite.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotoc_lib.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libre2.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/./libmemdataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libshared_memory.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libssl.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/hiprofilerd -> /system/lib/" src="out"/>
|
||||
</preparer>
|
||||
</target>
|
||||
<target name="plugin_module_api_ut">
|
||||
<preparer>
|
||||
<option name="push" value="developtools/developtools/libabsl_base.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_civil_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_cord.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_debugging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_demangle_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_dynamic_annotations.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_graphcycles_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_int128.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_log_severity.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_malloc_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_raw_logging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_spinlock_wait.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_stacktrace.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_status.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_statusor.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_str_format_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_symbolize.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_synchronization.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_throw_delegate.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time_zone.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libaddress_sorting.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libagentplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libares.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libbytraceplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcrypto.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgpr.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpc.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpcxx.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libhiperf_call_plugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf_lite.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotoc_lib.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libre2.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/./libmemdataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libshared_memory.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libssl.z.so -> /system/lib/" src="out"/>
|
||||
</preparer>
|
||||
</target>
|
||||
<target name="cpudataplugin_ut">
|
||||
<preparer>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/proc/stat -> /data/local/tmp/resources/proc/" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/proc/1872/stat -> /data/local/tmp/resources/proc/1872/" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/proc/1872/task/1872/stat -> /data/local/tmp/resources/proc/1872/task/1872/" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/proc/1872/task/1965/stat -> /data/local/tmp/resources/proc/1872/task/1965/" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/proc/1872/task/1966/stat -> /data/local/tmp/resources/proc/1872/task/1966/" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/proc/1872/task/1967/stat -> /data/local/tmp/resources/proc/1872/task/1967/" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/proc/1872/task/1968/stat -> /data/local/tmp/resources/proc/1872/task/1968/" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/proc/1872/task/1995/stat -> /data/local/tmp/resources/proc/1872/task/1995/" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/proc/1872/task/1996/stat -> /data/local/tmp/resources/proc/1872/task/1996/" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu0/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu0/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu0/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_cur_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu1/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_max_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu1/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_min_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu1/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_cur_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu2/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_max_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu2/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_min_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu2/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_cur_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu3/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_max_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu3/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_min_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu3/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu4/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_max_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu4/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_min_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu4/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_cur_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu5/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_max_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu5/cpufreq" src="res"/>
|
||||
<option name="push" value="plugins/cpu_plugin/test/resources/sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_min_freq -> /data/local/tmp/resources/sys/devices/system/cpu/cpu5/cpufreq" src="res"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_base.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_civil_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_cord.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_debugging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_demangle_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_dynamic_annotations.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_graphcycles_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_int128.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_log_severity.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_malloc_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_raw_logging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_spinlock_wait.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_stacktrace.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_status.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_statusor.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_str_format_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_symbolize.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_synchronization.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_throw_delegate.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time_zone.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libaddress_sorting.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libagentplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libares.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libbytraceplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcpudataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcrypto.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libdiskiodataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgpr.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpc.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpcxx.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libhiperf_call_plugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf_lite.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotoc_lib.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libre2.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/./libmemdataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libshared_memory.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libssl.z.so -> /system/lib/" src="out"/>
|
||||
</preparer>
|
||||
</target>
|
||||
<target name="diskiodataplugin_ut">
|
||||
<preparer>
|
||||
<option name="push" value="plugins/diskio_plugin/test/resources/proc/vmstat -> /data/local/tmp/resources/proc/" src="res"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_base.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_civil_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_cord.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_debugging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_demangle_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_dynamic_annotations.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_graphcycles_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_int128.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_log_severity.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_malloc_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_raw_logging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_spinlock_wait.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_stacktrace.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_status.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_statusor.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_str_format_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_symbolize.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_synchronization.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_throw_delegate.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time_zone.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libaddress_sorting.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libagentplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libares.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libbytraceplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcpudataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcrypto.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libdiskiodataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgpr.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpc.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpcxx.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libhiperf_call_plugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf_lite.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotoc_lib.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libre2.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/./libmemdataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libshared_memory.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libssl.z.so -> /system/lib/" src="out"/>
|
||||
</preparer>
|
||||
</target>
|
||||
<target name="networkplugin_ut">
|
||||
<preparer>
|
||||
<option name="push" value="plugins/network_plugin/test/utresources/begin/proc/9553/status -> /data/local/tmp/utresources/begin/proc/9553/" src="res"/>
|
||||
<option name="push" value="plugins/network_plugin/test/utresources/begin/proc/net/xt_qtaguid/stats -> /data/local/tmp/utresources/begin/proc/net/xt_qtaguid/" src="res"/>
|
||||
<option name="push" value="plugins/network_plugin/test/utresources/end/proc/9553/status -> /data/local/tmp/utresources/end/proc/9553/" src="res"/>
|
||||
<option name="push" value="plugins/network_plugin/test/utresources/end/proc/net/xt_qtaguid/stats -> /data/local/tmp/utresources/end/proc/net/xt_qtaguid/" src="res"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_base.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_civil_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_cord.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_debugging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_demangle_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_dynamic_annotations.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_graphcycles_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_int128.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_log_severity.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_malloc_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_raw_logging_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_spinlock_wait.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_stacktrace.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_status.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_statusor.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_str_format_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_strings_internal.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_symbolize.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_synchronization.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_throw_delegate.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libabsl_time_zone.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libaddress_sorting.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libagentplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libares.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libbytraceplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcpudataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libcrypto.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libdiskiodataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgpr.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpc.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libgrpcxx.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libhiperf_call_plugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotobuf_lite.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libprotoc_lib.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libre2.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/./libmemdataplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libshared_memory.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/libssl.z.so -> /system/lib/" src="out"/>
|
||||
</preparer>
|
||||
</target>
|
||||
<target name="agent_ut">
|
||||
<preparer>
|
||||
<option name="push" value="developtools/developtools/libagentplugin.z.so -> /system/lib/" src="out"/>
|
||||
<option name="push" value="developtools/developtools/hiprofilerd -> /system/lib/" src="out"/>
|
||||
</preparer>
|
||||
</target>
|
||||
</configuration>
|
15
device/plugins/api/BUILD.gn
Executable file → Normal file
15
device/plugins/api/BUILD.gn
Executable file → Normal file
@ -35,12 +35,13 @@ ohos_source_set("plugins_sources") {
|
||||
"../../base/include/",
|
||||
"${OHOS_PROFILER_DIR}/interfaces/kits",
|
||||
"//utils/native/base/include",
|
||||
"//third_party/boringssl/src/include",
|
||||
]
|
||||
sources = [
|
||||
"src/buffer_writer.cpp",
|
||||
"src/command_poller.cpp",
|
||||
"src/plugin_module.cpp",
|
||||
"src/plugin_manager.cpp",
|
||||
"src/plugin_module.cpp",
|
||||
"src/plugin_watcher.cpp",
|
||||
"src/writer_adapter.cpp",
|
||||
]
|
||||
@ -49,7 +50,9 @@ ohos_source_set("plugins_sources") {
|
||||
"${OHOS_PROFILER_DIR}/protos/services:plugin_services_proto",
|
||||
"${OHOS_PROFILER_DIR}/protos/services:service_types_proto",
|
||||
"../../base:hiprofiler_base",
|
||||
"//utils/native/base:utilsbase",
|
||||
"//third_party/boringssl:crypto",
|
||||
"//third_party/boringssl:crypto",
|
||||
"//utils/native/base:utilsecurec",
|
||||
]
|
||||
public_configs = [ ":hiprofiler_plugins_config" ]
|
||||
if (current_toolchain != host_toolchain) {
|
||||
@ -62,12 +65,8 @@ ohos_source_set("plugins_sources") {
|
||||
}
|
||||
|
||||
ohos_executable("hiprofiler_plugins") {
|
||||
deps = [
|
||||
":plugins_sources",
|
||||
]
|
||||
sources = [
|
||||
"src/main.cpp",
|
||||
]
|
||||
deps = [ ":plugins_sources" ]
|
||||
sources = [ "src/main.cpp" ]
|
||||
if (current_toolchain != host_toolchain) {
|
||||
defines = [ "HAVE_HILOG" ]
|
||||
if (build_l2) {
|
||||
|
48
device/plugins/api/include/manager_interface.h
Normal file
48
device/plugins/api/include/manager_interface.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef PLUGIN_INTERFACE_H
|
||||
#define PLUGIN_INTERFACE_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class ProfilerPluginConfig;
|
||||
class PluginResult;
|
||||
class CommandPoller;
|
||||
|
||||
class ManagerInterface {
|
||||
public:
|
||||
virtual ~ManagerInterface() {}
|
||||
|
||||
virtual bool LoadPlugin(const std::string& pluginPath) = 0;
|
||||
virtual bool UnloadPlugin(const std::string& pluginPath) = 0;
|
||||
virtual bool UnloadPlugin(const uint32_t pluginId) = 0;
|
||||
|
||||
// CommandPoller will call the following four interfaces after receiving the command
|
||||
virtual bool CreatePluginSession(const std::vector<ProfilerPluginConfig>& config) = 0;
|
||||
virtual bool DestroyPluginSession(const std::vector<uint32_t>& pluginIds) = 0;
|
||||
virtual bool StartPluginSession(const std::vector<uint32_t>& pluginIds,
|
||||
const std::vector<ProfilerPluginConfig>& config) = 0;
|
||||
virtual bool StopPluginSession(const std::vector<uint32_t>& pluginIds) = 0;
|
||||
|
||||
virtual bool CreateWriter(std::string pluginName, uint32_t bufferSize, int smbFd, int eventFd) = 0;
|
||||
virtual bool ResetWriter(uint32_t pluginId) = 0;
|
||||
virtual void SetCommandPoller(const std::shared_ptr<CommandPoller>& p) = 0;
|
||||
};
|
||||
|
||||
#endif // PLUGIN_INTERFACE_H
|
0
device/plugins/api/include/writer.h
Executable file → Normal file
0
device/plugins/api/include/writer.h
Executable file → Normal file
@ -15,50 +15,89 @@
|
||||
|
||||
#include "buffer_writer.h"
|
||||
#include "command_poller.h"
|
||||
#include "common_types.pb.h"
|
||||
#include "logging.h"
|
||||
#include "plugin_service_types.pb.h"
|
||||
#include "share_memory_allocator.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
|
||||
BufferWriter::BufferWriter(std::string name,
|
||||
uint32_t size,
|
||||
int fd,
|
||||
const CommandPollerPtr& cp,
|
||||
int smbFd,
|
||||
int eventFd,
|
||||
uint32_t pluginId)
|
||||
: pluginName_(name)
|
||||
{
|
||||
HILOG_DEBUG(LOG_CORE, "CreateMemoryBlockRemote %s %d %d", name.c_str(), size, fd);
|
||||
shareMemoryBlock_ = ShareMemoryAllocator::GetInstance().CreateMemoryBlockRemote(name, size, fd);
|
||||
HILOG_INFO(LOG_CORE, "BufferWriter %s %d [%d] [%d]", name.c_str(), size, smbFd, eventFd);
|
||||
shareMemoryBlock_ = ShareMemoryAllocator::GetInstance().CreateMemoryBlockRemote(name, size, smbFd);
|
||||
if (shareMemoryBlock_ == nullptr) {
|
||||
HILOG_DEBUG(LOG_CORE, "shareMemoryBlock_ == nullptr=");
|
||||
HILOG_DEBUG(LOG_CORE, "create shareMemoryBlock_ failed!");
|
||||
}
|
||||
commandPoller_ = cp;
|
||||
eventNotifier_ = EventNotifier::CreateWithFd(eventFd);
|
||||
pluginId_ = pluginId;
|
||||
lastFlushTime_ = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
BufferWriter::~BufferWriter()
|
||||
{
|
||||
HILOG_DEBUG(LOG_CORE, "BufferWriter destroy eventfd = %d!", eventNotifier_ ? eventNotifier_->GetFd() : -1);
|
||||
eventNotifier_ = nullptr;
|
||||
ShareMemoryAllocator::GetInstance().ReleaseMemoryBlockRemote(pluginName_);
|
||||
}
|
||||
|
||||
void BufferWriter::Report() const
|
||||
{
|
||||
HILOG_DEBUG(LOG_CORE, "BufferWriter stats B: %" PRIu64 ", P: %d, W:%" PRIu64 ", F: %d",
|
||||
bytesCount_.load(), bytesPending_.load(), writeCount_.load(), flushCount_.load());
|
||||
}
|
||||
|
||||
void BufferWriter::DoStats(long bytes)
|
||||
{
|
||||
++writeCount_;
|
||||
bytesCount_ += bytes;
|
||||
bytesPending_ += bytes;
|
||||
}
|
||||
|
||||
long BufferWriter::Write(const void* data, size_t size)
|
||||
{
|
||||
if (shareMemoryBlock_ == nullptr) {
|
||||
if (shareMemoryBlock_ == nullptr || data == nullptr || size == 0) {
|
||||
return false;
|
||||
}
|
||||
HILOG_DEBUG(LOG_CORE, "BufferWriter Write %zu", size);
|
||||
return shareMemoryBlock_->PutRaw(reinterpret_cast<const int8_t*>(data), static_cast<uint32_t>(size));
|
||||
|
||||
ProfilerPluginData pluginData;
|
||||
pluginData.set_name(pluginName_);
|
||||
pluginData.set_status(0);
|
||||
pluginData.set_data(data, size);
|
||||
|
||||
struct timespec ts = { 0, 0 };
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
|
||||
pluginData.set_clock_id(ProfilerPluginData::CLOCKID_REALTIME);
|
||||
pluginData.set_tv_sec(ts.tv_sec);
|
||||
pluginData.set_tv_nsec(ts.tv_nsec);
|
||||
|
||||
DoStats(pluginData.ByteSizeLong());
|
||||
return shareMemoryBlock_->PutMessage(pluginData);
|
||||
}
|
||||
|
||||
bool BufferWriter::WriteProtobuf(google::protobuf::Message& pmsg)
|
||||
bool BufferWriter::WriteMessage(const google::protobuf::Message& pmsg)
|
||||
{
|
||||
if (shareMemoryBlock_ == nullptr) {
|
||||
return false;
|
||||
}
|
||||
HILOG_DEBUG(LOG_CORE, "BufferWriter Write %zu", pmsg.ByteSizeLong());
|
||||
return shareMemoryBlock_->PutProtobuf(pmsg);
|
||||
DoStats(pmsg.ByteSizeLong());
|
||||
return shareMemoryBlock_->PutMessage(pmsg);
|
||||
}
|
||||
|
||||
bool BufferWriter::Flush()
|
||||
{
|
||||
++flushCount_;
|
||||
eventNotifier_->Post(flushCount_.load());
|
||||
lastFlushTime_ = std::chrono::steady_clock::now();
|
||||
bytesPending_ = 0;
|
||||
return true;
|
||||
}
|
||||
|
25
device/plugins/api/src/buffer_writer.h
Executable file → Normal file
25
device/plugins/api/src/buffer_writer.h
Executable file → Normal file
@ -16,7 +16,9 @@
|
||||
#ifndef BUFFER_WRITER_H
|
||||
#define BUFFER_WRITER_H
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include "event_notifier.h"
|
||||
#include "plugin_module_api.h"
|
||||
#include "share_memory_allocator.h"
|
||||
#include "writer.h"
|
||||
@ -27,18 +29,33 @@ using CommandPollerPtr = STD_PTR(shared, CommandPoller);
|
||||
|
||||
class BufferWriter : public Writer {
|
||||
public:
|
||||
BufferWriter(std::string name, uint32_t size, int fd, const CommandPollerPtr& cp, uint32_t pluginId);
|
||||
BufferWriter(std::string name,
|
||||
uint32_t size,
|
||||
int smbFd,
|
||||
int eventFd,
|
||||
uint32_t pluginId);
|
||||
~BufferWriter();
|
||||
long Write(const void* data, size_t size) override;
|
||||
bool Flush() override;
|
||||
|
||||
bool WriteProtobuf(google::protobuf::Message& pmsg);
|
||||
bool WriteMessage(const google::protobuf::Message& pmsg);
|
||||
|
||||
private:
|
||||
void DoStats(long bytes);
|
||||
void Report() const;
|
||||
|
||||
private:
|
||||
std::string pluginName_;
|
||||
std::shared_ptr<ShareMemoryBlock> shareMemoryBlock_;
|
||||
CommandPollerPtr commandPoller_;
|
||||
uint32_t pluginId_;
|
||||
EventNotifierPtr eventNotifier_ = nullptr;
|
||||
std::chrono::steady_clock::time_point lastFlushTime_;
|
||||
std::atomic<uint64_t> bytesCount_ = 0;
|
||||
std::atomic<uint32_t> bytesPending_ = 0;
|
||||
std::atomic<uint64_t> writeCount_ = 0;
|
||||
std::atomic<uint32_t> flushCount_ = 0;
|
||||
uint32_t pluginId_ = 0;
|
||||
};
|
||||
|
||||
using BufferWriterPtr = STD_PTR(shared, BufferWriter);
|
||||
|
||||
#endif // BUFFER_WRITER_H
|
||||
|
@ -17,8 +17,14 @@
|
||||
#include "plugin_manager.h"
|
||||
#include "socket_context.h"
|
||||
|
||||
CommandPoller::CommandPoller(const PluginManagerPtr& p)
|
||||
: requestIdAutoIncrease_(1), pluginManager_(p)
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace {
|
||||
constexpr int SLEEP_TIME = 10;
|
||||
}
|
||||
|
||||
CommandPoller::CommandPoller(const ManagerInterfacePtr& p) : requestIdAutoIncrease_(1), pluginManager_(p)
|
||||
{
|
||||
Connect(DEFAULT_UNIX_SOCKET_PATH);
|
||||
}
|
||||
@ -45,13 +51,17 @@ bool CommandPoller::OnCreateSessionCmd(const CreateSessionCmd& cmd, SocketContex
|
||||
HILOG_DEBUG(LOG_CORE, "OnCreateSessionCmd FAIL 1");
|
||||
return false;
|
||||
}
|
||||
int fd = -1;
|
||||
int smbFd = -1;
|
||||
int eventFd = -1;
|
||||
if (bufferSize != 0) {
|
||||
HILOG_DEBUG(LOG_CORE, "OnCreateSessionCmd bufferSize = %d", bufferSize);
|
||||
fd = context.ReceiveFileDiscriptor();
|
||||
HILOG_DEBUG(LOG_CORE, "OnCreateSessionCmd fd = %d", fd);
|
||||
smbFd = context.ReceiveFileDiscriptor();
|
||||
eventFd = context.ReceiveFileDiscriptor();
|
||||
int flags = fcntl(eventFd, F_GETFL);
|
||||
HILOG_DEBUG(LOG_CORE, "OnCreateSessionCmd smbFd = %d, eventFd = %d", smbFd, eventFd);
|
||||
HILOG_DEBUG(LOG_CORE, "eventFd flags = %X", flags);
|
||||
}
|
||||
if (!pluginManager->CreateWriter(config.name(), bufferSize, fd)) {
|
||||
if (!pluginManager->CreateWriter(config.name(), bufferSize, smbFd, eventFd)) {
|
||||
HILOG_DEBUG(LOG_CORE, "OnCreateSessionCmd CreateWriter FAIL");
|
||||
return false;
|
||||
}
|
||||
@ -128,7 +138,7 @@ bool CommandPoller::OnStopSessionCmd(const StopSessionCmd& cmd) const
|
||||
bool CommandPoller::OnGetCommandResponse(SocketContext& context, ::GetCommandResponse& response)
|
||||
{
|
||||
HILOG_DEBUG(LOG_CORE, "OnGetCommandResponse");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
|
||||
NotifyResultRequest nrr;
|
||||
nrr.set_request_id(1);
|
||||
nrr.set_command_id(response.command_id());
|
||||
|
8
device/plugins/api/src/command_poller.h
Executable file → Normal file
8
device/plugins/api/src/command_poller.h
Executable file → Normal file
@ -18,7 +18,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
class PluginManager;
|
||||
class ManagerInterface;
|
||||
class CreateSessionCmd;
|
||||
class DestroySessionCmd;
|
||||
class StartSessionCmd;
|
||||
@ -27,11 +27,11 @@ class StopSessionCmd;
|
||||
#include "logging.h"
|
||||
#include "plugin_service.ipc.h"
|
||||
|
||||
using PluginManagerPtr = STD_PTR(shared, PluginManager);
|
||||
using ManagerInterfacePtr = STD_PTR(shared, ManagerInterface);
|
||||
|
||||
class CommandPoller final : public IPluginServiceClient {
|
||||
public:
|
||||
explicit CommandPoller(const PluginManagerPtr& p);
|
||||
explicit CommandPoller(const ManagerInterfacePtr& p);
|
||||
~CommandPoller();
|
||||
|
||||
bool OnCreateSessionCmd(const CreateSessionCmd& cmd, SocketContext& context) const;
|
||||
@ -46,7 +46,7 @@ protected:
|
||||
|
||||
private:
|
||||
uint32_t requestIdAutoIncrease_;
|
||||
std::weak_ptr<PluginManager> pluginManager_;
|
||||
std::weak_ptr<ManagerInterface> pluginManager_;
|
||||
};
|
||||
|
||||
#endif // !COMMAND_POLLER_H
|
11
device/plugins/api/src/main.cpp
Executable file → Normal file
11
device/plugins/api/src/main.cpp
Executable file → Normal file
@ -47,8 +47,15 @@ int main(int argc, char* argv[])
|
||||
pluginManager->SetCommandPoller(commandPoller);
|
||||
|
||||
PluginWatcher watcher(pluginManager);
|
||||
watcher.ScanPlugins(pluginDir);
|
||||
watcher.WatchPlugins(pluginDir);
|
||||
if (!watcher.ScanPlugins(pluginDir)) {
|
||||
HILOG_DEBUG(LOG_CORE, "Scan pluginDir:%s failed!", DEFAULT_PLUGIN_PATH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!watcher.WatchPlugins(pluginDir)) {
|
||||
HILOG_DEBUG(LOG_CORE, "Monitor pluginDir:%s failed!", DEFAULT_PLUGIN_PATH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_ONE_SECOND));
|
||||
|
@ -15,12 +15,49 @@
|
||||
|
||||
#include "plugin_manager.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
|
||||
#include "command_poller.h"
|
||||
#include "logging.h"
|
||||
#include "openssl/sha.h"
|
||||
#include "plugin_service_types.pb.h"
|
||||
|
||||
namespace {
|
||||
constexpr int FILE_READ_CHUNK_SIZE = 4096;
|
||||
constexpr char HEX_CHARS[] = "0123456789abcdef";
|
||||
|
||||
#define HHB(v) (((v) & 0xF0) >> 4)
|
||||
#define LHB(v) ((v) & 0x0F)
|
||||
|
||||
std::string ComputeFileSha256(const std::string& path)
|
||||
{
|
||||
uint8_t out[SHA256_DIGEST_LENGTH];
|
||||
uint8_t buffer[FILE_READ_CHUNK_SIZE];
|
||||
|
||||
SHA256_CTX sha;
|
||||
SHA256_Init(&sha);
|
||||
|
||||
size_t nbytes = 0;
|
||||
std::unique_ptr<FILE, decltype(fclose)*> fptr(fopen(path.c_str(), "rb"), fclose);
|
||||
while ((nbytes = fread(buffer, 1, sizeof(buffer), fptr.get())) > 0) {
|
||||
SHA256_Update(&sha, buffer, nbytes);
|
||||
}
|
||||
SHA256_Final(out, &sha);
|
||||
|
||||
std::string result;
|
||||
result.reserve(SHA256_DIGEST_LENGTH + SHA256_DIGEST_LENGTH);
|
||||
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
|
||||
result.push_back(HEX_CHARS[HHB(out[i])]);
|
||||
result.push_back(HEX_CHARS[LHB(out[i])]);
|
||||
}
|
||||
|
||||
HILOG_DEBUG(LOG_CORE, "SHA256(%s): %s", path.c_str(), result.c_str());
|
||||
return result;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
PluginManager::~PluginManager() {}
|
||||
|
||||
void PluginManager::SetCommandPoller(const CommandPollerPtr& p)
|
||||
@ -30,7 +67,7 @@ void PluginManager::SetCommandPoller(const CommandPollerPtr& p)
|
||||
|
||||
bool PluginManager::AddPlugin(const std::string& pluginPath)
|
||||
{
|
||||
PluginModuleInfo info;
|
||||
PluginModuleInfo info = {0};
|
||||
|
||||
if (pluginIds_.find(pluginPath) != pluginIds_.end()) {
|
||||
HILOG_DEBUG(LOG_CORE, "already add");
|
||||
@ -62,7 +99,7 @@ bool PluginManager::AddPlugin(const std::string& pluginPath)
|
||||
RegisterPluginRequest request;
|
||||
request.set_request_id(commandPoller_->GetRequestId());
|
||||
request.set_path(pluginPath);
|
||||
request.set_sha256("");
|
||||
request.set_sha256(ComputeFileSha256(pluginPath));
|
||||
request.set_name(pluginPath);
|
||||
request.set_buffer_size_hint(0);
|
||||
RegisterPluginResponse response;
|
||||
@ -203,22 +240,22 @@ bool PluginManager::StartPluginSession(const std::vector<uint32_t>& pluginIds,
|
||||
HILOG_DEBUG(LOG_CORE, "plugin not find");
|
||||
return false;
|
||||
}
|
||||
auto configData = pluginModules_[id]->GetConfigData();
|
||||
if (!pluginModules_[id]->StartSession(
|
||||
reinterpret_cast<const uint8_t*>(configData.c_str()), configData.size())) {
|
||||
auto plugin = pluginModules_[id];
|
||||
auto cfgData = plugin->GetConfigData();
|
||||
if (!plugin->StartSession(reinterpret_cast<const uint8_t*>(cfgData.c_str()), cfgData.size())) {
|
||||
return false;
|
||||
}
|
||||
if (pluginModules_[id]->GetSampleMode() == PluginModule::POLLING) {
|
||||
if (plugin->GetSampleMode() == PluginModule::POLLING) {
|
||||
if (idx > config.size()) {
|
||||
HILOG_WARN(LOG_CORE, "idx %zu out of size %zu", idx, config.size());
|
||||
return false;
|
||||
}
|
||||
uint32_t sampleInterval = config[idx].sample_interval();
|
||||
auto interval = ScheduleTaskManager::ms(config[idx].sample_interval());
|
||||
std::string pluginName = config[idx].name();
|
||||
HILOG_DEBUG(LOG_CORE, "sampleInterval = %d", sampleInterval);
|
||||
HILOG_DEBUG(LOG_CORE, "name = %s", pluginName.c_str());
|
||||
if (!scheduleTaskManager_.ScheduleTask(pluginName, std::bind(&PluginManager::PullResult, this, id),
|
||||
ScheduleTaskManager::ms(sampleInterval))) {
|
||||
HILOG_DEBUG(LOG_CORE, "interval = %ld", static_cast<long>(interval.count()));
|
||||
HILOG_DEBUG(LOG_CORE, "pluginName = %s", pluginName.c_str());
|
||||
auto callback = std::bind(&PluginManager::PullResult, this, id);
|
||||
if (!scheduleTaskManager_.ScheduleTask(pluginName, callback, interval)) {
|
||||
HILOG_DEBUG(LOG_CORE, "ScheduleTask failed");
|
||||
return false;
|
||||
}
|
||||
@ -282,10 +319,8 @@ bool PluginManager::SubmitResult(const PluginResult& pluginResult)
|
||||
|
||||
bool PluginManager::PullResult(uint32_t pluginId)
|
||||
{
|
||||
HILOG_INFO(LOG_CORE, "%s: ready!", __func__);
|
||||
uint32_t size = 0;
|
||||
std::string name;
|
||||
HILOG_DEBUG(LOG_CORE, "PullResult pluginId = %d", pluginId);
|
||||
std::string name = "";
|
||||
auto it = pluginModules_.find(pluginId);
|
||||
if (it == pluginModules_.end()) {
|
||||
HILOG_DEBUG(LOG_CORE, "plugin not find");
|
||||
@ -293,19 +328,16 @@ bool PluginManager::PullResult(uint32_t pluginId)
|
||||
}
|
||||
pluginModules_[pluginId]->GetBufferSizeHint(size);
|
||||
pluginModules_[pluginId]->GetPluginName(name);
|
||||
std::unique_ptr<uint8_t[]> buffer {new (std::nothrow) uint8_t[size]};
|
||||
std::unique_ptr<uint8_t[]> buffer(new (std::nothrow) uint8_t[size]);
|
||||
if (buffer == nullptr) {
|
||||
HILOG_DEBUG(LOG_CORE, "buffer new failed!");
|
||||
} else {
|
||||
HILOG_DEBUG(LOG_CORE, "buffer new success!");
|
||||
return false;
|
||||
}
|
||||
|
||||
int length = it->second->ReportResult(buffer.get(), size);
|
||||
if (length < 0) {
|
||||
return false;
|
||||
}
|
||||
HILOG_DEBUG(LOG_CORE, "PullResult length = %d", length);
|
||||
HILOG_DEBUG(LOG_CORE, "PullResult name = %s", name.c_str());
|
||||
|
||||
ProfilerPluginData pluginData;
|
||||
pluginData.set_name(name);
|
||||
@ -319,14 +351,15 @@ bool PluginManager::PullResult(uint32_t pluginId)
|
||||
pluginData.set_tv_sec(ts.tv_sec);
|
||||
pluginData.set_tv_nsec(ts.tv_nsec);
|
||||
|
||||
auto writer = pluginModules_[pluginId]->GetWriter();
|
||||
auto writer = std::static_pointer_cast<BufferWriter>(pluginModules_[pluginId]->GetWriter());
|
||||
CHECK_NOTNULL(writer, false, "PullResult GetWriter nullptr");
|
||||
|
||||
std::static_pointer_cast<BufferWriter>(writer)->WriteProtobuf(pluginData);
|
||||
writer->WriteMessage(pluginData);
|
||||
writer->Flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PluginManager::CreateWriter(std::string pluginName, uint32_t bufferSize, int fd)
|
||||
bool PluginManager::CreateWriter(std::string pluginName, uint32_t bufferSize, int smbFd, int eventFd)
|
||||
{
|
||||
auto it = pluginIds_.find(pluginName);
|
||||
if (it == pluginIds_.end()) {
|
||||
@ -338,7 +371,7 @@ bool PluginManager::CreateWriter(std::string pluginName, uint32_t bufferSize, in
|
||||
if (bufferSize > 0) {
|
||||
HILOG_DEBUG(LOG_CORE, "%s Use ShareMemory %d", pluginName.c_str(), bufferSize);
|
||||
pluginModules_[index]->RegisterWriter(
|
||||
std::make_shared<BufferWriter>(pluginName, bufferSize, fd, commandPoller_, index));
|
||||
std::make_shared<BufferWriter>(pluginName, bufferSize, smbFd, eventFd, index));
|
||||
} else {
|
||||
HILOG_ERROR(LOG_CORE, "no shared memory buffer allocated!");
|
||||
return false;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "manager_interface.h"
|
||||
#include "plugin_module.h"
|
||||
#include "schedule_task_manager.h"
|
||||
|
||||
@ -28,7 +29,7 @@ class ProfilerPluginConfig;
|
||||
class PluginResult;
|
||||
class CommandPoller;
|
||||
|
||||
class PluginManager {
|
||||
class PluginManager : public ManagerInterface {
|
||||
public:
|
||||
virtual ~PluginManager();
|
||||
bool AddPlugin(const std::string& pluginPath);
|
||||
@ -50,7 +51,7 @@ public:
|
||||
|
||||
// for test
|
||||
virtual bool SubmitResult(const PluginResult& pluginResult);
|
||||
bool CreateWriter(std::string pluginName, uint32_t bufferSize, int fd);
|
||||
bool CreateWriter(std::string pluginName, uint32_t bufferSize, int smbFd, int eventFd);
|
||||
bool ResetWriter(uint32_t pluginId);
|
||||
void SetCommandPoller(const CommandPollerPtr& p);
|
||||
|
||||
|
@ -137,7 +137,7 @@ bool PluginModule::BindFunctions()
|
||||
return false;
|
||||
}
|
||||
if (structPtr_ == nullptr) {
|
||||
structPtr_ = (PluginModuleStruct*)dlsym(handle_, "g_pluginModule");
|
||||
structPtr_ = static_cast<PluginModuleStruct*>(dlsym(handle_, "g_pluginModule"));
|
||||
if (structPtr_ == nullptr) {
|
||||
HILOG_DEBUG(LOG_CORE, "structPtr_ == nullptr");
|
||||
return false;
|
||||
@ -165,7 +165,6 @@ bool PluginModule::StartSession(const uint8_t* buffer, uint32_t size)
|
||||
HILOG_DEBUG(LOG_CORE, "plugin not load");
|
||||
return false;
|
||||
}
|
||||
HILOG_DEBUG(LOG_CORE, "size = %u, ", size);
|
||||
|
||||
if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) {
|
||||
if (structPtr_->callbacks->onPluginSessionStart) {
|
||||
@ -192,8 +191,6 @@ bool PluginModule::StopSession()
|
||||
|
||||
int32_t PluginModule::ReportResult(uint8_t* buffer, uint32_t size)
|
||||
{
|
||||
HILOG_INFO(LOG_CORE, "%s: ready!", __func__);
|
||||
HILOG_DEBUG(LOG_CORE, "ReportResult");
|
||||
if (handle_ == nullptr) {
|
||||
HILOG_DEBUG(LOG_CORE, "plugin not open");
|
||||
return -1;
|
||||
@ -203,15 +200,11 @@ int32_t PluginModule::ReportResult(uint8_t* buffer, uint32_t size)
|
||||
first_ = false;
|
||||
} else {
|
||||
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
||||
std::chrono::duration<int, std::milli> interval =
|
||||
std::chrono::duration_cast<std::chrono::duration<int, std::milli>>(t1 - lastTime_);
|
||||
HILOG_DEBUG(LOG_CORE, "the id equals %u interval is %d milli seconds", size, interval.count());
|
||||
lastTime_ = t1;
|
||||
}
|
||||
|
||||
if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) {
|
||||
if (structPtr_->callbacks->onPluginReportResult != nullptr) {
|
||||
HILOG_INFO(LOG_CORE, "%s: call plugin ready!", __func__);
|
||||
return structPtr_->callbacks->onPluginReportResult(buffer, size);
|
||||
}
|
||||
}
|
||||
@ -223,6 +216,11 @@ bool PluginModule::RegisterWriter(const BufferWriterPtr writer)
|
||||
{
|
||||
writerAdapter_ = std::make_shared<WriterAdapter>();
|
||||
writerAdapter_->SetWriter(writer);
|
||||
|
||||
if (writer == nullptr) {
|
||||
HILOG_INFO(LOG_CORE, "BufferWriter is null, update WriterAdapter only!");
|
||||
return true;
|
||||
}
|
||||
if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) {
|
||||
if (structPtr_->callbacks->onRegisterWriterStruct != nullptr) {
|
||||
return structPtr_->callbacks->onRegisterWriterStruct(writerAdapter_->GetStruct());
|
||||
|
95
device/plugins/api/src/plugin_watcher.cpp
Executable file → Normal file
95
device/plugins/api/src/plugin_watcher.cpp
Executable file → Normal file
@ -19,6 +19,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <dirent.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -54,7 +55,7 @@ PluginWatcher::~PluginWatcher()
|
||||
monitorThread_.join();
|
||||
}
|
||||
|
||||
void PluginWatcher::ScanPlugins(const std::string& pluginDir)
|
||||
bool PluginWatcher::ScanPlugins(const std::string& pluginDir)
|
||||
{
|
||||
DIR* dir = nullptr;
|
||||
struct dirent* entry = nullptr;
|
||||
@ -63,7 +64,7 @@ void PluginWatcher::ScanPlugins(const std::string& pluginDir)
|
||||
HILOG_INFO(LOG_CORE, "scan plugin from directory %s", fullpath);
|
||||
dir = opendir(fullpath);
|
||||
if (dir == nullptr) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
while (true) {
|
||||
entry = readdir(dir);
|
||||
@ -80,10 +81,10 @@ void PluginWatcher::ScanPlugins(const std::string& pluginDir)
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PluginWatcher::WatchPlugins(const std::string& pluginDir)
|
||||
bool PluginWatcher::WatchPlugins(const std::string& pluginDir)
|
||||
{
|
||||
char fullpath[PATH_MAX + 1] = {0};
|
||||
realpath(pluginDir.c_str(), fullpath);
|
||||
@ -91,66 +92,80 @@ void PluginWatcher::WatchPlugins(const std::string& pluginDir)
|
||||
int wd = inotify_add_watch(inotifyFd_, fullpath, IN_ALL_EVENTS);
|
||||
if (wd < 0) {
|
||||
HILOG_INFO(LOG_CORE, "inotify_add_watch add directory %s failed", pluginDir.c_str());
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
HILOG_INFO(LOG_CORE, "inotify_add_watch add directory %s success", fullpath);
|
||||
std::lock_guard<std::mutex> guard(mtx_);
|
||||
wdToDir_.insert(std::pair<int, std::string>(wd, std::string(fullpath)));
|
||||
return true;
|
||||
}
|
||||
|
||||
void PluginWatcher::Monitor()
|
||||
|
||||
|
||||
bool PluginWatcher::MonitorIsSet()
|
||||
{
|
||||
const struct inotify_event* event = nullptr;
|
||||
char buffer[MAX_BUF_SIZE] = {'\0'};
|
||||
struct timeval time;
|
||||
char* ptr = nullptr;
|
||||
int ret = 0;
|
||||
|
||||
ssize_t readLength = read(inotifyFd_, buffer, MAX_BUF_SIZE);
|
||||
if (readLength == -1) {
|
||||
return false;
|
||||
}
|
||||
for (ptr = buffer; ptr < buffer + readLength; ptr += sizeof(struct inotify_event) + event->len) {
|
||||
event = reinterpret_cast<const struct inotify_event*>(ptr);
|
||||
std::unique_lock<std::mutex> guard(mtx_, std::adopt_lock);
|
||||
const std::string& pluginDir = wdToDir_[event->wd];
|
||||
guard.unlock();
|
||||
if (event->mask & IN_ISDIR) {
|
||||
continue;
|
||||
}
|
||||
std::string fileName = event->name;
|
||||
size_t pos = fileName.rfind(".so");
|
||||
if ((pos == std::string::npos) || (pos != fileName.length() - strlen(".so"))) {
|
||||
continue;
|
||||
}
|
||||
switch (event->mask) {
|
||||
case IN_CLOSE_WRITE:
|
||||
case IN_MOVED_TO:
|
||||
OnPluginAdded(pluginDir + '/' + fileName);
|
||||
break;
|
||||
case IN_DELETE:
|
||||
case IN_MOVED_FROM:
|
||||
OnPluginRemoved(pluginDir + '/' + fileName);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (memset_s(buffer, MAX_BUF_SIZE, 0, MAX_BUF_SIZE) != 0) {
|
||||
HILOG_ERROR(LOG_CORE, "memset_s error!");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PluginWatcher::Monitor()
|
||||
{
|
||||
struct timeval time;
|
||||
|
||||
pthread_setname_np(pthread_self(), "PluginWatcher");
|
||||
while (runMonitor_) {
|
||||
fd_set rFds;
|
||||
FD_ZERO(&rFds);
|
||||
FD_SET(inotifyFd_, &rFds);
|
||||
time.tv_sec = 1;
|
||||
time.tv_usec = 0;
|
||||
ret = select(inotifyFd_ + 1, &rFds, nullptr, nullptr, &time);
|
||||
int ret = select(inotifyFd_ + 1, &rFds, nullptr, nullptr, &time);
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
} else if (!ret) {
|
||||
continue;
|
||||
} else if (FD_ISSET(inotifyFd_, &rFds)) {
|
||||
ssize_t readLength = read(inotifyFd_, buffer, MAX_BUF_SIZE);
|
||||
if (readLength == -1) {
|
||||
if (!MonitorIsSet()) {
|
||||
continue;
|
||||
}
|
||||
for (ptr = buffer; ptr < buffer + readLength; ptr += sizeof(struct inotify_event) + event->len) {
|
||||
event = reinterpret_cast<const struct inotify_event*>(ptr);
|
||||
std::unique_lock<std::mutex> guard(mtx_, std::adopt_lock);
|
||||
const std::string& pluginDir = wdToDir_[event->wd];
|
||||
guard.unlock();
|
||||
if (event->mask & IN_ISDIR) {
|
||||
continue;
|
||||
}
|
||||
std::string fileName = event->name;
|
||||
size_t pos = fileName.rfind(".so");
|
||||
if (pos == std::string::npos || (pos != fileName.length() - strlen(".so"))) {
|
||||
continue;
|
||||
}
|
||||
switch (event->mask) {
|
||||
case IN_CLOSE_WRITE:
|
||||
case IN_MOVED_TO:
|
||||
OnPluginAdded(pluginDir + '/' + fileName);
|
||||
break;
|
||||
case IN_DELETE:
|
||||
case IN_MOVED_FROM:
|
||||
OnPluginRemoved(pluginDir + '/' + fileName);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (memset_s(buffer, MAX_BUF_SIZE, 0, MAX_BUF_SIZE) != EOK) {
|
||||
HILOG_ERROR(LOG_CORE, "memset_s error!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
9
device/plugins/api/src/plugin_watcher.h
Executable file → Normal file
9
device/plugins/api/src/plugin_watcher.h
Executable file → Normal file
@ -31,10 +31,8 @@ class PluginWatcher {
|
||||
public:
|
||||
explicit PluginWatcher(const PluginManagerPtr& pluginManager);
|
||||
~PluginWatcher();
|
||||
|
||||
void ScanPlugins(const std::string& pluginDir);
|
||||
|
||||
void WatchPlugins(const std::string& pluginDir);
|
||||
bool ScanPlugins(const std::string& pluginDir);
|
||||
bool WatchPlugins(const std::string& pluginDir);
|
||||
|
||||
private:
|
||||
int inotifyFd_;
|
||||
@ -43,11 +41,10 @@ private:
|
||||
std::thread monitorThread_;
|
||||
std::mutex mtx_;
|
||||
bool runMonitor_;
|
||||
|
||||
virtual void OnPluginAdded(const std::string& pluginPath);
|
||||
virtual void OnPluginRemoved(const std::string& pluginPath);
|
||||
void MonitorEventName(uint32_t mask, const std::string& fileName, const std::string& pluginDir);
|
||||
void Monitor();
|
||||
bool MonitorIsSet();
|
||||
};
|
||||
|
||||
#endif // !PLUGIN_WATCHER_H
|
||||
|
3
device/plugins/api/src/writer_adapter.cpp
Executable file → Normal file
3
device/plugins/api/src/writer_adapter.cpp
Executable file → Normal file
@ -40,7 +40,8 @@ const WriterStruct* WriterAdapter::GetStruct()
|
||||
|
||||
long WriterAdapter::WriteFunc(WriterStruct* writer, const void* data, size_t size)
|
||||
{
|
||||
WriterAdapter* writerAdaptor = reinterpret_cast<WriterAdapter*>(writer);
|
||||
static_assert(offsetof(WriterAdapter, writerStruct_) == 0, "unexpected alignment of writerStruct_!");
|
||||
WriterAdapter* writerAdaptor = reinterpret_cast<WriterAdapter*>(writer); // 转成 WriterAdapter*
|
||||
if (writerAdaptor && writerAdaptor->writer_) {
|
||||
return writerAdaptor->writer_->Write(data, size);
|
||||
}
|
||||
|
0
device/plugins/api/src/writer_adapter.h
Executable file → Normal file
0
device/plugins/api/src/writer_adapter.h
Executable file → Normal file
30
device/plugins/api/test/BUILD.gn
Executable file → Normal file
30
device/plugins/api/test/BUILD.gn
Executable file → Normal file
@ -16,49 +16,43 @@ import("../../../base/config.gni")
|
||||
|
||||
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
|
||||
config("module_private_config") {
|
||||
visibility = [":*"]
|
||||
visibility = [ ":*" ]
|
||||
}
|
||||
|
||||
config("cflags_config") {
|
||||
cflags = [
|
||||
"-Wno-sign-compare",
|
||||
"-pthread",
|
||||
"-Dprivate=public", #allow test code access private members
|
||||
"-Dprotected=public", #allow test code access private members
|
||||
"-Dprivate=public", #allow test code access private members
|
||||
"-Dprotected=public", #allow test code access private members
|
||||
]
|
||||
}
|
||||
|
||||
ohos_unittest("hiprofiler_plugins_ut") {
|
||||
module_out_path = module_output_path
|
||||
deps = [
|
||||
"../:plugins_sources",
|
||||
"${OHOS_PROFILER_DIR}/device/services/plugin_service:hiprofiler_plugin_service",
|
||||
"${OHOS_PROFILER_DIR}/device/services/profiler_service:profiler_service",
|
||||
"../:plugins_sources",
|
||||
"//third_party/googletest:gmock",
|
||||
"//third_party/googletest:gtest",
|
||||
]
|
||||
include_dirs = [
|
||||
"//third_party/googletest/googletest/include/gtest",
|
||||
]
|
||||
include_dirs = [ "//third_party/googletest/googletest/include/gtest" ]
|
||||
sources = [
|
||||
"unittest/writer_adapter_test.cpp",
|
||||
"unittest/buffer_write_test.cpp",
|
||||
"unittest/command_poller_test.cpp",
|
||||
"unittest/plugin_manager_test.cpp",
|
||||
"unittest/plugin_module_test.cpp",
|
||||
"unittest/plugin_watcher_test.cpp",
|
||||
"unittest/services_ipc_test.cpp",
|
||||
"unittest/services_profiler_service_test.cpp",
|
||||
"unittest/services_shared_memory_test.cpp",
|
||||
"unittest/services_plugin_service_test.cpp",
|
||||
"unittest/writer_adapter_test.cpp",
|
||||
]
|
||||
configs = [ ":cflags_config" ]
|
||||
external_deps = [
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
]
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}"
|
||||
resource_config_file = "${OHOS_PROFILER_DIR}/device/ohos_test.xml"
|
||||
}
|
||||
|
||||
group("unittest") {
|
||||
testonly = true
|
||||
deps = [
|
||||
":hiprofiler_plugins_ut",
|
||||
]
|
||||
deps = [ ":hiprofiler_plugins_ut" ]
|
||||
}
|
||||
|
205
device/plugins/api/test/unittest/buffer_write_test.cpp
Normal file
205
device/plugins/api/test/unittest/buffer_write_test.cpp
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <hwext/gtest-ext.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/syscall.h>
|
||||
#include "buffer_writer.h"
|
||||
#include "plugin_service_types.pb.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace {
|
||||
constexpr uint32_t SMB1_SIZE = 10 * 4096;
|
||||
constexpr uint32_t SMB2_SIZE = 10 * 4096;
|
||||
const std::string SMB1_NAME = "testsmb1";
|
||||
const std::string SMB2_NAME = "testsmb2";
|
||||
const std::string PLUGIN_NAME = "testplugin";
|
||||
void *g_smbAddr1 = nullptr;
|
||||
void *g_smbAddr2 = nullptr;
|
||||
int g_smbFd1 = 0;
|
||||
int g_smbFd2 = 0;
|
||||
|
||||
int InitShareMemory1()
|
||||
{
|
||||
int fd = syscall(SYS_memfd_create, SMB1_NAME.c_str(), 0);
|
||||
CHECK_TRUE(fd >= 0, false, "CreateBlock FAIL SYS_memfd_create");
|
||||
|
||||
int check = ftruncate(fd, SMB1_SIZE);
|
||||
if (check < 0) {
|
||||
close(fd);
|
||||
HILOG_ERROR(LOG_CORE, "CreateBlock ftruncate ERR : %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_smbAddr1 = mmap(nullptr, SMB1_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (g_smbAddr1 == MAP_FAILED) {
|
||||
close(fd);
|
||||
HILOG_ERROR(LOG_CORE, "CreateBlock g_smbAddr1 mmap ERR : %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ShareMemoryBlock::BlockHeader* header_ = reinterpret_cast<ShareMemoryBlock::BlockHeader*>(g_smbAddr1);
|
||||
|
||||
// initialize header infos
|
||||
header_->info.readOffset_ = 0;
|
||||
header_->info.writeOffset_ = 0;
|
||||
header_->info.memorySize_ = SMB1_SIZE - sizeof(ShareMemoryBlock::BlockHeader);
|
||||
header_->info.bytesCount_ = 0;
|
||||
header_->info.chunkCount_ = 0;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int InitShareMemory2()
|
||||
{
|
||||
int fd = syscall(SYS_memfd_create, SMB2_NAME.c_str(), 0);
|
||||
CHECK_TRUE(fd >= 0, false, "CreateBlock FAIL SYS_memfd_create");
|
||||
|
||||
int check = ftruncate(fd, SMB2_SIZE);
|
||||
if (check < 0) {
|
||||
close(fd);
|
||||
HILOG_ERROR(LOG_CORE, "CreateBlock ftruncate ERR : %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_smbAddr2 = mmap(nullptr, SMB2_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (g_smbAddr2 == MAP_FAILED) {
|
||||
close(fd);
|
||||
HILOG_ERROR(LOG_CORE, "CreateBlock g_smbAddr2 mmap ERR : %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ShareMemoryBlock::BlockHeader* header_ = reinterpret_cast<ShareMemoryBlock::BlockHeader*>(g_smbAddr2);
|
||||
|
||||
// initialize header infos
|
||||
header_->info.readOffset_ = 0;
|
||||
header_->info.writeOffset_ = 0;
|
||||
header_->info.memorySize_ = SMB2_SIZE - sizeof(ShareMemoryBlock::BlockHeader);
|
||||
header_->info.bytesCount_ = 0;
|
||||
header_->info.chunkCount_ = 0;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
class BufferWriteTest : public ::testing::Test {
|
||||
protected:
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
g_smbFd1 = InitShareMemory1();
|
||||
g_smbFd2 = InitShareMemory2();
|
||||
printf("SetUpTestCase success\n");
|
||||
}
|
||||
static void TearDownTestCase() {}
|
||||
};
|
||||
|
||||
bool CheckBuffer(uint8_t *buffer, size_t size)
|
||||
{
|
||||
ShareMemoryBlock::BlockHeader* header_ = reinterpret_cast<ShareMemoryBlock::BlockHeader*>(g_smbAddr1);
|
||||
uint8_t *cmpaddr = (uint8_t *)g_smbAddr1 + sizeof(ShareMemoryBlock::BlockHeader) + header_->info.readOffset_;
|
||||
uint32_t cmpsize = *(uint32_t*)cmpaddr;
|
||||
cmpaddr = cmpaddr + sizeof(uint32_t);
|
||||
ProfilerPluginData pluginData;
|
||||
pluginData.ParseFromArray(cmpaddr, cmpsize);
|
||||
const char* data = pluginData.data().c_str();
|
||||
|
||||
header_->info.readOffset_ = header_->info.writeOffset_;
|
||||
if (memcmp(buffer, data, size) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CheckMessage(uint8_t *buffer, size_t size)
|
||||
{
|
||||
ShareMemoryBlock::BlockHeader* header_ = reinterpret_cast<ShareMemoryBlock::BlockHeader*>(g_smbAddr2);
|
||||
uint8_t *cmpaddr = (uint8_t *)g_smbAddr2 + sizeof(ShareMemoryBlock::BlockHeader) + header_->info.readOffset_;
|
||||
cmpaddr = cmpaddr + sizeof(uint32_t);
|
||||
header_->info.readOffset_ = header_->info.writeOffset_;
|
||||
|
||||
if (memcmp(buffer, cmpaddr, size) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Write data to shared memory through writer.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(BufferWriteTest, WriteTest, TestSize.Level1)
|
||||
{
|
||||
auto write = std::make_shared<BufferWriter>(PLUGIN_NAME, SMB1_SIZE, g_smbFd1, -1, 0);
|
||||
|
||||
uint8_t buffer1[] = {0x55, 0xAA, 0x55, 0xAA};
|
||||
uint8_t buffer2[] = {0x11, 0x22, 0x33, 0x44};
|
||||
uint8_t buffer3[] = {0xAA, 0xBB, 0xCC, 0xDD};
|
||||
|
||||
EXPECT_TRUE(write->Write(buffer1, sizeof(buffer1)));
|
||||
EXPECT_TRUE(CheckBuffer(buffer1, sizeof(buffer1)));
|
||||
EXPECT_TRUE(write->Write(buffer2, sizeof(buffer2)));
|
||||
EXPECT_TRUE(CheckBuffer(buffer2, sizeof(buffer2)));
|
||||
EXPECT_TRUE(write->Write(buffer3, sizeof(buffer3)));
|
||||
EXPECT_TRUE(CheckBuffer(buffer3, sizeof(buffer3)));
|
||||
EXPECT_FALSE(write->Write(nullptr, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Write data to shared memory through writer.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(BufferWriteTest, WriteMessageTest, TestSize.Level1)
|
||||
{
|
||||
uint8_t data[1024];
|
||||
auto write = std::make_shared<BufferWriter>(PLUGIN_NAME, SMB2_SIZE, g_smbFd2, -1, 0);
|
||||
|
||||
ProfilerPluginConfig configData;
|
||||
configData.set_name("111");
|
||||
configData.set_plugin_sha256("222");
|
||||
configData.set_sample_interval(1000);
|
||||
size_t size = configData.ByteSizeLong();
|
||||
configData.SerializeToArray(data, size);
|
||||
|
||||
EXPECT_TRUE(write->WriteMessage(configData));
|
||||
EXPECT_TRUE(CheckMessage(data, size));
|
||||
|
||||
ProfilerPluginState stateData;
|
||||
stateData.set_name("st");
|
||||
stateData.set_state(ProfilerPluginState::IN_SESSION);
|
||||
size = stateData.ByteSizeLong();
|
||||
stateData.SerializeToArray(data, size);
|
||||
|
||||
EXPECT_TRUE(write->WriteMessage(stateData));
|
||||
EXPECT_TRUE(CheckMessage(data, size));
|
||||
|
||||
|
||||
ProfilerPluginData pluginData;
|
||||
pluginData.set_name("test");
|
||||
pluginData.set_status(1);
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
pluginData.set_clock_id(ProfilerPluginData::CLOCKID_REALTIME);
|
||||
pluginData.set_tv_sec(ts.tv_sec);
|
||||
pluginData.set_tv_nsec(ts.tv_nsec);
|
||||
size = pluginData.ByteSizeLong();
|
||||
pluginData.SerializeToArray(data, size);
|
||||
|
||||
EXPECT_TRUE(write->WriteMessage(pluginData));
|
||||
EXPECT_TRUE(CheckMessage(data, size));
|
||||
}
|
||||
} // namespace
|
208
device/plugins/api/test/unittest/command_poller_test.cpp
Normal file
208
device/plugins/api/test/unittest/command_poller_test.cpp
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <hwext/gtest-ext.h>
|
||||
#include <hwext/gtest-tag.h>
|
||||
|
||||
#include "command_poller.h"
|
||||
|
||||
#include "plugin_manager.h"
|
||||
#include "plugin_service.ipc.h"
|
||||
#include "socket_context.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace {
|
||||
class PluginManagerStub final : public ManagerInterface {
|
||||
public:
|
||||
virtual bool LoadPlugin(const std::string& pluginPath) override
|
||||
{
|
||||
if (pluginPath == "existplugin") {
|
||||
return true;
|
||||
} else if (pluginPath == "noexistplugin") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual bool UnloadPlugin(const std::string& pluginPath)
|
||||
{
|
||||
if (pluginPath == "existplugin") {
|
||||
return true;
|
||||
} else if (pluginPath == "noexistplugin") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual bool UnloadPlugin(const uint32_t pluginId)
|
||||
{
|
||||
if (pluginId == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool CreatePluginSession(const std::vector<ProfilerPluginConfig>& config)
|
||||
{
|
||||
if (config[0].name() == "existplugin") {
|
||||
return true;
|
||||
} else if (config[0].name() == "noexistplugin") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual bool DestroyPluginSession(const std::vector<uint32_t>& pluginIds)
|
||||
{
|
||||
if (pluginIds[0] != 1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual bool StartPluginSession(const std::vector<uint32_t>& pluginIds,
|
||||
const std::vector<ProfilerPluginConfig>& config)
|
||||
{
|
||||
if (pluginIds[0] == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (config[0].name() == "existplugin") {
|
||||
return true;
|
||||
} else if (config[0].name() == "noexistplugin") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual bool StopPluginSession(const std::vector<uint32_t>& pluginIds)
|
||||
{
|
||||
if (pluginIds[0] == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool CreateWriter(std::string pluginName, uint32_t bufferSize, int smbFd, int eventFd)
|
||||
{
|
||||
if (bufferSize == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual bool ResetWriter(uint32_t pluginId)
|
||||
{
|
||||
if (pluginId == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual void SetCommandPoller(const std::shared_ptr<CommandPoller>& p)
|
||||
{
|
||||
this->commandPoller_ = p;
|
||||
}
|
||||
private:
|
||||
CommandPollerPtr commandPoller_;
|
||||
};
|
||||
|
||||
|
||||
class CommandPollerTest : public ::testing::Test {
|
||||
protected:
|
||||
static void SetUpTestCase() {}
|
||||
static void TearDownTestCase() {}
|
||||
};
|
||||
|
||||
HWTEST_F(CommandPollerTest, CreateCmdTest, TestSize.Level1)
|
||||
{
|
||||
auto pluginManage = std::make_shared<PluginManagerStub>();
|
||||
auto commandPoller = std::make_shared<CommandPoller>(pluginManage);
|
||||
pluginManage->SetCommandPoller(commandPoller);
|
||||
|
||||
CreateSessionCmd successCmd;
|
||||
CreateSessionCmd failed1Cmd;
|
||||
CreateSessionCmd failed2Cmd;
|
||||
CreateSessionCmd failed3Cmd;
|
||||
SocketContext ctx;
|
||||
|
||||
successCmd.add_buffer_sizes(1024);
|
||||
successCmd.add_plugin_configs()->set_name("existplugin");
|
||||
|
||||
failed1Cmd.add_buffer_sizes(0);
|
||||
failed1Cmd.add_plugin_configs()->set_name("existplugin");
|
||||
|
||||
failed2Cmd.add_buffer_sizes(0);
|
||||
failed2Cmd.add_plugin_configs()->set_name("noexistplugin");
|
||||
|
||||
failed3Cmd.add_buffer_sizes(1);
|
||||
failed3Cmd.add_plugin_configs()->set_name("noexistplugin");
|
||||
EXPECT_TRUE(commandPoller->OnCreateSessionCmd(successCmd, ctx));
|
||||
EXPECT_FALSE(commandPoller->OnCreateSessionCmd(failed1Cmd, ctx));
|
||||
EXPECT_FALSE(commandPoller->OnCreateSessionCmd(failed2Cmd, ctx));
|
||||
EXPECT_FALSE(commandPoller->OnCreateSessionCmd(failed3Cmd, ctx));
|
||||
}
|
||||
|
||||
HWTEST_F(CommandPollerTest, StartCmdTest, TestSize.Level1)
|
||||
{
|
||||
auto pluginManage = std::make_shared<PluginManagerStub>();
|
||||
auto commandPoller = std::make_shared<CommandPoller>(pluginManage);
|
||||
pluginManage->SetCommandPoller(commandPoller);
|
||||
|
||||
StartSessionCmd successCmd;
|
||||
successCmd.add_plugin_ids(1);
|
||||
successCmd.add_plugin_configs()->set_name("existplugin");
|
||||
StartSessionCmd failed1Cmd;
|
||||
|
||||
failed1Cmd.add_plugin_ids(0);
|
||||
failed1Cmd.add_plugin_configs()->set_name("existplugin");
|
||||
|
||||
StartSessionCmd failed2Cmd;
|
||||
failed2Cmd.add_plugin_ids(1);
|
||||
failed2Cmd.add_plugin_configs()->set_name("noexistplugin");
|
||||
|
||||
EXPECT_TRUE(commandPoller->OnStartSessionCmd(successCmd));
|
||||
EXPECT_FALSE(commandPoller->OnStartSessionCmd(failed1Cmd));
|
||||
EXPECT_FALSE(commandPoller->OnStartSessionCmd(failed2Cmd));
|
||||
}
|
||||
|
||||
HWTEST_F(CommandPollerTest, StopCmdTest, TestSize.Level1)
|
||||
{
|
||||
auto pluginManage = std::make_shared<PluginManagerStub>();
|
||||
auto commandPoller = std::make_shared<CommandPoller>(pluginManage);
|
||||
pluginManage->SetCommandPoller(commandPoller);
|
||||
|
||||
StopSessionCmd successCmd;
|
||||
successCmd.add_plugin_ids(1);
|
||||
StopSessionCmd failedCmd;
|
||||
failedCmd.add_plugin_ids(0);
|
||||
EXPECT_TRUE(commandPoller->OnStopSessionCmd(successCmd));
|
||||
EXPECT_FALSE(commandPoller->OnStopSessionCmd(failedCmd));
|
||||
}
|
||||
|
||||
HWTEST_F(CommandPollerTest, DestoryCmdTest, TestSize.Level1)
|
||||
{
|
||||
auto pluginManage = std::make_shared<PluginManagerStub>();
|
||||
auto commandPoller = std::make_shared<CommandPoller>(pluginManage);
|
||||
pluginManage->SetCommandPoller(commandPoller);
|
||||
DestroySessionCmd successCmd;
|
||||
DestroySessionCmd failed1Cmd;
|
||||
DestroySessionCmd failed2Cmd;
|
||||
DestroySessionCmd failed3Cmd;
|
||||
successCmd.add_plugin_ids(1);
|
||||
failed1Cmd.add_plugin_ids(0);
|
||||
failed2Cmd.add_plugin_ids(2);
|
||||
failed3Cmd.add_plugin_ids(3);
|
||||
EXPECT_TRUE(commandPoller->OnDestroySessionCmd(successCmd));
|
||||
EXPECT_FALSE(commandPoller->OnDestroySessionCmd(failed1Cmd));
|
||||
EXPECT_FALSE(commandPoller->OnDestroySessionCmd(failed2Cmd));
|
||||
EXPECT_FALSE(commandPoller->OnDestroySessionCmd(failed3Cmd));
|
||||
}
|
||||
}
|
@ -32,8 +32,12 @@ using google::protobuf::Message;
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace {
|
||||
constexpr int DEFAULT_BUFFER_SIZE = 4096;
|
||||
constexpr int DEFAULT_SLEEP_TIME = 1000;
|
||||
const static std::string SUCCESS_PLUGIN_NAME = "libmemdataplugin.z.so";
|
||||
std::string g_testPluginDir("/data/local/tmp/");
|
||||
std::string g_testPluginDir("/system/lib/");
|
||||
int g_hiprofilerProcessNum = -1;
|
||||
const std::string DEFAULT_HIPROFILERD_PATH("/system/lib/hiprofilerd");
|
||||
|
||||
class PluginManagerTest : public ::testing::Test {
|
||||
protected:
|
||||
@ -54,10 +58,29 @@ protected:
|
||||
printf("======> pluginDir = %s\n", g_testPluginDir.c_str());
|
||||
|
||||
std::this_thread::sleep_for(TEMP_DELAY);
|
||||
|
||||
int processNum = fork();
|
||||
std::cout << "processNum : " << processNum << std::endl;
|
||||
if (processNum == 0) {
|
||||
// start running hiprofilerd
|
||||
std::string cmd = "chmod 777 " + DEFAULT_HIPROFILERD_PATH;
|
||||
std::cout << "cmd : " << cmd << std::endl;
|
||||
system(cmd.c_str());
|
||||
execl(DEFAULT_HIPROFILERD_PATH.c_str(), nullptr, nullptr);
|
||||
_exit(1);
|
||||
} else {
|
||||
g_hiprofilerProcessNum = processNum;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(DEFAULT_SLEEP_TIME));
|
||||
printf("SetUpTestCase success\n");
|
||||
}
|
||||
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
std::string stopCmd = "kill " + std::to_string(g_hiprofilerProcessNum);
|
||||
std::cout << "stop command : " << stopCmd << std::endl;
|
||||
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(stopCmd.c_str(), "r"), pclose);
|
||||
}
|
||||
};
|
||||
|
||||
@ -75,33 +98,30 @@ HWTEST_F(PluginManagerTest, SuccessPlugin, TestSize.Level1)
|
||||
const uint8_t configData[] = {0x30, 0x01, 0x38, 0x01, 0x42, 0x01, 0x01};
|
||||
ProfilerPluginConfig config;
|
||||
const std::vector<uint32_t> pluginIdsVector = {1};
|
||||
config.set_name(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME);
|
||||
config.set_name(g_testPluginDir + SUCCESS_PLUGIN_NAME);
|
||||
config.set_config_data((const void*)configData, 7);
|
||||
config.set_sample_interval(1000);
|
||||
config.set_sample_interval(DEFAULT_SLEEP_TIME);
|
||||
|
||||
EXPECT_FALSE(pluginManage->LoadPlugin(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->UnloadPlugin(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->AddPlugin(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->AddPlugin(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->RemovePlugin(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->RemovePlugin(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->AddPlugin(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->LoadPlugin(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->LoadPlugin(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->UnloadPlugin(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->LoadPlugin(g_testPluginDir + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->UnloadPlugin(g_testPluginDir + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_TRUE(pluginManage->AddPlugin(g_testPluginDir + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->AddPlugin(g_testPluginDir + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_TRUE(pluginManage->RemovePlugin(g_testPluginDir + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->RemovePlugin(g_testPluginDir + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_TRUE(pluginManage->AddPlugin(g_testPluginDir + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_TRUE(pluginManage->LoadPlugin(g_testPluginDir + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_FALSE(pluginManage->LoadPlugin(g_testPluginDir + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_TRUE(pluginManage->UnloadPlugin(g_testPluginDir + SUCCESS_PLUGIN_NAME));
|
||||
|
||||
EXPECT_FALSE(pluginManage->LoadPlugin(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME));
|
||||
EXPECT_TRUE(pluginManage->LoadPlugin(g_testPluginDir + SUCCESS_PLUGIN_NAME));
|
||||
|
||||
std::vector<ProfilerPluginConfig> configVec;
|
||||
configVec.push_back(config);
|
||||
EXPECT_FALSE(pluginManage->CreatePluginSession(configVec));
|
||||
|
||||
EXPECT_FALSE(pluginManage->StartPluginSession(pluginIdsVector, configVec));
|
||||
EXPECT_TRUE(pluginManage->CreatePluginSession(configVec));
|
||||
EXPECT_TRUE(pluginManage->StartPluginSession(pluginIdsVector, configVec));
|
||||
std::this_thread::sleep_for(TEMP_DELAY);
|
||||
|
||||
EXPECT_FALSE(pluginManage->StopPluginSession(pluginIdsVector));
|
||||
|
||||
EXPECT_FALSE(pluginManage->DestroyPluginSession(pluginIdsVector));
|
||||
EXPECT_TRUE(pluginManage->StopPluginSession(pluginIdsVector));
|
||||
EXPECT_TRUE(pluginManage->DestroyPluginSession(pluginIdsVector));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,7 +132,14 @@ HWTEST_F(PluginManagerTest, SuccessPlugin, TestSize.Level1)
|
||||
HWTEST_F(PluginManagerTest, GetSampleMode, TestSize.Level1)
|
||||
{
|
||||
PluginModule pluginModule;
|
||||
pluginModule.GetSampleMode();
|
||||
if (pluginModule.structPtr_ && pluginModule.structPtr_->callbacks) {
|
||||
if (pluginModule.structPtr_->callbacks->onPluginReportResult != nullptr) {
|
||||
EXPECT_EQ(pluginModule.GetSampleMode(), PluginModule::SampleMode::POLLING);
|
||||
} else if (pluginModule.structPtr_->callbacks->onRegisterWriterStruct != nullptr) {
|
||||
EXPECT_EQ(pluginModule.GetSampleMode(), PluginModule::SampleMode::STREAMING);
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(pluginModule.GetSampleMode(), PluginModule::SampleMode::UNKNOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,25 +151,30 @@ HWTEST_F(PluginManagerTest, PluginManager, TestSize.Level1)
|
||||
{
|
||||
PluginManager pluginManager;
|
||||
PluginModuleInfo info;
|
||||
pluginManager.UnloadPlugin(0);
|
||||
EXPECT_FALSE(pluginManager.UnloadPlugin(0));
|
||||
PluginResult pluginResult;
|
||||
pluginManager.SubmitResult(pluginResult);
|
||||
pluginManager.PullResult(0);
|
||||
pluginManager.CreateWriter("", 0, -1);
|
||||
pluginManager.ResetWriter(-1);
|
||||
EXPECT_FALSE(pluginManager.SubmitResult(pluginResult));
|
||||
EXPECT_FALSE(pluginManager.PullResult(0));
|
||||
EXPECT_FALSE(pluginManager.CreateWriter("", 0, -1, -1));
|
||||
EXPECT_FALSE(pluginManager.ResetWriter(-1));
|
||||
|
||||
PluginModule pluginModule;
|
||||
pluginModule.ComputeSha256();
|
||||
pluginModule.Unload();
|
||||
pluginModule.GetInfo(info);
|
||||
EXPECT_EQ(pluginModule.ComputeSha256(), "");
|
||||
EXPECT_FALSE(pluginModule.Unload());
|
||||
EXPECT_FALSE(pluginModule.GetInfo(info));
|
||||
std::string str("memory-plugin");
|
||||
pluginModule.GetPluginName(str);
|
||||
EXPECT_FALSE(pluginModule.GetPluginName(str));
|
||||
uint32_t num = 0;
|
||||
pluginModule.GetBufferSizeHint(num);
|
||||
pluginModule.IsLoaded();
|
||||
EXPECT_FALSE(pluginModule.GetBufferSizeHint(num));
|
||||
EXPECT_FALSE(pluginModule.IsLoaded());
|
||||
|
||||
BufferWriter bufferWriter("", 0, -1, nullptr, 0);
|
||||
bufferWriter.Write(nullptr, 0);
|
||||
bufferWriter.Flush();
|
||||
BufferWriter bufferWriter("test", DEFAULT_BUFFER_SIZE, -1, -1, 0);
|
||||
|
||||
EXPECT_EQ(bufferWriter.shareMemoryBlock_, nullptr);
|
||||
EXPECT_FALSE(bufferWriter.Write(str.data(), str.size()));
|
||||
bufferWriter.shareMemoryBlock_ =
|
||||
ShareMemoryAllocator::GetInstance().CreateMemoryBlockLocal("test", DEFAULT_BUFFER_SIZE);
|
||||
EXPECT_TRUE(bufferWriter.Write(str.data(), str.size()));
|
||||
EXPECT_TRUE(bufferWriter.Flush());
|
||||
}
|
||||
} // namespace
|
||||
|
143
device/plugins/api/test/unittest/plugin_module_test.cpp
Normal file
143
device/plugins/api/test/unittest/plugin_module_test.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <hwext/gtest-ext.h>
|
||||
#include <hwext/gtest-tag.h>
|
||||
#include <thread>
|
||||
|
||||
#include "plugin_module.h"
|
||||
#include "common_types.pb.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace {
|
||||
const static std::string SUCCESS_PLUGIN_NAME = "libmemdataplugin.z.so";
|
||||
constexpr size_t READ_BUFFER_SIZE = 4 * 1024 * 1024;
|
||||
std::string g_testPluginDir("/system/lib/");
|
||||
|
||||
class PluginModuleTest : public ::testing::Test {
|
||||
protected:
|
||||
static constexpr auto TEMP_DELAY = std::chrono::milliseconds(20);
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
char pluginDir[PATH_MAX + 1] = {0};
|
||||
if (readlink("/proc/self/exe", pluginDir, PATH_MAX) > 0) {
|
||||
char* pos = strrchr(pluginDir, '/');
|
||||
if (pos != nullptr) {
|
||||
*(pos++) = '\0';
|
||||
printf("-----> pluginModuleDir = %s\n", pluginDir);
|
||||
g_testPluginDir = pluginDir;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
printf("======> pluginModuleDir = %s\n", g_testPluginDir.c_str());
|
||||
|
||||
std::this_thread::sleep_for(TEMP_DELAY);
|
||||
printf("SetUpTestCase success\n");
|
||||
}
|
||||
|
||||
static void TearDownTestCase() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: pluginmodule normal test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(PluginModuleTest, PluginModuleNormal, TestSize.Level1)
|
||||
{
|
||||
std::string pluginPath = g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME;
|
||||
PluginModuleInfo info;
|
||||
auto plugin = std::make_shared<PluginModule>(pluginPath);
|
||||
EXPECT_TRUE(plugin->Load());
|
||||
EXPECT_TRUE(plugin->BindFunctions());
|
||||
EXPECT_TRUE(plugin->GetInfo(info));
|
||||
EXPECT_TRUE(plugin->IsLoaded());
|
||||
|
||||
uint32_t size = 0;
|
||||
plugin->GetBufferSizeHint(size);
|
||||
EXPECT_EQ(size, READ_BUFFER_SIZE);
|
||||
|
||||
std::string name;
|
||||
plugin->GetPluginName(name);
|
||||
EXPECT_STREQ(name.c_str(), "memory-plugin");
|
||||
|
||||
const uint8_t configData[] = {74, 1, 10};
|
||||
ProfilerPluginConfig config;
|
||||
config.set_name(g_testPluginDir + "/" + SUCCESS_PLUGIN_NAME);
|
||||
config.set_config_data((const void*)configData, 3);
|
||||
config.set_sample_interval(1000);
|
||||
plugin->SetConfigData(config.config_data());
|
||||
|
||||
std::string cfgData = plugin->GetConfigData();
|
||||
EXPECT_EQ(cfgData.c_str()[0], 74);
|
||||
EXPECT_EQ(cfgData.c_str()[1], 1);
|
||||
EXPECT_EQ(cfgData.c_str()[2], 10);
|
||||
|
||||
std::unique_ptr<uint8_t[]> buffer(new (std::nothrow) uint8_t[size]);
|
||||
EXPECT_NE(buffer, nullptr);
|
||||
EXPECT_TRUE(plugin->StartSession(reinterpret_cast<const uint8_t*>(cfgData.c_str()), cfgData.size()));
|
||||
EXPECT_NE(plugin->ReportResult(buffer.get(), size), 0);
|
||||
EXPECT_TRUE(plugin->StopSession());
|
||||
|
||||
EXPECT_TRUE(plugin->StartSession(nullptr, 0));
|
||||
EXPECT_EQ(plugin->ReportResult(buffer.get(), size), 0);
|
||||
EXPECT_TRUE(plugin->StopSession());
|
||||
|
||||
EXPECT_TRUE(plugin->StartSession(reinterpret_cast<const uint8_t*>(cfgData.c_str()), cfgData.size()));
|
||||
EXPECT_NE(plugin->ReportResult(nullptr, 0), 0);
|
||||
EXPECT_NE(plugin->ReportResult(nullptr, 0), -1);
|
||||
EXPECT_TRUE(plugin->StopSession());
|
||||
|
||||
EXPECT_TRUE(plugin->StartSession(nullptr, 0));
|
||||
EXPECT_EQ(plugin->ReportResult(nullptr, 0), 0);
|
||||
EXPECT_TRUE(plugin->StopSession());
|
||||
|
||||
EXPECT_TRUE(plugin->Unload());
|
||||
EXPECT_FALSE(plugin->IsLoaded());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: pluginmodule abnormal test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(PluginModuleTest, PluginModuleAbnormal, TestSize.Level1)
|
||||
{
|
||||
std::string pluginPath = "invalid.z.so";
|
||||
PluginModuleInfo info;
|
||||
auto plugin = std::make_shared<PluginModule>(pluginPath);
|
||||
EXPECT_FALSE(plugin->Load());
|
||||
EXPECT_FALSE(plugin->BindFunctions());
|
||||
EXPECT_FALSE(plugin->GetInfo(info));
|
||||
EXPECT_FALSE(plugin->IsLoaded());
|
||||
|
||||
uint32_t size = 0;
|
||||
plugin->GetBufferSizeHint(size);
|
||||
EXPECT_EQ(size, 0);
|
||||
|
||||
std::string name;
|
||||
plugin->GetPluginName(name);
|
||||
EXPECT_STREQ(name.c_str(), "");
|
||||
|
||||
std::unique_ptr<uint8_t[]> buffer(new (std::nothrow) uint8_t[size]);
|
||||
EXPECT_NE(buffer, nullptr);
|
||||
EXPECT_FALSE(plugin->StartSession(nullptr, 0));
|
||||
EXPECT_EQ(plugin->ReportResult(buffer.get(), size), -1);
|
||||
EXPECT_FALSE(plugin->StopSession());
|
||||
EXPECT_FALSE(plugin->Unload());
|
||||
}
|
||||
} // namespace
|
272
device/plugins/api/test/unittest/plugin_watcher_test.cpp
Executable file → Normal file
272
device/plugins/api/test/unittest/plugin_watcher_test.cpp
Executable file → Normal file
@ -29,27 +29,15 @@
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace {
|
||||
static std::vector<std::string> g_cmpFileList;
|
||||
static std::vector<std::string> g_createFileList = {
|
||||
"lib_6.so", "lib_5.so", "lib_8.so", "lib_4.so", "test1.txt"
|
||||
};
|
||||
std::vector<int> g_createFdList;
|
||||
|
||||
static std::vector<std::string> g_addFileList = {
|
||||
"libadd_6.so", "libadd_5.so", "libadd_8.so", "libadd_4.so", "test2.txt"
|
||||
};
|
||||
|
||||
static std::vector<std::string> g_expectFileList = {
|
||||
"libadd_6.so", "libadd_5.so", "libadd_8.so", "libadd_4.so",
|
||||
"lib_6.so", "lib_5.so", "lib_8.so", "lib_4.so"
|
||||
};
|
||||
|
||||
static int g_defaultFileMode = 0777;
|
||||
constexpr int DEAFULT_FILE_MODE = 0777;
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
const static std::string DEFAULT_TEST_PATH = "./";
|
||||
#else
|
||||
const static std::string DEFAULT_TEST_PATH = "/data/local/tmp/";
|
||||
const static std::string DEFAULT_TEST_PATH_1 = "/data/local/tmp/watchertest/1/";
|
||||
const static std::string DEFAULT_TEST_PATH_2 = "/data/local/tmp/watchertest/2/";
|
||||
const static std::string DEFAULT_TEST_PATH_3 = "/data/local/tmp/watchertest/3/";
|
||||
const static std::string NO_EXIST_TEST_PATH = "/data/local/tmp/noexist/";
|
||||
#endif
|
||||
|
||||
class PluginWatchTest : public ::testing::Test {
|
||||
@ -58,8 +46,98 @@ protected:
|
||||
static void SetUpTestCase() {}
|
||||
static void TearDownTestCase() {}
|
||||
|
||||
void SetUp() override {}
|
||||
void TearDown() override {}
|
||||
void SetUp() override
|
||||
{
|
||||
std::string cmd = "mkdir -p " + DEFAULT_TEST_PATH_1;
|
||||
system(cmd.c_str());
|
||||
cmd = "mkdir -p " + DEFAULT_TEST_PATH_2;
|
||||
system(cmd.c_str());
|
||||
cmd = "mkdir -p " + DEFAULT_TEST_PATH_3;
|
||||
system(cmd.c_str());
|
||||
sort(expectFileList.begin(), expectFileList.end());
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
cmpFileList.clear();
|
||||
}
|
||||
|
||||
void OnPluginAddedStub(const std::string& path)
|
||||
{
|
||||
cmpFileList.push_back(path);
|
||||
sort(cmpFileList.begin(), cmpFileList.end());
|
||||
}
|
||||
|
||||
void OnPluginRemovedStub(const std::string& path)
|
||||
{
|
||||
for (auto iter = cmpFileList.cbegin(); iter != cmpFileList.cend(); iter++) {
|
||||
if (*iter == path) {
|
||||
cmpFileList.erase(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CreateFile(std::string dirPath) const
|
||||
{
|
||||
for (auto it : createFileList) {
|
||||
int fd = creat((dirPath + it).c_str(), DEAFULT_FILE_MODE);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
void AddFile(std::string dirPath) const
|
||||
{
|
||||
for (auto it : addFileList) {
|
||||
int fd = creat((dirPath + it).c_str(), DEAFULT_FILE_MODE);
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
write(fd, "testcase", 1);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
void DeleteFile(std::string dirPath) const
|
||||
{
|
||||
for (auto it : createFileList) {
|
||||
remove((dirPath + it).c_str());
|
||||
}
|
||||
for (auto it : addFileList) {
|
||||
remove((dirPath + it).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckFileList(std::string dirPath) const
|
||||
{
|
||||
if (cmpFileList.size() != expectFileList.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < cmpFileList.size(); i++) {
|
||||
if (cmpFileList.at(i) != (dirPath + expectFileList.at(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::string> cmpFileList;
|
||||
|
||||
const std::vector<std::string> createFileList = {
|
||||
"lib_6.so", "lib_5.so", "lib_8.so", "lib_4.so", "test1.txt"
|
||||
};
|
||||
|
||||
const std::vector<std::string> addFileList = {
|
||||
"libadd_6.so", "libadd_5.so", "libadd_8.so", "libadd_4.so", "test2.txt"
|
||||
};
|
||||
|
||||
std::vector<std::string> expectFileList = {
|
||||
"libadd_6.so", "libadd_5.so", "libadd_8.so", "libadd_4.so",
|
||||
"lib_6.so", "lib_5.so", "lib_8.so", "lib_4.so"
|
||||
};
|
||||
};
|
||||
|
||||
class MockPluginWatcher : public PluginWatcher {
|
||||
@ -70,82 +148,9 @@ public:
|
||||
MOCK_METHOD1(OnPluginRemoved, void(const std::string&));
|
||||
};
|
||||
|
||||
static void OnPluginAddedStub(const std::string& path)
|
||||
{
|
||||
g_cmpFileList.push_back(path);
|
||||
sort(g_cmpFileList.begin(), g_cmpFileList.end());
|
||||
return;
|
||||
}
|
||||
|
||||
static void OnPluginRemovedStub(const std::string& path)
|
||||
{
|
||||
for (auto iter = g_cmpFileList.cbegin(); iter != g_cmpFileList.cend(); iter++) {
|
||||
if (*iter == path) {
|
||||
g_cmpFileList.erase(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void CreateFile()
|
||||
{
|
||||
for (auto it : g_createFileList) {
|
||||
int fd = creat(it.c_str(), g_defaultFileMode);
|
||||
g_createFdList.push_back(fd);
|
||||
}
|
||||
}
|
||||
|
||||
static void AddFile()
|
||||
{
|
||||
for (auto it : g_addFileList) {
|
||||
int fd = creat(it.c_str(), g_defaultFileMode);
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
write(fd, "testcase", 1);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void DeleteFile()
|
||||
{
|
||||
for (auto it : g_createFileList) {
|
||||
for (auto fd : g_createFdList) {
|
||||
close(fd);
|
||||
}
|
||||
remove(it.c_str());
|
||||
}
|
||||
for (auto it : g_addFileList) {
|
||||
remove(it.c_str());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static bool CheckFileList()
|
||||
{
|
||||
sort(g_expectFileList.begin(), g_expectFileList.end());
|
||||
if (g_expectFileList.size() != g_cmpFileList.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < g_expectFileList.size(); i++) {
|
||||
char fullpath[PATH_MAX + 1] = {0};
|
||||
realpath(g_expectFileList.at(i).c_str(), fullpath);
|
||||
if (g_cmpFileList.at(i) != fullpath) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Monitor the plugin loading in the test directory.
|
||||
* @tc.desc: Monitor single plugin dir.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(PluginWatchTest, SingleWatchDirTest, TestSize.Level1)
|
||||
@ -153,32 +158,81 @@ HWTEST_F(PluginWatchTest, SingleWatchDirTest, TestSize.Level1)
|
||||
auto pluginManage = std::make_shared<PluginManager>();
|
||||
MockPluginWatcher watcher(pluginManage);
|
||||
|
||||
EXPECT_CALL(watcher, OnPluginAdded(testing::_)).WillRepeatedly(testing::Invoke(OnPluginAddedStub));
|
||||
EXPECT_CALL(watcher, OnPluginRemoved(testing::_)).WillRepeatedly(testing::Invoke(OnPluginRemovedStub));
|
||||
EXPECT_CALL(watcher, OnPluginAdded(testing::_)).WillRepeatedly(
|
||||
testing::Invoke(this, &PluginWatchTest::OnPluginAddedStub));
|
||||
EXPECT_CALL(watcher, OnPluginRemoved(testing::_)).WillRepeatedly(
|
||||
testing::Invoke(this, &PluginWatchTest::OnPluginRemovedStub));
|
||||
CreateFile(DEFAULT_TEST_PATH_1);
|
||||
|
||||
g_createFdList.clear();
|
||||
CreateFile();
|
||||
watcher.ScanPlugins(DEFAULT_TEST_PATH);
|
||||
watcher.WatchPlugins(DEFAULT_TEST_PATH);
|
||||
EXPECT_TRUE(watcher.ScanPlugins(DEFAULT_TEST_PATH_1));
|
||||
EXPECT_TRUE(watcher.WatchPlugins(DEFAULT_TEST_PATH_1));
|
||||
usleep(TEMP_DELAY);
|
||||
AddFile();
|
||||
AddFile(DEFAULT_TEST_PATH_1);
|
||||
usleep(TEMP_DELAY);
|
||||
EXPECT_EQ(CheckFileList(), false);
|
||||
DeleteFile();
|
||||
EXPECT_EQ(CheckFileList(DEFAULT_TEST_PATH_1), true);
|
||||
DeleteFile(DEFAULT_TEST_PATH_1);
|
||||
usleep(TEMP_DELAY);
|
||||
EXPECT_EQ(g_cmpFileList.empty(), true);
|
||||
EXPECT_EQ(cmpFileList.size(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Plug-in process exception test.
|
||||
* @tc.desc: Monitor multi plugin dir.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(PluginWatchTest, OnPluginAdded, TestSize.Level1)
|
||||
HWTEST_F(PluginWatchTest, MultiWatchDirTest, TestSize.Level1)
|
||||
{
|
||||
const auto pluginManage = std::make_shared<PluginManager>();
|
||||
PluginWatcher pluginWatcher(pluginManage);
|
||||
pluginWatcher.OnPluginAdded("");
|
||||
pluginWatcher.OnPluginRemoved("");
|
||||
auto pluginManage = std::make_shared<PluginManager>();
|
||||
MockPluginWatcher watcher(pluginManage);
|
||||
|
||||
EXPECT_CALL(watcher, OnPluginAdded(testing::_)).WillRepeatedly(
|
||||
testing::Invoke(this, &PluginWatchTest::OnPluginAddedStub));
|
||||
EXPECT_CALL(watcher, OnPluginRemoved(testing::_)).WillRepeatedly(
|
||||
testing::Invoke(this, &PluginWatchTest::OnPluginRemovedStub));
|
||||
CreateFile(DEFAULT_TEST_PATH_1);
|
||||
EXPECT_TRUE(watcher.ScanPlugins(DEFAULT_TEST_PATH_1));
|
||||
EXPECT_TRUE(watcher.WatchPlugins(DEFAULT_TEST_PATH_1));
|
||||
usleep(TEMP_DELAY);
|
||||
AddFile(DEFAULT_TEST_PATH_1);
|
||||
usleep(TEMP_DELAY);
|
||||
EXPECT_EQ(CheckFileList(DEFAULT_TEST_PATH_1), true);
|
||||
DeleteFile(DEFAULT_TEST_PATH_1);
|
||||
usleep(TEMP_DELAY);
|
||||
EXPECT_EQ(cmpFileList.size(), 0);
|
||||
|
||||
CreateFile(DEFAULT_TEST_PATH_2);
|
||||
EXPECT_TRUE(watcher.ScanPlugins(DEFAULT_TEST_PATH_2));
|
||||
EXPECT_TRUE(watcher.WatchPlugins(DEFAULT_TEST_PATH_2));
|
||||
usleep(TEMP_DELAY);
|
||||
AddFile(DEFAULT_TEST_PATH_2);
|
||||
usleep(TEMP_DELAY);
|
||||
EXPECT_EQ(CheckFileList(DEFAULT_TEST_PATH_2), true);
|
||||
DeleteFile(DEFAULT_TEST_PATH_2);
|
||||
usleep(TEMP_DELAY);
|
||||
EXPECT_EQ(cmpFileList.size(), 0);
|
||||
|
||||
CreateFile(DEFAULT_TEST_PATH_3);
|
||||
EXPECT_TRUE(watcher.ScanPlugins(DEFAULT_TEST_PATH_3));
|
||||
EXPECT_TRUE(watcher.WatchPlugins(DEFAULT_TEST_PATH_3));
|
||||
usleep(TEMP_DELAY);
|
||||
AddFile(DEFAULT_TEST_PATH_3);
|
||||
usleep(TEMP_DELAY);
|
||||
EXPECT_EQ(CheckFileList(DEFAULT_TEST_PATH_3), true);
|
||||
DeleteFile(DEFAULT_TEST_PATH_3);
|
||||
usleep(TEMP_DELAY);
|
||||
EXPECT_EQ(cmpFileList.size(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Exception test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(PluginWatchTest, ExceptionTest, TestSize.Level1)
|
||||
{
|
||||
auto pluginManage = std::make_shared<PluginManager>();
|
||||
MockPluginWatcher watcher(pluginManage);
|
||||
EXPECT_FALSE(watcher.ScanPlugins(NO_EXIST_TEST_PATH));
|
||||
EXPECT_FALSE(watcher.WatchPlugins(NO_EXIST_TEST_PATH));
|
||||
}
|
||||
} // namespace
|
||||
|
@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <hwext/gtest-ext.h>
|
||||
#include <hwext/gtest-tag.h>
|
||||
#include <thread>
|
||||
|
||||
#include "client_map.h"
|
||||
#include "plugin_service.ipc.h"
|
||||
#include "service_entry.h"
|
||||
#include "socket_context.h"
|
||||
#include "unix_socket_client.h"
|
||||
#include "unix_socket_server.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace {
|
||||
class ServicesIpcTest : public ::testing::Test {
|
||||
protected:
|
||||
static constexpr auto TEMP_DELAY = std::chrono::milliseconds(10);
|
||||
static void SetUpTestCase() {}
|
||||
static void TearDownTestCase() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* @tc.name: ipc
|
||||
* @tc.desc: Socket send/recv interface.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesIpcTest, ProtocolProc, TestSize.Level1)
|
||||
{
|
||||
ServiceBase serviceBase;
|
||||
SocketContext socketContext;
|
||||
ASSERT_FALSE(serviceBase.ProtocolProc(socketContext, 0, nullptr, 0));
|
||||
ASSERT_TRUE(!socketContext.SendRaw(-1, nullptr, 0, 0));
|
||||
ASSERT_TRUE(!socketContext.SendFileDescriptor(-1));
|
||||
ASSERT_EQ(socketContext.ReceiveFileDiscriptor(), -1);
|
||||
ASSERT_EQ(socketContext.RawProtocolProc(-1, nullptr, -1), -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: ipc
|
||||
* @tc.desc: Client link.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesIpcTest, ClientSocket, TestSize.Level1)
|
||||
{
|
||||
ServiceEntry serviceEntry;
|
||||
ClientMap::GetInstance().PutClientSocket(0, serviceEntry);
|
||||
ASSERT_EQ(ClientMap::GetInstance().AutoRelease(), 1);
|
||||
|
||||
ClientConnection* clientConnection = new ClientConnection(0, serviceEntry);
|
||||
ASSERT_EQ(clientConnection->RawProtocolProc(-1, nullptr, 0), -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Abnormal client link.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesIpcTest, unixSocketClient, TestSize.Level1)
|
||||
{
|
||||
UnixSocketClient unixSocketClient;
|
||||
ServiceBase serviceBase;
|
||||
ASSERT_TRUE(!unixSocketClient.Connect("asdf", serviceBase));
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Start unixSocket Server.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesIpcTest, UnixSocketServer, TestSize.Level1)
|
||||
{
|
||||
UnixSocketServer unixSocketServer;
|
||||
|
||||
unixSocketServer.UnixSocketAccept(nullptr);
|
||||
|
||||
ServiceEntry serviceEntry;
|
||||
ASSERT_TRUE(unixSocketServer.StartServer("", serviceEntry));
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Server process monitoring.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesIpcTest, ServiceEntry, TestSize.Level1)
|
||||
{
|
||||
ServiceEntry serviceEntry;
|
||||
IPluginServiceServer pluginService;
|
||||
serviceEntry.StartServer("test_unix_socket_service_entry");
|
||||
serviceEntry.RegisterService(pluginService);
|
||||
serviceEntry.FindServiceByName(pluginService.serviceName_);
|
||||
|
||||
std::this_thread::sleep_for(TEMP_DELAY);
|
||||
|
||||
GetTimeMS();
|
||||
GetTimeUS();
|
||||
GetTimeNS();
|
||||
|
||||
IPluginServiceClient pluginClient;
|
||||
ASSERT_FALSE(pluginClient.Connect(""));
|
||||
std::this_thread::sleep_for(TEMP_DELAY);
|
||||
}
|
||||
} // namespace
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <hwext/gtest-ext.h>
|
||||
#include <hwext/gtest-tag.h>
|
||||
|
||||
#include "plugin_service.h"
|
||||
#include "plugin_session.h"
|
||||
#include "profiler_data_repeater.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
using PluginServicePtr = STD_PTR(shared, PluginService);
|
||||
|
||||
class ServicesPluginServiceTest : public ::testing::Test {
|
||||
protected:
|
||||
static void SetUpTestCase() {}
|
||||
static void TearDownTestCase() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Session flow test, get session id by plugin name.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesPluginServiceTest, PluginService1, TestSize.Level1)
|
||||
{
|
||||
PluginServicePtr pluginService = std::make_shared<PluginService>();
|
||||
ProfilerPluginConfig ppc;
|
||||
ppc.set_name("abc.so");
|
||||
ppc.set_plugin_sha256("ASDFAADSF");
|
||||
ppc.set_sample_interval(20);
|
||||
|
||||
pluginService->CreatePluginSession(ppc, std::make_shared<ProfilerDataRepeater>(4096));
|
||||
pluginService->StartPluginSession(ppc);
|
||||
pluginService->StopPluginSession("abc.so");
|
||||
pluginService->DestroyPluginSession("abc.so");
|
||||
pluginService->GetPluginIdByName("abc.so");
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Session flow test, get plugin status.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesPluginServiceTest, PluginService2, TestSize.Level1)
|
||||
{
|
||||
PluginServicePtr pluginService = std::make_shared<PluginService>();
|
||||
ProfilerPluginConfig ppc;
|
||||
ppc.set_name("abc.so");
|
||||
ppc.set_plugin_sha256("ASDFAADSF");
|
||||
ppc.set_sample_interval(20);
|
||||
|
||||
ProfilerSessionConfig::BufferConfig bc;
|
||||
bc.set_pages(1);
|
||||
bc.set_policy(ProfilerSessionConfig_BufferConfig_Policy_RECYCLE);
|
||||
|
||||
pluginService->CreatePluginSession(ppc, bc, std::make_shared<ProfilerDataRepeater>(4096));
|
||||
pluginService->StartPluginSession(ppc);
|
||||
pluginService->StopPluginSession("abc.so");
|
||||
pluginService->GetPluginStatus();
|
||||
|
||||
PluginInfo pi;
|
||||
pi.id = 0;
|
||||
pi.name = "abc.so";
|
||||
pi.path = "abc.so";
|
||||
pi.sha256 = "asdfasdf";
|
||||
pluginService->RemovePluginInfo(pi);
|
||||
}
|
@ -1,435 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <hwext/gtest-ext.h>
|
||||
#include <hwext/gtest-tag.h>
|
||||
|
||||
#include "logging.h"
|
||||
#include "plugin_service.h"
|
||||
#include "plugin_session.h"
|
||||
#include "profiler_capability_manager.h"
|
||||
#include "profiler_data_repeater.h"
|
||||
#include "profiler_service.h"
|
||||
#include "result_demuxer.h"
|
||||
#include "trace_file_reader.h"
|
||||
#include "trace_file_writer.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace {
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
const std::string DEFAULT_TEST_PATH("./");
|
||||
#else
|
||||
const std::string DEFAULT_TEST_PATH("/data/local/tmp/");
|
||||
#endif
|
||||
|
||||
using PluginServicePtr = STD_PTR(shared, PluginService);
|
||||
using ProfilerDataRepeaterPtr = STD_PTR(shared, ProfilerDataRepeater);
|
||||
using ProfilerServicePtr = STD_PTR(shared, ProfilerService);
|
||||
using ProfilerPluginDataPtr = STD_PTR(shared, ProfilerPluginData);
|
||||
|
||||
constexpr int DATA_MAX_SIZE = 10;
|
||||
|
||||
class ServicesProfilerServiceTest : public ::testing::Test {
|
||||
protected:
|
||||
ProfilerPluginConfig config;
|
||||
ProfilerSessionConfig::BufferConfig bufferConfig;
|
||||
PluginInfo pluginInfo;
|
||||
PluginServicePtr service;
|
||||
ProfilerDataRepeaterPtr repeater;
|
||||
ProfilerServicePtr service_;
|
||||
std::unique_ptr<grpc::ServerContext> context_;
|
||||
std::atomic<int> requestCounter{0};
|
||||
|
||||
static void SetUpTestCase() {}
|
||||
static void TearDownTestCase() {}
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
config.set_name("test_session");
|
||||
bufferConfig.set_pages(0);
|
||||
pluginInfo.name = config.name();
|
||||
service = std::make_shared<PluginService>();
|
||||
repeater = std::make_shared<ProfilerDataRepeater>(DATA_MAX_SIZE);
|
||||
if (service) {
|
||||
service->AddPluginInfo(pluginInfo);
|
||||
}
|
||||
|
||||
service_ = std::make_shared<ProfilerService>(service);
|
||||
context_ = std::make_unique<grpc::ServerContext>();
|
||||
}
|
||||
void TearDown() override
|
||||
{
|
||||
if (service) {
|
||||
service->RemovePluginInfo(pluginInfo);
|
||||
}
|
||||
ProfilerCapabilityManager::GetInstance().pluginCapabilities_.clear();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Plugin session flow test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesProfilerServiceTest, PluginSession, TestSize.Level1)
|
||||
{
|
||||
auto session = std::make_shared<PluginSession>(config, nullptr, nullptr);
|
||||
EXPECT_NE(session, nullptr);
|
||||
EXPECT_FALSE(session->IsAvailable());
|
||||
|
||||
EXPECT_FALSE(session->Create());
|
||||
config.set_name("test_session2");
|
||||
session = std::make_shared<PluginSession>(config, service, repeater);
|
||||
repeater->Size();
|
||||
|
||||
session.reset();
|
||||
config.set_name("test_session3");
|
||||
session = std::make_shared<PluginSession>(config, service, repeater);
|
||||
|
||||
ASSERT_NE(session->GetState(), PluginSession::CREATED);
|
||||
EXPECT_FALSE(session->Start());
|
||||
ASSERT_NE(session->GetState(), PluginSession::STARTED);
|
||||
EXPECT_FALSE(session->Stop());
|
||||
ASSERT_NE(session->GetState(), PluginSession::CREATED);
|
||||
EXPECT_FALSE(session->Destroy());
|
||||
EXPECT_EQ(session->GetState(), PluginSession::INITIAL);
|
||||
|
||||
// recreate is OK
|
||||
EXPECT_FALSE(session->Create());
|
||||
EXPECT_FALSE(session->Destroy());
|
||||
repeater->Reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Streaming session test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesProfilerServiceTest, TraceFileWriter, TestSize.Level1)
|
||||
{
|
||||
std::string path = "trace.bin";
|
||||
auto writer = std::make_shared<TraceFileWriter>(path);
|
||||
EXPECT_NE(writer, nullptr);
|
||||
|
||||
std::string testData = "Hello, Wrold!";
|
||||
EXPECT_EQ(writer->Write(testData.data(), testData.size()), sizeof(uint32_t) + testData.size());
|
||||
EXPECT_EQ(writer->Flush(), true);
|
||||
|
||||
ProfilerPluginData pluginData;
|
||||
pluginData.set_name("ABC");
|
||||
pluginData.set_status(0);
|
||||
pluginData.set_data("DEF");
|
||||
EXPECT_GT(writer->Write(pluginData), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: plugin
|
||||
* @tc.desc: Streaming session test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesProfilerServiceTest, TraceFileReader, TestSize.Level1)
|
||||
{
|
||||
std::string path = "trace-write-msg.bin";
|
||||
auto writer = std::make_shared<TraceFileWriter>(path);
|
||||
ASSERT_NE(writer, nullptr);
|
||||
|
||||
constexpr int n = 100;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
ProfilerPluginData pluginData{};
|
||||
pluginData.set_name("test_name");
|
||||
pluginData.set_status(i);
|
||||
pluginData.set_data("Hello, Wrold!");
|
||||
long bytes = writer->Write(pluginData);
|
||||
EXPECT_EQ(bytes, sizeof(uint32_t) + pluginData.ByteSizeLong());
|
||||
HILOG_INFO(LOG_CORE, "[%d/%d] write %ld bytes to %s.", i, n, bytes, path.c_str());
|
||||
}
|
||||
writer.reset(); // make sure write done!
|
||||
|
||||
auto reader = std::make_shared<TraceFileReader>();
|
||||
ASSERT_NE(reader, nullptr);
|
||||
ASSERT_TRUE(reader->Open(path));
|
||||
for (int i = 1; i <= n; i++) {
|
||||
ProfilerPluginData data{};
|
||||
long bytes = reader->Read(data);
|
||||
HILOG_INFO(LOG_CORE, "data = {%s, %d, %s}", data.name().c_str(), data.status(), data.data().c_str());
|
||||
HILOG_INFO(LOG_CORE, "read %ld bytes from %s", bytes, path.c_str());
|
||||
}
|
||||
|
||||
ASSERT_TRUE(reader->Open(path));
|
||||
long bytes = 0;
|
||||
do {
|
||||
ProfilerPluginData data{};
|
||||
bytes = reader->Read(data);
|
||||
HILOG_INFO(LOG_CORE, "data = {%s, %d, %s}", data.name().c_str(), data.status(), data.data().c_str());
|
||||
HILOG_INFO(LOG_CORE, "read %ld bytes from %s", bytes, path.c_str());
|
||||
} while (bytes > 0);
|
||||
|
||||
ASSERT_EQ(reader->Read(nullptr, 0), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: service
|
||||
* @tc.desc: Streaming session report result test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesProfilerServiceTest, ResultDemuxer1, TestSize.Level1)
|
||||
{
|
||||
std::string path = "demux.bin";
|
||||
ProfilerDataRepeaterPtr repeater = std::make_shared<ProfilerDataRepeater>(DATA_MAX_SIZE);
|
||||
|
||||
auto demuxer = std::make_shared<ResultDemuxer>(repeater);
|
||||
EXPECT_NE(demuxer, nullptr);
|
||||
demuxer->SetTraceWriter(nullptr);
|
||||
|
||||
auto writer = std::make_shared<TraceFileWriter>(path);
|
||||
EXPECT_NE(writer, nullptr);
|
||||
demuxer->SetTraceWriter(writer);
|
||||
|
||||
const int putCount = 20;
|
||||
const int putDelayUs = 10 * 1000;
|
||||
demuxer->StartTakeResults();
|
||||
std::thread dataProducer([=] {
|
||||
for (int i = 0; i < putCount; i++) {
|
||||
auto pluginData = std::make_shared<ProfilerPluginData>();
|
||||
ASSERT_NE(pluginData, nullptr);
|
||||
pluginData->set_name("test-" + std::to_string(i));
|
||||
pluginData->set_status(i);
|
||||
repeater->PutPluginData(pluginData);
|
||||
HILOG_DEBUG(LOG_CORE, "put test data %d...", i);
|
||||
usleep(putDelayUs);
|
||||
}
|
||||
repeater->PutPluginData(nullptr);
|
||||
});
|
||||
|
||||
HILOG_DEBUG(LOG_CORE, "wating producer thread done...");
|
||||
dataProducer.join();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: service
|
||||
* @tc.desc: Streaming session report result test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesProfilerServiceTest, ResultDemuxer2, TestSize.Level1)
|
||||
{
|
||||
std::string path = "demux.bin";
|
||||
ProfilerDataRepeaterPtr repeater = std::make_shared<ProfilerDataRepeater>(DATA_MAX_SIZE);
|
||||
|
||||
auto demuxer = std::make_shared<ResultDemuxer>(repeater);
|
||||
ASSERT_NE(demuxer, nullptr);
|
||||
|
||||
auto writer = std::make_shared<TraceFileWriter>(path);
|
||||
EXPECT_NE(writer, nullptr);
|
||||
demuxer->SetTraceWriter(writer);
|
||||
|
||||
const int putCount = 30;
|
||||
const int putDelayUs = 10 * 1000;
|
||||
demuxer->StartTakeResults();
|
||||
std::thread dataProducer([=] {
|
||||
for (int i = 0; i < putCount; i++) {
|
||||
auto pluginData = std::make_shared<ProfilerPluginData>();
|
||||
ASSERT_NE(pluginData, nullptr);
|
||||
pluginData->set_name("AB-" + std::to_string(i));
|
||||
pluginData->set_status(i);
|
||||
|
||||
HILOG_DEBUG(LOG_CORE, "put test data %d...", i);
|
||||
if (!repeater->PutPluginData(pluginData)) {
|
||||
HILOG_WARN(LOG_CORE, "put test data %d FAILED!", i);
|
||||
break;
|
||||
}
|
||||
usleep(putDelayUs);
|
||||
}
|
||||
});
|
||||
|
||||
usleep((putCount / 2) * putDelayUs);
|
||||
demuxer->StopTakeResults();
|
||||
|
||||
repeater->Close();
|
||||
HILOG_DEBUG(LOG_CORE, "wating producer thread done...");
|
||||
dataProducer.join();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: server
|
||||
* @tc.desc: Profiler capacity management.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesProfilerServiceTest, ProfilerCapabilityManager, TestSize.Level1)
|
||||
{
|
||||
std::vector<ProfilerPluginCapability> caps = ProfilerCapabilityManager::GetInstance().GetCapabilities();
|
||||
for (int i = 0; i < caps.size(); i++) {
|
||||
auto cap = caps[i];
|
||||
EXPECT_TRUE(ProfilerCapabilityManager::GetInstance().RemoveCapability(cap.name()));
|
||||
}
|
||||
caps.clear();
|
||||
|
||||
EXPECT_EQ(ProfilerCapabilityManager::GetInstance().GetCapability("xxx"), nullptr);
|
||||
EXPECT_EQ(ProfilerCapabilityManager::GetInstance().GetCapabilities().size(), 0);
|
||||
|
||||
caps = ProfilerCapabilityManager::GetInstance().GetCapabilities();
|
||||
EXPECT_EQ(caps.size(), 0);
|
||||
|
||||
const int n = 10;
|
||||
for (int i = 0; i < n; i++) {
|
||||
ProfilerPluginCapability cap;
|
||||
cap.set_path("/system/lib/libcap_" + std::to_string(i) + ".so");
|
||||
cap.set_name("cap_" + std::to_string(i));
|
||||
EXPECT_TRUE(ProfilerCapabilityManager::GetInstance().AddCapability(cap));
|
||||
EXPECT_EQ(ProfilerCapabilityManager::GetInstance().GetCapabilities().size(), i + 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
ProfilerPluginCapability cap;
|
||||
cap.set_name("cap_" + std::to_string(i));
|
||||
auto capPtr = ProfilerCapabilityManager::GetInstance().GetCapability(cap.name());
|
||||
ASSERT_NE(capPtr, nullptr);
|
||||
EXPECT_EQ(capPtr->name(), cap.name());
|
||||
}
|
||||
|
||||
ProfilerPluginCapability cap1;
|
||||
cap1.set_path("/system/lib/libcap1.so");
|
||||
cap1.set_name("cap1");
|
||||
EXPECT_TRUE(ProfilerCapabilityManager::GetInstance().AddCapability(cap1));
|
||||
|
||||
cap1.set_path("/system/lib/libcap2.so");
|
||||
EXPECT_TRUE(ProfilerCapabilityManager::GetInstance().UpdateCapability(cap1.name(), cap1));
|
||||
EXPECT_TRUE(ProfilerCapabilityManager::GetInstance().RemoveCapability(cap1.name()));
|
||||
|
||||
caps = ProfilerCapabilityManager::GetInstance().GetCapabilities();
|
||||
EXPECT_EQ(caps.size(), n);
|
||||
for (int i = 0; i < caps.size(); i++) {
|
||||
auto cap = caps[i];
|
||||
EXPECT_TRUE(ProfilerCapabilityManager::GetInstance().RemoveCapability(cap.name()));
|
||||
|
||||
EXPECT_EQ(ProfilerCapabilityManager::GetInstance().GetCapabilities().size(), n - (i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: server
|
||||
* @tc.desc: Profiler data repeater.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesProfilerServiceTest, ProfilerDataRepeater, TestSize.Level1)
|
||||
{
|
||||
const int itemCounts = 10000;
|
||||
const int bufferSize = itemCounts;
|
||||
auto inDataRepeater = std::make_shared<ProfilerDataRepeater>(bufferSize);
|
||||
ASSERT_NE(inDataRepeater, nullptr);
|
||||
|
||||
auto outDataRepeater = std::make_shared<ProfilerDataRepeater>(bufferSize);
|
||||
ASSERT_NE(outDataRepeater, nullptr);
|
||||
|
||||
auto f = [](int x) { return 2 * x + 1; };
|
||||
std::thread worker([&]() {
|
||||
for (int i = 0; i < itemCounts; i++) {
|
||||
auto xData = inDataRepeater->TakePluginData();
|
||||
|
||||
// compute in worker thread
|
||||
int x = xData ? std::stoi(xData->data()) : 0;
|
||||
int y = f(x);
|
||||
|
||||
auto yData = std::make_shared<ProfilerPluginData>();
|
||||
yData->set_data(std::to_string(y));
|
||||
outDataRepeater->PutPluginData(yData);
|
||||
}
|
||||
});
|
||||
|
||||
std::vector<int> yVec;
|
||||
for (int i = 0; i < itemCounts; i++) {
|
||||
int x0 = i;
|
||||
auto xData = std::make_shared<ProfilerPluginData>();
|
||||
xData->set_data(std::to_string(x0));
|
||||
inDataRepeater->PutPluginData(xData);
|
||||
|
||||
int y0 = f(x0);
|
||||
yVec.push_back(y0);
|
||||
}
|
||||
worker.join();
|
||||
|
||||
std::vector<ProfilerPluginDataPtr> pluginDataVec;
|
||||
auto count = outDataRepeater->TakePluginData(pluginDataVec);
|
||||
EXPECT_EQ(count, yVec.size());
|
||||
|
||||
for (size_t i = 0; i < pluginDataVec.size(); i++) {
|
||||
auto yData = pluginDataVec[i];
|
||||
int y = yData ? std::stoi(yData->data()) : 0;
|
||||
EXPECT_EQ(y, yVec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: server
|
||||
* @tc.desc: Session flow test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesProfilerServiceTest, ProfilerService1, TestSize.Level1)
|
||||
{
|
||||
ASSERT_NE(service_, nullptr);
|
||||
ASSERT_NE(context_, nullptr);
|
||||
|
||||
GetCapabilitiesRequest request;
|
||||
GetCapabilitiesResponse response;
|
||||
|
||||
ProfilerPluginCapability cap;
|
||||
cap.set_name("cap1");
|
||||
ProfilerCapabilityManager::GetInstance().AddCapability(cap);
|
||||
|
||||
request.set_request_id(++requestCounter);
|
||||
auto status = service_->GetCapabilities(context_.get(), &request, &response);
|
||||
EXPECT_EQ(status.error_code(), grpc::StatusCode::OK);
|
||||
EXPECT_GT(response.capabilities_size(), 0);
|
||||
HILOG_DEBUG(LOG_CORE, "GetCapabilities, capabilities_size = %d", response.capabilities_size());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: server
|
||||
* @tc.desc: Session flow test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesProfilerServiceTest, ProfilerService2, TestSize.Level1)
|
||||
{
|
||||
ASSERT_NE(service_, nullptr);
|
||||
ASSERT_NE(context_, nullptr);
|
||||
|
||||
CreateSessionRequest request;
|
||||
CreateSessionResponse response;
|
||||
|
||||
auto status = service_->CreateSession(context_.get(), &request, &response);
|
||||
EXPECT_NE(status.error_code(), grpc::StatusCode::OK);
|
||||
|
||||
StartSessionRequest startrequest;
|
||||
StartSessionResponse startresponse;
|
||||
startrequest.set_session_id(0);
|
||||
startrequest.set_request_id(++requestCounter);
|
||||
status = service_->StartSession(context_.get(), &startrequest, &startresponse);
|
||||
EXPECT_NE(status.error_code(), grpc::StatusCode::OK);
|
||||
|
||||
StopSessionRequest stoprequest;
|
||||
StopSessionResponse stopresponse;
|
||||
stoprequest.set_session_id(0);
|
||||
stoprequest.set_request_id(++requestCounter);
|
||||
status = service_->StopSession(context_.get(), &stoprequest, &stopresponse);
|
||||
EXPECT_NE(status.error_code(), grpc::StatusCode::OK);
|
||||
|
||||
DestroySessionRequest destroyrequest;
|
||||
DestroySessionResponse destroyresponse;
|
||||
destroyrequest.set_session_id(0);
|
||||
destroyrequest.set_request_id(++requestCounter);
|
||||
status = service_->DestroySession(context_.get(), &destroyrequest, &destroyresponse);
|
||||
EXPECT_NE(status.error_code(), grpc::StatusCode::OK);
|
||||
}
|
||||
} // namespace
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <hwext/gtest-ext.h>
|
||||
#include <hwext/gtest-tag.h>
|
||||
#include <thread>
|
||||
|
||||
#include "plugin_service_types.pb.h"
|
||||
#include "share_memory_allocator.h"
|
||||
#include "share_memory_block.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace {
|
||||
class ServicesSharedMemoryTest : public ::testing::Test {
|
||||
protected:
|
||||
static void SetUpTestCase() {}
|
||||
static void TearDownTestCase() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* @tc.name: server
|
||||
* @tc.desc: Shared memory flow test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesSharedMemoryTest, SharedMemoryBlock, TestSize.Level1)
|
||||
{
|
||||
ShareMemoryBlock shareMemoryBlock;
|
||||
ASSERT_TRUE(shareMemoryBlock.CreateBlock("testname", 1024));
|
||||
|
||||
shareMemoryBlock.GetName();
|
||||
shareMemoryBlock.GetSize();
|
||||
shareMemoryBlock.GetfileDescriptor();
|
||||
|
||||
shareMemoryBlock.SetDropType(ShareMemoryBlock::DropType::DROP_NONE);
|
||||
int8_t data[100];
|
||||
for (int i = 0; i < 20; i++) {
|
||||
*((uint32_t*)data) = i;
|
||||
shareMemoryBlock.PutRaw(data, 100);
|
||||
}
|
||||
int8_t* p = shareMemoryBlock.GetFreeMemory(100);
|
||||
ASSERT_TRUE(p == nullptr);
|
||||
do {
|
||||
p = const_cast<int8_t*>(shareMemoryBlock.GetDataPoint());
|
||||
printf("%p,p=%d\n", p, *((int*)p));
|
||||
} while (shareMemoryBlock.Next() && shareMemoryBlock.GetDataSize() > 0);
|
||||
|
||||
NotifyResultResponse response;
|
||||
response.set_status(123);
|
||||
ASSERT_TRUE(shareMemoryBlock.PutProtobuf(response));
|
||||
ASSERT_TRUE(shareMemoryBlock.GetDataSize() > 0);
|
||||
response.ParseFromArray(shareMemoryBlock.GetDataPoint(), shareMemoryBlock.GetDataSize());
|
||||
ASSERT_TRUE(response.status() == 123);
|
||||
|
||||
ASSERT_TRUE(shareMemoryBlock.ReleaseBlock());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: server
|
||||
* @tc.desc: Shared memory abnormal flow test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ServicesSharedMemoryTest, SharedMemoryAllocator, TestSize.Level1)
|
||||
{
|
||||
ASSERT_TRUE(ShareMemoryAllocator::GetInstance().CreateMemoryBlockLocal("testname", 1) ==
|
||||
nullptr); // 创建内存块大小<1024,返回空
|
||||
ASSERT_TRUE(ShareMemoryAllocator::GetInstance().CreateMemoryBlockLocal("testname", 1024) != nullptr); // 成功创建
|
||||
ASSERT_TRUE(ShareMemoryAllocator::GetInstance().CreateMemoryBlockLocal("testname", 1024) ==
|
||||
nullptr); // 创建同名内存块返回空
|
||||
|
||||
ASSERT_TRUE(ShareMemoryAllocator::GetInstance().ReleaseMemoryBlockLocal("testname"));
|
||||
ASSERT_FALSE(ShareMemoryAllocator::GetInstance().ReleaseMemoryBlockLocal("or")); // 释放不存在的内存块返回-1
|
||||
}
|
||||
} // namespace
|
8
device/plugins/api/test/unittest/writer_adapter_test.cpp
Executable file → Normal file
8
device/plugins/api/test/unittest/writer_adapter_test.cpp
Executable file → Normal file
@ -34,8 +34,8 @@ protected:
|
||||
HWTEST_F(WriterAdapterTest, Writer, TestSize.Level1)
|
||||
{
|
||||
WriterAdapter writerAdapter;
|
||||
writerAdapter.GetWriter();
|
||||
writerAdapter.GetStruct();
|
||||
EXPECT_EQ(writerAdapter.GetWriter(), nullptr);
|
||||
EXPECT_EQ(writerAdapter.GetStruct(), &writerAdapter.writerStruct_);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,7 +46,7 @@ HWTEST_F(WriterAdapterTest, Writer, TestSize.Level1)
|
||||
HWTEST_F(WriterAdapterTest, Func, TestSize.Level1)
|
||||
{
|
||||
WriterAdapter writerAdapter;
|
||||
writerAdapter.WriteFunc(nullptr, nullptr, 0);
|
||||
writerAdapter.FlushFunc(nullptr);
|
||||
EXPECT_EQ(writerAdapter.WriteFunc(nullptr, nullptr, 0), 0);
|
||||
EXPECT_FALSE(writerAdapter.FlushFunc(nullptr));
|
||||
}
|
||||
} // namespace
|
18
device/plugins/bytrace_plugin/BUILD.gn
Executable file → Normal file
18
device/plugins/bytrace_plugin/BUILD.gn
Executable file → Normal file
@ -10,7 +10,6 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
import("../../base/config.gni")
|
||||
|
||||
@ -27,14 +26,13 @@ config("bytraceplugin_config") {
|
||||
|
||||
ohos_shared_library("bytraceplugin") {
|
||||
output_name = "bytraceplugin"
|
||||
sources = [
|
||||
"src/bytrace_module.cpp",
|
||||
]
|
||||
sources = [ "src/bytrace_module.cpp" ]
|
||||
public_configs = [ ":bytraceplugin_config" ]
|
||||
public_deps = [
|
||||
"${OHOS_PROFILER_DIR}/protos/types/plugins/bytrace_plugin:bytrace_plugin_protos_cpp",
|
||||
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf_lite",
|
||||
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protoc_lib",
|
||||
"${OHOS_PROFILER_DIR}/protos/types/plugins/bytrace_plugin:bytrace_plugin_protos_cpp",
|
||||
"//utils/native/base:utilsecurec",
|
||||
]
|
||||
if (current_toolchain != host_toolchain) {
|
||||
defines = [ "HAVE_HILOG" ]
|
||||
@ -48,14 +46,10 @@ ohos_shared_library("bytraceplugin") {
|
||||
subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}"
|
||||
}
|
||||
|
||||
ohos_executable("test_bytraceplugin") {
|
||||
ohos_executable("test_bytrace_plugin") {
|
||||
output_name = "test_bytraceplugin"
|
||||
sources = [
|
||||
"src/run_test.cpp",
|
||||
]
|
||||
deps = [
|
||||
":bytraceplugin",
|
||||
]
|
||||
sources = [ "src/run_test.cpp" ]
|
||||
deps = [ ":bytraceplugin" ]
|
||||
install_enable = true
|
||||
subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}"
|
||||
}
|
||||
|
5
device/plugins/bytrace_plugin/include/bytrace_module.h
Executable file → Normal file
5
device/plugins/bytrace_plugin/include/bytrace_module.h
Executable file → Normal file
@ -16,13 +16,12 @@
|
||||
#ifndef BYTRACE_MODULE_H
|
||||
#define BYTRACE_MODULE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "plugin_module_api.h"
|
||||
|
||||
int BytracePluginSessionStart(const uint8_t* configData, const uint32_t configSize);
|
||||
|
||||
int BytraceRegisterWriterStruct(WriterStruct* writer);
|
||||
int BytraceRegisterWriterStruct(const WriterStruct* writer);
|
||||
|
||||
int BytracePluginSessionStop();
|
||||
int BytracePluginSessionStop(void);
|
||||
|
||||
#endif // BYTRACE_MODULE_H
|
@ -12,9 +12,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "bytrace_module.h"
|
||||
|
||||
#include <array>
|
||||
#include <poll.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@ -27,101 +27,136 @@
|
||||
#include "securec.h"
|
||||
|
||||
namespace {
|
||||
const std::string CMD_PATH = "/system/bin/bytrace";
|
||||
int g_processNum = -1;
|
||||
constexpr uint32_t MAX_BUFFER_SIZE = 4 * 1024 * 1024;
|
||||
constexpr uint32_t READ_BUFFER_SIZE = 4096;
|
||||
const std::string DEFAULT_FILE = "/local/data/tmp/bytrace.txt";
|
||||
|
||||
bool RunWithConfig(const BytracePluginConfig& config)
|
||||
std::mutex g_taskMutex;
|
||||
|
||||
struct BytraceInfo {
|
||||
bool isRoot;
|
||||
uint32_t buffSize;
|
||||
uint32_t time;
|
||||
std::string clockType;
|
||||
std::string outFile;
|
||||
std::vector<std::string> categoryVec;
|
||||
};
|
||||
std::unique_ptr<BytraceInfo> g_bytraceInfo = nullptr;
|
||||
|
||||
void ParseConfig(const BytracePluginConfig& config)
|
||||
{
|
||||
std::vector<std::string> args;
|
||||
args.push_back("bytrace");
|
||||
if (config.buffe_size() != 0) {
|
||||
args.push_back("-b");
|
||||
args.push_back(std::to_string(config.buffe_size()));
|
||||
}
|
||||
if (config.time() != 0) {
|
||||
args.push_back("-t");
|
||||
args.push_back(std::to_string(config.time()));
|
||||
g_bytraceInfo->buffSize = config.buffe_size();
|
||||
}
|
||||
g_bytraceInfo->time = config.time();
|
||||
g_bytraceInfo->isRoot = config.is_root();
|
||||
if (!config.clock().empty()) {
|
||||
args.push_back("--trace_clock");
|
||||
args.push_back(config.clock());
|
||||
g_bytraceInfo->clockType = config.clock();
|
||||
}
|
||||
if (!config.outfile_name().empty()) {
|
||||
args.push_back("-o");
|
||||
args.push_back(config.outfile_name());
|
||||
g_bytraceInfo->outFile = config.outfile_name();
|
||||
}
|
||||
if (!config.categories().empty()) {
|
||||
for (std::string category : config.categories()) {
|
||||
args.push_back(category);
|
||||
g_bytraceInfo->categoryVec.push_back(category);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<char*> params;
|
||||
std::string cmdPrintStr = "";
|
||||
for (std::string& it : args) {
|
||||
cmdPrintStr += (it + " ");
|
||||
params.push_back(const_cast<char*>(it.c_str()));
|
||||
bool RunCommand(const std::string& cmd)
|
||||
{
|
||||
HILOG_INFO(LOG_CORE, "BytraceCall::start running commond: %s", cmd.c_str());
|
||||
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.data(), "r"), pclose);
|
||||
CHECK_TRUE(pipe, false, "BytraceCall::RunCommand: create popen FAILED!");
|
||||
|
||||
if (g_bytraceInfo->time == 0) {
|
||||
return true;
|
||||
}
|
||||
params.push_back(nullptr);
|
||||
HILOG_INFO(LOG_CORE, "call bytrace::Run: %s", cmdPrintStr.c_str());
|
||||
|
||||
execv(CMD_PATH.data(), ¶ms[0]);
|
||||
std::array<char, READ_BUFFER_SIZE> buffer;
|
||||
std::string result;
|
||||
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
|
||||
result += buffer.data();
|
||||
}
|
||||
HILOG_INFO(LOG_CORE, "BytraceCall::RunCommand result: %s", result.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BeginTrace()
|
||||
{
|
||||
// two case: real-time and offline type.
|
||||
std::string beginCmd;
|
||||
if (g_bytraceInfo->isRoot) {
|
||||
beginCmd = "su root ";
|
||||
}
|
||||
beginCmd += "bytrace ";
|
||||
if (g_bytraceInfo->buffSize != 0) {
|
||||
beginCmd += " -b " + std::to_string(g_bytraceInfo->buffSize);
|
||||
}
|
||||
if (!g_bytraceInfo->clockType.empty()) {
|
||||
beginCmd += " --trace_clock " + g_bytraceInfo->clockType;
|
||||
}
|
||||
// real-time: time is set 0.
|
||||
if (g_bytraceInfo->time == 0) {
|
||||
// if time is not set 1s(must >= 1), bytrace tool will use 5s by dafault.
|
||||
beginCmd += " -t 1 ";
|
||||
beginCmd += " --trace_begin ";
|
||||
} else {
|
||||
beginCmd += " -t " + std::to_string(g_bytraceInfo->time);
|
||||
beginCmd += " -o ";
|
||||
beginCmd += g_bytraceInfo->outFile;
|
||||
beginCmd += " ";
|
||||
}
|
||||
for (const std::string& category : g_bytraceInfo->categoryVec) {
|
||||
beginCmd += category;
|
||||
beginCmd += " ";
|
||||
}
|
||||
return RunCommand(beginCmd);
|
||||
}
|
||||
|
||||
bool StopTrace()
|
||||
{
|
||||
std::string finishCmd;
|
||||
if (g_bytraceInfo->isRoot) {
|
||||
finishCmd = "su root ";
|
||||
}
|
||||
finishCmd += "bytrace --trace_finish --trace_dump";
|
||||
if (g_bytraceInfo->outFile.empty()) {
|
||||
g_bytraceInfo->outFile = DEFAULT_FILE;
|
||||
}
|
||||
finishCmd += " -o ";
|
||||
finishCmd += g_bytraceInfo->outFile;
|
||||
return RunCommand(finishCmd);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int BytracePluginSessionStart(const uint8_t* configData, const uint32_t configSize)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(g_taskMutex);
|
||||
BytracePluginConfig config;
|
||||
HILOG_INFO(LOG_CORE, "BytracePluginSessionStart %u", configSize);
|
||||
CHECK_TRUE(config.ParseFromArray(configData, configSize), 0, "parse config FAILED!");
|
||||
|
||||
g_processNum = fork();
|
||||
CHECK_TRUE(g_processNum >= 0, -1, "create process FAILED!");
|
||||
|
||||
if (g_processNum == 0) {
|
||||
// child process
|
||||
CHECK_TRUE(RunWithConfig(config), 0, "run bytrace FAILED!");
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BytraceRegisterWriterStruct(const WriterStruct* writer)
|
||||
{
|
||||
int res = config.ParseFromArray(configData, configSize);
|
||||
CHECK_TRUE(res, 0, "BytracePluginSessionStart, parse config FAILED! configSize: %u", configSize);
|
||||
g_bytraceInfo = std::make_unique<BytraceInfo>();
|
||||
ParseConfig(config);
|
||||
res = BeginTrace();
|
||||
CHECK_TRUE(res, 0, "BytracePluginSessionStart, bytrace begin FAILED!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BytracePluginSessionStop()
|
||||
{
|
||||
if (g_processNum > 0) {
|
||||
// parent process
|
||||
int status = 0;
|
||||
// judge if child process have exited.
|
||||
if (waitpid(g_processNum, &status, WNOHANG) == 0) {
|
||||
// send SIGKILL to child process.
|
||||
if (kill(g_processNum, SIGINT)) {
|
||||
HILOG_WARN(LOG_CORE, "BytracePluginSessionStop kill child process failed.");
|
||||
} else {
|
||||
HILOG_INFO(LOG_CORE, "BytracePluginSessionStop kill child process success.");
|
||||
}
|
||||
}
|
||||
// report child process exit status.
|
||||
if (WIFEXITED(status)) {
|
||||
HILOG_INFO(LOG_CORE, "child %d exit with status %d!", g_processNum,
|
||||
WEXITSTATUS(static_cast<unsigned>(status)));
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
HILOG_INFO(LOG_CORE, "child %d exit with signal %d!", g_processNum,
|
||||
WTERMSIG(static_cast<unsigned>(status)));
|
||||
} else if (WIFSTOPPED(status)) {
|
||||
HILOG_INFO(LOG_CORE, "child %d stopped by signal %d", g_processNum,
|
||||
WSTOPSIG(static_cast<unsigned>(status)));
|
||||
} else {
|
||||
HILOG_INFO(LOG_CORE, "child %d otherwise", g_processNum);
|
||||
}
|
||||
std::lock_guard<std::mutex> guard(g_taskMutex);
|
||||
// real-time type nead finish trace.
|
||||
if (g_bytraceInfo->time == 0) {
|
||||
int res = StopTrace();
|
||||
CHECK_TRUE(res, 0, "BytracePluginSessionStop, bytrace finish FAILED!");
|
||||
}
|
||||
g_bytraceInfo = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BytraceRegisterWriterStruct(const WriterStruct* writer)
|
||||
{
|
||||
HILOG_INFO(LOG_CORE, "writer %p", writer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -132,4 +167,4 @@ static PluginModuleCallbacks g_callbacks = {
|
||||
BytraceRegisterWriterStruct,
|
||||
};
|
||||
|
||||
PluginModuleStruct g_pluginModule = {&g_callbacks, "bytrace_plugin", MAX_BUFFER_SIZE};
|
||||
PluginModuleStruct g_pluginModule = {&g_callbacks, "bytrace_plugin", MAX_BUFFER_SIZE};
|
@ -25,15 +25,15 @@ constexpr uint32_t BUFFE_SIZE = 1024;
|
||||
|
||||
int main()
|
||||
{
|
||||
WriterStruct writer;
|
||||
BytraceRegisterWriterStruct(&writer);
|
||||
|
||||
BytracePluginConfig config;
|
||||
config.set_outfile_name("/data/local/tmp/bytrace.txt");
|
||||
config.set_clock("boot");
|
||||
config.set_time(TRACE_TIME);
|
||||
config.set_buffe_size(BUFFE_SIZE);
|
||||
config.set_outfile_name("/data/local/tmp/bytrace.txt");
|
||||
config.add_categories("sched");
|
||||
config.add_categories("freq");
|
||||
config.add_categories("idle");
|
||||
config.add_categories("workq");
|
||||
|
||||
std::vector<char> buffer(config.ByteSizeLong());
|
||||
CHECK_TRUE(config.SerializeToArray(buffer.data(), buffer.size()), 0, "Serialize config FAILED!");
|
||||
|
75
device/plugins/cpu_plugin/BUILD.gn
Normal file
75
device/plugins/cpu_plugin/BUILD.gn
Normal file
@ -0,0 +1,75 @@
|
||||
# Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
import("../../base/config.gni")
|
||||
|
||||
ohos_shared_library("cpudataplugin") {
|
||||
output_name = "cpudataplugin"
|
||||
sources = [
|
||||
"../memory_plugin/src/buffer_splitter.cpp",
|
||||
"src/cpu_data_plugin.cpp",
|
||||
"src/cpu_module.cpp",
|
||||
]
|
||||
include_dirs = [
|
||||
"include",
|
||||
"../memory_plugin/include",
|
||||
"${OHOS_PROFILER_DIR}/interfaces/kits",
|
||||
"${OHOS_PROFILER_DIR}/device/base/include",
|
||||
"//utils/native/base/include",
|
||||
]
|
||||
deps = [
|
||||
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf_lite",
|
||||
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protoc_lib",
|
||||
"${OHOS_PROFILER_DIR}/protos/types/plugins/cpu_data:cpu_data_cpp",
|
||||
"//utils/native/base:utilsecurec",
|
||||
]
|
||||
if (current_toolchain != host_toolchain) {
|
||||
defines = [ "HAVE_HILOG" ]
|
||||
if (build_l2) {
|
||||
external_deps = [ "shared_library:libhilog" ]
|
||||
} else {
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
}
|
||||
}
|
||||
public_configs = [ "${OHOS_PROFILER_DIR}/device/base:hiprofiler_test_config" ]
|
||||
install_enable = true
|
||||
subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}"
|
||||
}
|
||||
|
||||
ohos_executable("cpudataplugintest") {
|
||||
output_name = "cpudataplugintest"
|
||||
sources = [ "src/test_main.cpp" ]
|
||||
include_dirs = [
|
||||
"include",
|
||||
"../api/include",
|
||||
"${OHOS_PROFILER_DIR}/interfaces/kits",
|
||||
"${OHOS_PROFILER_DIR}/device/base/include",
|
||||
]
|
||||
deps = [
|
||||
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf_lite",
|
||||
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protoc_lib",
|
||||
"${OHOS_PROFILER_DIR}/protos/types/plugins/cpu_data:cpu_data_cpp",
|
||||
]
|
||||
if (current_toolchain != host_toolchain) {
|
||||
defines = [ "HAVE_HILOG" ]
|
||||
if (build_l2) {
|
||||
external_deps = [ "shared_library:libhilog" ]
|
||||
} else {
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
}
|
||||
}
|
||||
public_configs = [ "${OHOS_PROFILER_DIR}/device/base:hiprofiler_test_config" ]
|
||||
install_enable = true
|
||||
subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}"
|
||||
}
|
116
device/plugins/cpu_plugin/include/cpu_data_plugin.h
Normal file
116
device/plugins/cpu_plugin/include/cpu_data_plugin.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef CPU_DATA_PLUGIN_H
|
||||
#define CPU_DATA_PLUGIN_H
|
||||
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "cpu_plugin_config.pb.h"
|
||||
#include "cpu_plugin_result.pb.h"
|
||||
#include "logging.h"
|
||||
|
||||
enum ErrorType {
|
||||
RET_NULL_ADDR,
|
||||
RET_IVALID_PID,
|
||||
RET_TGID_VALUE_NULL,
|
||||
RET_FAIL = -1,
|
||||
RET_SUCC = 0,
|
||||
};
|
||||
|
||||
enum ProcessCpuTimeType {
|
||||
PROCESS_UTIME = 0,
|
||||
PROCESS_STIME,
|
||||
PROCESS_CUTIME,
|
||||
PROCESS_CSTIME,
|
||||
PROCESS_UNSPECIFIED,
|
||||
};
|
||||
|
||||
enum SystemCpuTimeType {
|
||||
SYSTEM_USER = 1,
|
||||
SYSTEM_NICE,
|
||||
SYSTEM_SYSTEM,
|
||||
SYSTEM_IDLE,
|
||||
SYSTEM_IOWAIT,
|
||||
SYSTEM_IRQ,
|
||||
SYSTEM_SOFTIRQ,
|
||||
SYSTEM_STEAL,
|
||||
SYSTEM_UNSPECIFIED,
|
||||
};
|
||||
|
||||
class CpuDataPlugin {
|
||||
public:
|
||||
CpuDataPlugin();
|
||||
~CpuDataPlugin();
|
||||
int Start(const uint8_t* configData, uint32_t configSize);
|
||||
int Report(uint8_t* configData, uint32_t configSize);
|
||||
int Stop();
|
||||
|
||||
private:
|
||||
int32_t ReadFile(std::string& fileName);
|
||||
void SetTimestamp(SampleTimeStamp& timestamp);
|
||||
|
||||
int64_t GetUserHz();
|
||||
int64_t GetCpuUsageTime(std::vector<std::string>& cpuUsageVec);
|
||||
void WriteProcessCpuUsage(CpuUsageInfo& cpuUsageInfo, const char* pFile, uint32_t fileLen);
|
||||
void GetSystemCpuTime(std::vector<std::string>& cpuUsageVec, int64_t& usageTime, int64_t& time);
|
||||
void WriteSystemCpuUsage(CpuUsageInfo& cpuUsageInfo, const char* pFile, uint32_t fileLen);
|
||||
void WriteCpuUsageInfo(CpuData& data);
|
||||
|
||||
bool addTidBySort(int32_t tid);
|
||||
DIR* OpenDestDir(std::string& dirPath);
|
||||
int32_t GetValidTid(DIR* dirp);
|
||||
ThreadState GetThreadState(const char threadState);
|
||||
void WriteThread(ThreadInfo& threadInfo, const char* pFile, uint32_t fileLen, int32_t tid);
|
||||
void WriteSingleThreadInfo(CpuData& data, int32_t tid);
|
||||
void WriteThreadInfo(CpuData& data);
|
||||
|
||||
int32_t GetCpuFrequency(std::string fileName);
|
||||
int GetCpuCoreSize();
|
||||
int32_t GetMaxCpuFrequencyIndex();
|
||||
void SetCpuFrequency(CpuCoreUsageInfo& cpuCore, int32_t coreNum);
|
||||
|
||||
// for UT
|
||||
void SetPath(std::string path)
|
||||
{
|
||||
path_ = path;
|
||||
}
|
||||
void SetFreqPath(std::string path);
|
||||
|
||||
private:
|
||||
/* data */
|
||||
CpuConfig protoConfig_;
|
||||
void* buffer_;
|
||||
std::string path_;
|
||||
int32_t err_;
|
||||
|
||||
int pid_;
|
||||
std::vector<int32_t> tidVec_;
|
||||
int64_t prevProcessCpuTime_;
|
||||
int64_t prevSystemCpuTime_;
|
||||
int64_t prevSystemBootTime_;
|
||||
std::map<int32_t, int64_t> prevThreadCpuTimeMap_;
|
||||
std::map<int32_t, int64_t> prevCoreSystemCpuTimeMap_;
|
||||
std::map<int32_t, int64_t> prevCoreSystemBootTimeMap_;
|
||||
std::vector<int32_t> maxFrequencyVec_;
|
||||
std::vector<int32_t> minFrequencyVec_;
|
||||
int32_t maxFreqIndex_;
|
||||
std::string freqPath_;
|
||||
};
|
||||
|
||||
#endif
|
567
device/plugins/cpu_plugin/src/cpu_data_plugin.cpp
Normal file
567
device/plugins/cpu_plugin/src/cpu_data_plugin.cpp
Normal file
@ -0,0 +1,567 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "cpu_data_plugin.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <vector>
|
||||
|
||||
#include "buffer_splitter.h"
|
||||
|
||||
namespace {
|
||||
constexpr size_t READ_BUFFER_SIZE = 1024 * 16;
|
||||
constexpr int SYSTEM_STAT_COUNT = 9;
|
||||
constexpr int STAT_COUNT = 17;
|
||||
constexpr int STAT_START = 13;
|
||||
constexpr int THREAD_NAME_POS = 1;
|
||||
constexpr int THREAD_STATE_POS = 2;
|
||||
constexpr int CPU_USER_HZ_L = 100;
|
||||
constexpr int CPU_USER_HZ_H = 1000;
|
||||
constexpr int CPU_HZ_H = 10;
|
||||
|
||||
const std::string FREQUENCY_PATH = "/sys/devices/system/cpu";
|
||||
const std::string FREQUENCY_MIN_PATH = "/cpufreq/cpuinfo_min_freq";
|
||||
const std::string FREQUENCY_MAX_PATH = "/cpufreq/cpuinfo_max_freq";
|
||||
const std::string FREQUENCY_CUR_PATH = "/cpufreq/cpuinfo_cur_freq";
|
||||
constexpr int CPU_FREQUENCY_KHZ = 1000;
|
||||
} // namespace
|
||||
|
||||
CpuDataPlugin::CpuDataPlugin()
|
||||
{
|
||||
buffer_ = nullptr;
|
||||
path_ = "/proc/";
|
||||
err_ = -1;
|
||||
pid_ = -1;
|
||||
prevProcessCpuTime_ = 0;
|
||||
prevSystemCpuTime_ = 0;
|
||||
prevSystemBootTime_ = 0;
|
||||
maxFreqIndex_ = -1;
|
||||
freqPath_ = FREQUENCY_PATH;
|
||||
}
|
||||
|
||||
CpuDataPlugin::~CpuDataPlugin()
|
||||
{
|
||||
HILOG_INFO(LOG_CORE, "plugin:~CpuDataPlugin!");
|
||||
if (buffer_ != nullptr) {
|
||||
free(buffer_);
|
||||
buffer_ = nullptr;
|
||||
}
|
||||
|
||||
tidVec_.clear();
|
||||
prevThreadCpuTimeMap_.clear();
|
||||
prevCoreSystemCpuTimeMap_.clear();
|
||||
prevCoreSystemBootTimeMap_.clear();
|
||||
maxFrequencyVec_.clear();
|
||||
minFrequencyVec_.clear();
|
||||
}
|
||||
|
||||
int CpuDataPlugin::Start(const uint8_t* configData, uint32_t configSize)
|
||||
{
|
||||
buffer_ = malloc(READ_BUFFER_SIZE);
|
||||
if (buffer_ == nullptr) {
|
||||
HILOG_ERROR(LOG_CORE, "plugin:malloc buffer_ fail");
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
if (protoConfig_.ParseFromArray(configData, configSize) <= 0) {
|
||||
HILOG_ERROR(LOG_CORE, "plugin:ParseFromArray failed");
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
if (protoConfig_.pid() > 0) {
|
||||
pid_ = protoConfig_.pid();
|
||||
} else {
|
||||
HILOG_ERROR(LOG_CORE, "plugin:Invalid pid");
|
||||
return RET_FAIL;
|
||||
}
|
||||
HILOG_INFO(LOG_CORE, "plugin:start success!");
|
||||
return RET_SUCC;
|
||||
}
|
||||
|
||||
int CpuDataPlugin::Report(uint8_t* data, uint32_t dataSize)
|
||||
{
|
||||
CpuData dataProto;
|
||||
uint32_t length;
|
||||
|
||||
WriteCpuUsageInfo(dataProto);
|
||||
WriteThreadInfo(dataProto);
|
||||
|
||||
length = dataProto.ByteSizeLong();
|
||||
if (length > dataSize) {
|
||||
return -length;
|
||||
}
|
||||
if (dataProto.SerializeToArray(data, length) > 0) {
|
||||
return length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CpuDataPlugin::Stop()
|
||||
{
|
||||
if (buffer_ != nullptr) {
|
||||
free(buffer_);
|
||||
buffer_ = nullptr;
|
||||
}
|
||||
|
||||
tidVec_.clear();
|
||||
prevThreadCpuTimeMap_.clear();
|
||||
prevCoreSystemCpuTimeMap_.clear();
|
||||
prevCoreSystemBootTimeMap_.clear();
|
||||
HILOG_INFO(LOG_CORE, "plugin:stop success!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t CpuDataPlugin::ReadFile(std::string& fileName)
|
||||
{
|
||||
int fd = -1;
|
||||
ssize_t bytesRead = 0;
|
||||
|
||||
fd = open(fileName.c_str(), O_RDONLY | O_CLOEXEC);
|
||||
if (fd == -1) {
|
||||
HILOG_ERROR(LOG_CORE, "Failed to open(%s), errno=%d", fileName.c_str(), errno);
|
||||
err_ = errno;
|
||||
return RET_FAIL;
|
||||
}
|
||||
if (buffer_ == nullptr) {
|
||||
HILOG_ERROR(LOG_CORE, "%s:Empty address, buffer_ is NULL", __func__);
|
||||
err_ = RET_NULL_ADDR;
|
||||
close(fd);
|
||||
return RET_FAIL;
|
||||
}
|
||||
bytesRead = read(fd, buffer_, READ_BUFFER_SIZE - 1);
|
||||
if (bytesRead <= 0) {
|
||||
close(fd);
|
||||
HILOG_ERROR(LOG_CORE, "Failed to read(%s), errno=%d", fileName.c_str(), errno);
|
||||
err_ = errno;
|
||||
return RET_FAIL;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
void CpuDataPlugin::SetTimestamp(SampleTimeStamp& timestamp)
|
||||
{
|
||||
timespec time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
timestamp.set_tv_sec(time.tv_sec);
|
||||
timestamp.set_tv_nsec(time.tv_nsec);
|
||||
}
|
||||
|
||||
int64_t CpuDataPlugin::GetUserHz()
|
||||
{
|
||||
int64_t hz = -1;
|
||||
int64_t user_hz = sysconf(_SC_CLK_TCK);
|
||||
switch (user_hz) {
|
||||
case CPU_USER_HZ_L:
|
||||
hz = CPU_HZ_H;
|
||||
break;
|
||||
case CPU_USER_HZ_H:
|
||||
hz = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return hz;
|
||||
}
|
||||
|
||||
int64_t CpuDataPlugin::GetCpuUsageTime(std::vector<std::string>& cpuUsageVec)
|
||||
{
|
||||
int64_t utime, stime, cutime, cstime, usageTime;
|
||||
utime = atoi(cpuUsageVec[PROCESS_UTIME].c_str());
|
||||
stime = atoi(cpuUsageVec[PROCESS_STIME].c_str());
|
||||
cutime = atoi(cpuUsageVec[PROCESS_CUTIME].c_str());
|
||||
cstime = atoi(cpuUsageVec[PROCESS_CSTIME].c_str());
|
||||
usageTime = (utime + stime + cutime + cstime) * GetUserHz();
|
||||
|
||||
return usageTime;
|
||||
}
|
||||
|
||||
void CpuDataPlugin::WriteProcessCpuUsage(CpuUsageInfo& cpuUsageInfo, const char* pFile, uint32_t fileLen)
|
||||
{
|
||||
BufferSplitter totalbuffer(const_cast<char*>(pFile), fileLen + 1);
|
||||
std::vector<std::string> cpuUsageVec;
|
||||
for (int i = 0; i < STAT_COUNT; i++) {
|
||||
totalbuffer.NextWord(' ');
|
||||
if (!totalbuffer.CurWord()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (i < STAT_START) {
|
||||
continue;
|
||||
} else {
|
||||
std::string curWord = std::string(totalbuffer.CurWord(), totalbuffer.CurWordSize());
|
||||
cpuUsageVec.push_back(curWord);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取到的数据不包含utime、stime、cutime、cstime四个数值时返回
|
||||
if (cpuUsageVec.size() != PROCESS_UNSPECIFIED) {
|
||||
HILOG_ERROR(LOG_CORE, "Failed to get process cpu usage, size=%d", cpuUsageVec.size());
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t usageTime = GetCpuUsageTime(cpuUsageVec);
|
||||
cpuUsageInfo.set_prev_process_cpu_time_ms(prevProcessCpuTime_);
|
||||
cpuUsageInfo.set_process_cpu_time_ms(usageTime);
|
||||
prevProcessCpuTime_ = usageTime;
|
||||
}
|
||||
|
||||
int32_t CpuDataPlugin::GetCpuFrequency(std::string fileName)
|
||||
{
|
||||
int32_t frequency = 0;
|
||||
int32_t ret = ReadFile(fileName);
|
||||
if (ret == RET_FAIL) {
|
||||
HILOG_ERROR(LOG_CORE, "read %s file failed", fileName.c_str());
|
||||
} else {
|
||||
frequency = atoi((char*)buffer_);
|
||||
}
|
||||
return frequency;
|
||||
}
|
||||
|
||||
int CpuDataPlugin::GetCpuCoreSize()
|
||||
{
|
||||
int coreSize = 0;
|
||||
DIR* procDir = nullptr;
|
||||
procDir = OpenDestDir(freqPath_);
|
||||
if (procDir == nullptr) {
|
||||
HILOG_ERROR(LOG_CORE, "procDir is nullptr");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (struct dirent* dirEnt = readdir(procDir)) {
|
||||
if (dirEnt->d_type != DT_DIR) {
|
||||
continue;
|
||||
}
|
||||
if (strncmp(dirEnt->d_name, "cpu", strlen("cpu")) == 0) {
|
||||
coreSize++;
|
||||
}
|
||||
}
|
||||
|
||||
return coreSize;
|
||||
}
|
||||
|
||||
int32_t CpuDataPlugin::GetMaxCpuFrequencyIndex()
|
||||
{
|
||||
int coreSize = GetCpuCoreSize();
|
||||
int index = -1;
|
||||
int32_t maxFreq = -1;
|
||||
maxFrequencyVec_.clear();
|
||||
minFrequencyVec_.clear();
|
||||
for (int i = 0; i < coreSize; i++) {
|
||||
std::string fileName = freqPath_ + "/cpu" + std::to_string(i) + FREQUENCY_MAX_PATH;
|
||||
int32_t maxFrequency = GetCpuFrequency(fileName);
|
||||
maxFrequencyVec_.push_back(maxFrequency);
|
||||
fileName = freqPath_ + "/cpu" + std::to_string(i) + FREQUENCY_MIN_PATH;
|
||||
int32_t minFrequency = GetCpuFrequency(fileName);
|
||||
minFrequencyVec_.push_back(minFrequency);
|
||||
|
||||
if (maxFreq < maxFrequency) {
|
||||
maxFreq = maxFrequency;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
// 单核或所有核最大频率相同,默认小核
|
||||
if (coreSize == 1 || (coreSize > 1 && index == 0 && maxFreq == maxFrequencyVec_[1])) {
|
||||
index = -1;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void CpuDataPlugin::SetCpuFrequency(CpuCoreUsageInfo& cpuCore, int32_t coreNum)
|
||||
{
|
||||
// 第一次获取最大频率核位置,并保存各核最大最小频率到vector
|
||||
if (maxFrequencyVec_.empty() || minFrequencyVec_.empty()) {
|
||||
maxFreqIndex_ = GetMaxCpuFrequencyIndex();
|
||||
}
|
||||
std::string fileName = freqPath_ + "/cpu" + std::to_string(coreNum) + FREQUENCY_CUR_PATH;
|
||||
int32_t curFrequency = GetCpuFrequency(fileName) / CPU_FREQUENCY_KHZ;
|
||||
int32_t maxFrequency = maxFrequencyVec_[coreNum] / CPU_FREQUENCY_KHZ;
|
||||
int32_t minFrequency = minFrequencyVec_[coreNum] / CPU_FREQUENCY_KHZ;
|
||||
|
||||
if (coreNum == maxFreqIndex_) {
|
||||
cpuCore.set_is_little_core(false);
|
||||
} else {
|
||||
cpuCore.set_is_little_core(true);
|
||||
}
|
||||
CpuCoreFrequency* frequency = cpuCore.mutable_frequency();
|
||||
frequency->set_min_frequency_khz(minFrequency);
|
||||
frequency->set_max_frequency_khz(maxFrequency);
|
||||
frequency->set_cur_frequency_khz(curFrequency);
|
||||
}
|
||||
|
||||
void CpuDataPlugin::GetSystemCpuTime(std::vector<std::string>& cpuUsageVec, int64_t& usageTime, int64_t& time)
|
||||
{
|
||||
// 获取到的数据不包含user, nice, system, idle, iowait, irq, softirq, steal八个数值时返回
|
||||
if (cpuUsageVec.size() != SYSTEM_UNSPECIFIED) {
|
||||
HILOG_ERROR(LOG_CORE, "Failed to get system cpu usage, size=%d", cpuUsageVec.size());
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t user, nice, system, idle, iowait, irq, softirq, steal;
|
||||
user = atoi(cpuUsageVec[SYSTEM_USER].c_str());
|
||||
nice = atoi(cpuUsageVec[SYSTEM_NICE].c_str());
|
||||
system = atoi(cpuUsageVec[SYSTEM_SYSTEM].c_str());
|
||||
idle = atoi(cpuUsageVec[SYSTEM_IDLE].c_str());
|
||||
iowait = atoi(cpuUsageVec[SYSTEM_IOWAIT].c_str());
|
||||
irq = atoi(cpuUsageVec[SYSTEM_IRQ].c_str());
|
||||
softirq = atoi(cpuUsageVec[SYSTEM_SOFTIRQ].c_str());
|
||||
steal = atoi(cpuUsageVec[SYSTEM_STEAL].c_str());
|
||||
|
||||
usageTime = (user + nice + system + irq + softirq + steal) * GetUserHz();
|
||||
time = (usageTime + idle + iowait) * GetUserHz();
|
||||
}
|
||||
|
||||
void CpuDataPlugin::WriteSystemCpuUsage(CpuUsageInfo& cpuUsageInfo, const char* pFile, uint32_t fileLen)
|
||||
{
|
||||
BufferSplitter totalbuffer(const_cast<char*>(pFile), fileLen + 1);
|
||||
std::vector<std::string> cpuUsageVec;
|
||||
int64_t usageTime, time;
|
||||
size_t cpuLength = strlen("cpu");
|
||||
|
||||
do {
|
||||
totalbuffer.NextWord(' ');
|
||||
if (strncmp(totalbuffer.CurWord(), "cpu", cpuLength) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < SYSTEM_STAT_COUNT; i++) {
|
||||
if (!totalbuffer.CurWord()) {
|
||||
return;
|
||||
}
|
||||
std::string curWord = std::string(totalbuffer.CurWord(), totalbuffer.CurWordSize());
|
||||
cpuUsageVec.push_back(curWord);
|
||||
totalbuffer.NextWord(' ');
|
||||
}
|
||||
|
||||
GetSystemCpuTime(cpuUsageVec, usageTime, time);
|
||||
if (strcmp(cpuUsageVec[0].c_str(), "cpu") == 0) {
|
||||
cpuUsageInfo.set_prev_system_cpu_time_ms(prevSystemCpuTime_);
|
||||
cpuUsageInfo.set_prev_system_boot_time_ms(prevSystemBootTime_);
|
||||
cpuUsageInfo.set_system_cpu_time_ms(usageTime);
|
||||
cpuUsageInfo.set_system_boot_time_ms(time);
|
||||
prevSystemCpuTime_ = usageTime;
|
||||
prevSystemBootTime_ = time;
|
||||
} else {
|
||||
std::string core = std::string(cpuUsageVec[0].c_str() + cpuLength, cpuUsageVec[0].size() - cpuLength);
|
||||
int32_t coreNum = atoi(core.c_str());
|
||||
// 第一次获取数据时需要将前一个数据置为0
|
||||
if (prevCoreSystemCpuTimeMap_.size() == static_cast<size_t>(coreNum)) {
|
||||
prevCoreSystemCpuTimeMap_[coreNum] = 0;
|
||||
prevCoreSystemBootTimeMap_[coreNum] = 0;
|
||||
}
|
||||
CpuCoreUsageInfo* cpuCore = cpuUsageInfo.add_cores();
|
||||
cpuCore->set_cpu_core(coreNum);
|
||||
cpuCore->set_prev_system_cpu_time_ms(prevCoreSystemCpuTimeMap_[coreNum]);
|
||||
cpuCore->set_prev_system_boot_time_ms(prevCoreSystemBootTimeMap_[coreNum]);
|
||||
cpuCore->set_system_cpu_time_ms(usageTime);
|
||||
cpuCore->set_system_boot_time_ms(time);
|
||||
|
||||
SetCpuFrequency(*cpuCore, coreNum);
|
||||
prevCoreSystemCpuTimeMap_[coreNum] = usageTime;
|
||||
prevCoreSystemBootTimeMap_[coreNum] = time;
|
||||
}
|
||||
|
||||
cpuUsageVec.clear();
|
||||
usageTime = 0;
|
||||
time = 0;
|
||||
} while (totalbuffer.NextLine());
|
||||
}
|
||||
|
||||
void CpuDataPlugin::WriteCpuUsageInfo(CpuData& data)
|
||||
{
|
||||
// write process info
|
||||
std::string fileName = path_ + std::to_string(pid_) + "/stat";
|
||||
int32_t ret = ReadFile(fileName);
|
||||
if (ret == RET_FAIL) {
|
||||
HILOG_ERROR(LOG_CORE, "read /proc/pid/stat file failed");
|
||||
return;
|
||||
}
|
||||
if ((buffer_ == nullptr) || (ret == 0)) {
|
||||
HILOG_ERROR(LOG_CORE, "%s:invalid params, read buffer_ is NULL", __func__);
|
||||
return;
|
||||
}
|
||||
auto* cpuUsageInfo = data.mutable_cpu_usage_info();
|
||||
WriteProcessCpuUsage(*cpuUsageInfo, (char*)buffer_, ret);
|
||||
|
||||
// write system info
|
||||
fileName = path_ + "stat";
|
||||
ret = ReadFile(fileName);
|
||||
if (ret == RET_FAIL) {
|
||||
HILOG_ERROR(LOG_CORE, "read /proc/stat file failed");
|
||||
return;
|
||||
}
|
||||
if ((buffer_ == nullptr) || (ret == 0)) {
|
||||
HILOG_ERROR(LOG_CORE, "%s:invalid params, read buffer_ is NULL", __func__);
|
||||
return;
|
||||
}
|
||||
WriteSystemCpuUsage(*cpuUsageInfo, (char*)buffer_, ret);
|
||||
|
||||
auto* timestamp = cpuUsageInfo->mutable_timestamp();
|
||||
SetTimestamp(*timestamp);
|
||||
}
|
||||
|
||||
bool CpuDataPlugin::addTidBySort(int32_t tid)
|
||||
{
|
||||
auto tidsEnd = tidVec_.end();
|
||||
auto it = std::lower_bound(tidVec_.begin(), tidsEnd, tid);
|
||||
if (it != tidsEnd && *it == tid) {
|
||||
return false;
|
||||
}
|
||||
it = tidVec_.insert(it, std::move(tid));
|
||||
return true;
|
||||
}
|
||||
|
||||
DIR* CpuDataPlugin::OpenDestDir(std::string& dirPath)
|
||||
{
|
||||
DIR* destDir = nullptr;
|
||||
|
||||
destDir = opendir(dirPath.c_str());
|
||||
if (destDir == nullptr) {
|
||||
HILOG_ERROR(LOG_CORE, "Failed to opendir(%s), errno=%d", dirPath.c_str(), errno);
|
||||
}
|
||||
|
||||
return destDir;
|
||||
}
|
||||
|
||||
int32_t CpuDataPlugin::GetValidTid(DIR* dirp)
|
||||
{
|
||||
if (!dirp) {
|
||||
return 0;
|
||||
}
|
||||
while (struct dirent* dirEnt = readdir(dirp)) {
|
||||
if (dirEnt->d_type != DT_DIR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t tid = atoi(dirEnt->d_name);
|
||||
if (tid) {
|
||||
return tid;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ThreadState CpuDataPlugin::GetThreadState(const char threadState)
|
||||
{
|
||||
ThreadState state = THREAD_UNSPECIFIED;
|
||||
switch (threadState) {
|
||||
case 'R':
|
||||
state = THREAD_RUNNING;
|
||||
break;
|
||||
case 'S':
|
||||
state = THREAD_SLEEPING;
|
||||
break;
|
||||
case 'T':
|
||||
state = THREAD_STOPPED;
|
||||
break;
|
||||
case 'D':
|
||||
state = THREAD_WAITING;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void CpuDataPlugin::WriteThread(ThreadInfo& threadInfo, const char* pFile, uint32_t fileLen, int32_t tid)
|
||||
{
|
||||
BufferSplitter totalbuffer(const_cast<char*>(pFile), fileLen + 1);
|
||||
std::vector<std::string> cpuUsageVec;
|
||||
for (int i = 0; i < STAT_COUNT; i++) {
|
||||
totalbuffer.NextWord(' ');
|
||||
if (!totalbuffer.CurWord()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (i == THREAD_NAME_POS) {
|
||||
std::string curWord = std::string(totalbuffer.CurWord() + 1, totalbuffer.CurWordSize() - sizeof(")"));
|
||||
threadInfo.set_thread_name(curWord);
|
||||
} else if (i == THREAD_STATE_POS) {
|
||||
std::string curWord = std::string(totalbuffer.CurWord(), totalbuffer.CurWordSize());
|
||||
ThreadState state = GetThreadState(curWord[0]);
|
||||
threadInfo.set_thread_state(state);
|
||||
} else if (i >= STAT_START) {
|
||||
std::string curWord = std::string(totalbuffer.CurWord(), totalbuffer.CurWordSize());
|
||||
cpuUsageVec.push_back(curWord);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取到的数据不包含utime、stime、cutime、cstime四个数值时返回
|
||||
if (cpuUsageVec.size() != PROCESS_UNSPECIFIED) {
|
||||
HILOG_ERROR(LOG_CORE, "Failed to get thread cpu usage, size=%d", cpuUsageVec.size());
|
||||
return;
|
||||
}
|
||||
|
||||
// 第一次获取该线程数据时需要将前一个数据置为0
|
||||
if (prevThreadCpuTimeMap_.find(tid) == prevThreadCpuTimeMap_.end()) {
|
||||
prevThreadCpuTimeMap_[tid] = 0;
|
||||
}
|
||||
|
||||
int64_t usageTime = GetCpuUsageTime(cpuUsageVec);
|
||||
threadInfo.set_prev_thread_cpu_time_ms(prevThreadCpuTimeMap_[tid]);
|
||||
threadInfo.set_thread_cpu_time_ms(usageTime);
|
||||
prevThreadCpuTimeMap_[tid] = usageTime;
|
||||
threadInfo.set_tid(tid);
|
||||
|
||||
auto* timestamp = threadInfo.mutable_timestamp();
|
||||
SetTimestamp(*timestamp);
|
||||
}
|
||||
|
||||
void CpuDataPlugin::WriteSingleThreadInfo(CpuData& data, int32_t tid)
|
||||
{
|
||||
std::string fileName = path_ + std::to_string(pid_) + "/task/" + std::to_string(tid) + "/stat";
|
||||
int32_t ret = ReadFile(fileName);
|
||||
if (ret == RET_FAIL) {
|
||||
HILOG_ERROR(LOG_CORE, "%s:read tid file failed", fileName.c_str());
|
||||
return;
|
||||
}
|
||||
if ((buffer_ == nullptr) || (ret == 0)) {
|
||||
HILOG_ERROR(LOG_CORE, "%s:invalid params, read buffer_ is NULL", __func__);
|
||||
return;
|
||||
}
|
||||
auto* threadInfo = data.add_thread_info();
|
||||
WriteThread(*threadInfo, (char*)buffer_, ret, tid);
|
||||
}
|
||||
|
||||
void CpuDataPlugin::WriteThreadInfo(CpuData& data)
|
||||
{
|
||||
DIR* procDir = nullptr;
|
||||
std::string path = path_ + std::to_string(pid_) + "/task";
|
||||
procDir = OpenDestDir(path);
|
||||
if (procDir == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (int32_t tid = GetValidTid(procDir)) {
|
||||
if (find(tidVec_.begin(), tidVec_.end(), tid) == tidVec_.end()) {
|
||||
addTidBySort(tid);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < tidVec_.size(); i++) {
|
||||
WriteSingleThreadInfo(data, tidVec_[i]);
|
||||
}
|
||||
closedir(procDir);
|
||||
}
|
||||
|
||||
// for UT
|
||||
void CpuDataPlugin::SetFreqPath(std::string path)
|
||||
{
|
||||
freqPath_ = path + FREQUENCY_PATH;
|
||||
}
|
55
device/plugins/cpu_plugin/src/cpu_module.cpp
Normal file
55
device/plugins/cpu_plugin/src/cpu_module.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "cpu_data_plugin.h"
|
||||
#include "plugin_module_api.h"
|
||||
|
||||
namespace {
|
||||
constexpr uint32_t MAX_BUFFER_SIZE = 4 * 1024 * 1024;
|
||||
std::unique_ptr<CpuDataPlugin> g_plugin = nullptr;
|
||||
std::mutex g_taskMutex;
|
||||
} // namespace
|
||||
|
||||
static int CpuDataPluginSessionStart(const uint8_t* configData, uint32_t configSize)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(g_taskMutex);
|
||||
g_plugin = std::make_unique<CpuDataPlugin>();
|
||||
return g_plugin->Start(configData, configSize);
|
||||
}
|
||||
|
||||
static int CpuPluginReportResult(uint8_t* bufferData, uint32_t bufferSize)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(g_taskMutex);
|
||||
return g_plugin->Report(bufferData, bufferSize);
|
||||
}
|
||||
|
||||
static int CpuPluginSessionStop()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(g_taskMutex);
|
||||
HILOG_INFO(LOG_CORE, "%s:stop Session success!", __func__);
|
||||
g_plugin->Stop();
|
||||
g_plugin = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PluginModuleCallbacks g_callbacks = {
|
||||
CpuDataPluginSessionStart,
|
||||
CpuPluginReportResult,
|
||||
CpuPluginSessionStop,
|
||||
};
|
||||
|
||||
PluginModuleStruct g_pluginModule = {&g_callbacks, "cpu-plugin", MAX_BUFFER_SIZE};
|
107
device/plugins/cpu_plugin/src/test_main.cpp
Normal file
107
device/plugins/cpu_plugin/src/test_main.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "cpu_plugin_config.pb.h"
|
||||
#include "cpu_plugin_result.pb.h"
|
||||
#include "plugin_module_api.h"
|
||||
|
||||
namespace {
|
||||
constexpr int TEST_PID = 10;
|
||||
int g_testCount = 10;
|
||||
} // namespace
|
||||
|
||||
static void Report(PluginModuleStruct*& cpuPlugin, std::vector<uint8_t>& dataBuffer)
|
||||
{
|
||||
while (g_testCount--) {
|
||||
int len = cpuPlugin->callbacks->onPluginReportResult(dataBuffer.data(), cpuPlugin->resultBufferSizeHint);
|
||||
std::cout << "test:filler buffer length = " << len << std::endl;
|
||||
|
||||
if (len > 0) {
|
||||
CpuData cpuData;
|
||||
cpuData.ParseFromArray(dataBuffer.data(), len);
|
||||
std::cout << "test:ParseFromArray length = " << len << std::endl;
|
||||
|
||||
CpuUsageInfo cpuUsageInfo = cpuData.cpu_usage_info();
|
||||
std::cout << "prev_process_cpu_time_ms:" << cpuUsageInfo.prev_process_cpu_time_ms() << std::endl;
|
||||
std::cout << "prev_system_cpu_time_ms:" << cpuUsageInfo.prev_system_cpu_time_ms() << std::endl;
|
||||
std::cout << "prev_system_boot_time_ms:" << cpuUsageInfo.prev_system_boot_time_ms() << std::endl;
|
||||
std::cout << "process_cpu_time_ms:" << cpuUsageInfo.process_cpu_time_ms() << std::endl;
|
||||
std::cout << "system_cpu_time_ms:" << cpuUsageInfo.system_cpu_time_ms() << std::endl;
|
||||
std::cout << "system_boot_time_ms:" << cpuUsageInfo.system_boot_time_ms() << std::endl;
|
||||
|
||||
for (int i = 0; i < cpuUsageInfo.cores_size(); i++) {
|
||||
CpuCoreUsageInfo cpuCoreUsageInfo = cpuUsageInfo.cores()[i];
|
||||
std::cout << "cpu_core:" << cpuCoreUsageInfo.cpu_core() << std::endl;
|
||||
std::cout << "prev_system_cpu_time_ms:" << cpuCoreUsageInfo.prev_system_cpu_time_ms() << std::endl;
|
||||
std::cout << "prev_system_boot_time_ms:" << cpuCoreUsageInfo.prev_system_boot_time_ms() << std::endl;
|
||||
std::cout << "system_cpu_time_ms:" << cpuCoreUsageInfo.system_cpu_time_ms() << std::endl;
|
||||
std::cout << "system_boot_time_ms:" << cpuCoreUsageInfo.system_boot_time_ms() << std::endl;
|
||||
std::cout << "min_frequency_khz:" << cpuCoreUsageInfo.frequency().min_frequency_khz() << std::endl;
|
||||
std::cout << "max_frequency_khz:" << cpuCoreUsageInfo.frequency().max_frequency_khz() << std::endl;
|
||||
std::cout << "cur_frequency_khz:" << cpuCoreUsageInfo.frequency().cur_frequency_khz() << std::endl;
|
||||
std::cout << "is_little_core:" << cpuCoreUsageInfo.is_little_core() << std::endl;
|
||||
}
|
||||
std::cout << "timestamp.tv_sec : " << cpuUsageInfo.timestamp().tv_sec() << std::endl;
|
||||
std::cout << "timestamp.tv_nsec : " << cpuUsageInfo.timestamp().tv_nsec() << std::endl;
|
||||
|
||||
for (int i = 0; i < cpuData.thread_info_size(); i++) {
|
||||
ThreadInfo threadInfo = cpuData.thread_info()[i];
|
||||
std::cout << "tid : " << threadInfo.tid() << std::endl;
|
||||
std::cout << "thread_name : " << threadInfo.thread_name() << std::endl;
|
||||
std::cout << "thread_state : " << threadInfo.thread_state() << std::endl;
|
||||
std::cout << "prev_thread_cpu_time_ms : " << threadInfo.prev_thread_cpu_time_ms() << std::endl;
|
||||
std::cout << "thread_cpu_time_ms : " << threadInfo.thread_cpu_time_ms() << std::endl;
|
||||
std::cout << "timestamp.tv_sec : " << threadInfo.timestamp().tv_sec() << std::endl;
|
||||
std::cout << "timestamp.tv_nsec : " << threadInfo.timestamp().tv_nsec() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "test:sleep...................." << std::endl;
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
CpuConfig protoConfig;
|
||||
void* handle = dlopen("./libcpudataplugin.z.so", RTLD_LAZY);
|
||||
if (handle == nullptr) {
|
||||
std::cout << "test:dlopen err: " << dlerror() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
std::cout << "test:handle = " << handle << std::endl;
|
||||
PluginModuleStruct* cpuPlugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule");
|
||||
std::cout << "test:name = " << cpuPlugin->name << std::endl;
|
||||
std::cout << "test:buffer size = " << cpuPlugin->resultBufferSizeHint << std::endl;
|
||||
|
||||
// Serialize config
|
||||
protoConfig.set_pid(TEST_PID);
|
||||
int configLength = protoConfig.ByteSizeLong();
|
||||
std::vector<uint8_t> configBuffer(configLength);
|
||||
int ret = protoConfig.SerializeToArray(configBuffer.data(), configLength);
|
||||
std::cout << "test:configLength = " << configLength << std::endl;
|
||||
std::cout << "test:serialize success start plugin ret = " << ret << std::endl;
|
||||
|
||||
// run plugin
|
||||
std::vector<uint8_t> dataBuffer(cpuPlugin->resultBufferSizeHint);
|
||||
cpuPlugin->callbacks->onPluginSessionStart(configBuffer.data(), configLength);
|
||||
Report(cpuPlugin, dataBuffer);
|
||||
cpuPlugin->callbacks->onPluginSessionStop();
|
||||
|
||||
return 0;
|
||||
}
|
55
device/plugins/cpu_plugin/test/BUILD.gn
Normal file
55
device/plugins/cpu_plugin/test/BUILD.gn
Normal file
@ -0,0 +1,55 @@
|
||||
# Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/test.gni")
|
||||
import("../../../base/config.gni")
|
||||
|
||||
module_output_path = "${OHOS_PROFILER_TEST_MODULE_OUTPUT_PATH}/device"
|
||||
config("module_private_config") {
|
||||
visibility = [ ":*" ]
|
||||
if (current_toolchain != host_toolchain) {
|
||||
defines = [ "HAVE_HILOG" ]
|
||||
}
|
||||
}
|
||||
|
||||
ohos_unittest("cpudataplugin_ut") {
|
||||
module_out_path = module_output_path
|
||||
sources = [ "unittest/cpu_data_plugin_unittest.cpp" ]
|
||||
deps = [
|
||||
"${OHOS_PROFILER_DIR}/device/plugins/cpu_plugin:cpudataplugin",
|
||||
"${OHOS_PROFILER_DIR}/protos/types/plugins/cpu_data:cpu_data_cpp",
|
||||
"//third_party/googletest:gtest_main",
|
||||
"//utils/native/base:utilsecurec",
|
||||
]
|
||||
include_dirs = [
|
||||
"../include",
|
||||
"../../../memory_plugin/include",
|
||||
"${OHOS_PROFILER_DIR}/interfaces/kits",
|
||||
"${OHOS_PROFILER_DIR}/device/base/include",
|
||||
"//third_party/googletest/googletest/include/gtest",
|
||||
"//utils/native/base/include",
|
||||
]
|
||||
cflags = [
|
||||
"-Wno-inconsistent-missing-override",
|
||||
"-Dprivate=public", #allow test code access private members
|
||||
]
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
configs = [ ":module_private_config" ]
|
||||
subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}"
|
||||
resource_config_file = "${OHOS_PROFILER_DIR}/device/ohos_test.xml"
|
||||
}
|
||||
|
||||
group("unittest") {
|
||||
testonly = true
|
||||
deps = [ ":cpudataplugin_ut" ]
|
||||
}
|
1
device/plugins/cpu_plugin/test/resources/proc/1872/stat
Normal file
1
device/plugins/cpu_plugin/test/resources/proc/1872/stat
Normal file
@ -0,0 +1 @@
|
||||
1872 (ibus-x11) S 1 1865 1780 1025 1780 4194304 3233 0 457 0 60 10 20 30 20 0 7 0 4394 726278144 0 18446744073709551615 1 1 0 0 0 0 0 16781312 16386 0 0 0 17 5 0 0 5 0 0 0 0 0 0 0 0 0 0
|
@ -0,0 +1 @@
|
||||
1872 (ibus-x11) R 1 1865 1780 1025 1780 4194304 3217 0 457 0 17 5 10 10 20 0 7 0 4394 726278144 0 18446744073709551615 1 1 0 0 0 0 0 16781312 16386 0 0 0 17 5 0 0 5 0 0 0 0 0 0 0 0 0 0
|
@ -0,0 +1 @@
|
||||
1965 (ibus-x1:disk$0) S 1 1865 1780 1025 1780 1077936192 1 0 0 0 8 1 5 8 20 0 7 0 4444 726278144 0 18446744073709551615 1 1 0 0 0 0 1073479423 16781312 16386 0 0 0 -1 5 0 5 0 0 0 0 0 0 0 0 0 0 0
|
@ -0,0 +1 @@
|
||||
1966 (ibus-x1:disk$1) X 1 1865 1780 1025 1780 1077936192 1 0 0 0 0 0 0 0 20 0 7 0 4444 726278144 0 18446744073709551615 1 1 0 0 0 0 1073479423 16781312 16386 0 0 0 -1 5 0 5 0 0 0 0 0 0 0 0 0 0 0
|
@ -0,0 +1 @@
|
||||
1967 (ibus-x1:disk$2) S 1 1865 1780 1025 1780 1077936192 1 0 0 0 10 1 5 8 20 0 7 0 4444 726278144 0 18446744073709551615 1 1 0 0 0 0 1073479423 16781312 16386 0 0 0 -1 5 0 5 0 0 0 0 0 0 0 0 0 0 0
|
@ -0,0 +1 @@
|
||||
1968 (ibus-x1:disk$3) T 1 1865 1780 1025 1780 1077936192 1 0 0 0 7 0 0 0 20 0 7 0 4444 726278144 0 18446744073709551615 1 1 0 0 0 0 1073479423 16781312 16386 0 0 0 -1 5 0 5 0 0 0 0 0 0 0 0 0 0 0
|
@ -0,0 +1 @@
|
||||
1995 (gmain) S 1 1865 1780 1025 1780 4194368 1 0 0 0 15 3 0 4 20 0 7 0 4446 726278144 0 18446744073709551615 1 1 0 0 0 0 2147221247 16781312 16386 0 0 0 -1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
|
@ -0,0 +1 @@
|
||||
1996 (gdbus) D 1 1865 1780 1025 1780 4194368 11 0 0 0 5 0 0 0 20 0 7 0 4446 726278144 0 18446744073709551615 1 1 0 0 0 0 0 16781312 16386 0 0 0 -1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
|
14
device/plugins/cpu_plugin/test/resources/proc/stat
Normal file
14
device/plugins/cpu_plugin/test/resources/proc/stat
Normal file
@ -0,0 +1,14 @@
|
||||
cpu 24875428 3952448 11859815 1193297105 8980661 0 2607250 0 0 0
|
||||
cpu0 4165400 662862 1966195 196987024 3571925 0 817371 0 0 0
|
||||
cpu1 3861506 676578 1702753 199535158 1752008 0 401639 0 0 0
|
||||
cpu2 3549890 676286 1544630 200640747 1133743 0 205972 0 0 0
|
||||
cpu3 3336646 676939 1458898 201176432 854578 0 124812 0 0 0
|
||||
cpu4 4566158 601107 2305309 197166395 929594 0 1007959 0 0 0
|
||||
cpu5 5395826 658673 2882028 197791346 738811 0 49496 0 0 0
|
||||
intr 1770859348 7 4 0 0 0 0 0 0 1 11 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 171 59725591 981403168 19 439482 559268 457611 427943 581724 453376 45 20991 669 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
ctxt 2926398868
|
||||
btime 1620093904
|
||||
processes 18239603
|
||||
procs_running 1
|
||||
procs_blocked 0
|
||||
softirq 2254950393 2090427 450858980 2885663 985716628 59484869 0 134917257 208251538 45883 410699148
|
@ -0,0 +1 @@
|
||||
1018000
|
@ -0,0 +1 @@
|
||||
3844000
|
@ -0,0 +1 @@
|
||||
509000
|
@ -0,0 +1 @@
|
||||
1023000
|
@ -0,0 +1 @@
|
||||
2844000
|
@ -0,0 +1 @@
|
||||
509000
|
@ -0,0 +1 @@
|
||||
1011000
|
@ -0,0 +1 @@
|
||||
3844000
|
@ -0,0 +1 @@
|
||||
509000
|
@ -0,0 +1 @@
|
||||
1518000
|
@ -0,0 +1 @@
|
||||
3844000
|
@ -0,0 +1 @@
|
||||
1018000
|
@ -0,0 +1 @@
|
||||
1245000
|
@ -0,0 +1 @@
|
||||
1844000
|
@ -0,0 +1 @@
|
||||
1018000
|
@ -0,0 +1 @@
|
||||
1767000
|
@ -0,0 +1 @@
|
||||
3044000
|
@ -0,0 +1 @@
|
||||
1018000
|
@ -0,0 +1,399 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <cinttypes>
|
||||
#include <hwext/gtest-ext.h>
|
||||
#include <hwext/gtest-tag.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "cpu_data_plugin.h"
|
||||
#include "plugin_module_api.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace {
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
const std::string DEFAULT_TEST_PATH = "./resources";
|
||||
#else
|
||||
const std::string DEFAULT_TEST_PATH = "/data/local/tmp/resources";
|
||||
#endif
|
||||
|
||||
constexpr uint32_t BUF_SIZE = 4 * 1024 * 1024;
|
||||
const std::string SO_PATH = "/system/lib/libcpudataplugin.z.so";
|
||||
constexpr int TEST_PID = 1;
|
||||
|
||||
std::string g_path;
|
||||
std::string g_testPath;
|
||||
std::vector<int> g_tidList = {1872, 1965, 1966, 1967, 1968, 1995, 1996};
|
||||
|
||||
constexpr int CORE_NUM = 6;
|
||||
constexpr int THREAD_NUM = 7;
|
||||
|
||||
struct TestSystemStat {
|
||||
int32_t core;
|
||||
int64_t user;
|
||||
int64_t nice;
|
||||
int64_t system;
|
||||
int64_t idle;
|
||||
int64_t iowait;
|
||||
int64_t irq;
|
||||
int64_t softirq;
|
||||
int64_t steal;
|
||||
};
|
||||
|
||||
struct TestStat {
|
||||
int64_t utime;
|
||||
int64_t stime;
|
||||
int64_t cutime;
|
||||
int64_t cstime;
|
||||
};
|
||||
|
||||
struct TestTidStat {
|
||||
int32_t tid;
|
||||
std::string name;
|
||||
ThreadState state;
|
||||
TestStat stat;
|
||||
};
|
||||
|
||||
struct TestFreq {
|
||||
int32_t curFreq;
|
||||
int32_t maxFreq;
|
||||
int32_t minFreq;
|
||||
};
|
||||
|
||||
TestSystemStat g_systemStat[CORE_NUM + 1] = {
|
||||
{-1, 24875428, 3952448, 11859815, 1193297105, 8980661, 0, 2607250, 0},
|
||||
{0, 4165400, 662862, 1966195, 196987024, 3571925, 0, 817371, 0},
|
||||
{1, 3861506, 676578, 1702753, 199535158, 1752008, 0, 401639, 0},
|
||||
{2, 3549890, 676286, 1544630, 200640747, 1133743, 0, 205972, 0},
|
||||
{3, 3336646, 676939, 1458898, 201176432, 854578, 0, 124812, 0},
|
||||
{4, 4566158, 601107, 2305309, 197166395, 929594, 0, 1007959, 0},
|
||||
{5, 5395826, 658673, 2882028, 197791346, 738811, 0, 49496, 0},
|
||||
};
|
||||
|
||||
TestStat g_pidStat = {60, 10, 20, 30};
|
||||
|
||||
TestTidStat g_tidStat[THREAD_NUM] = {
|
||||
{1872, "ibus-x11", THREAD_RUNNING, {17, 5, 10, 10}},
|
||||
{1965, "ibus-x1:disk$0", THREAD_SLEEPING, {8, 1, 5, 8}},
|
||||
{1966, "ibus-x1:disk$1", THREAD_UNSPECIFIED, {0, 0, 0, 0}},
|
||||
{1967, "ibus-x1:disk$2", THREAD_SLEEPING, {10, 1, 5, 8}},
|
||||
{1968, "ibus-x1:disk$3", THREAD_STOPPED, {7, 0, 0, 0}},
|
||||
{1995, "gmain", THREAD_SLEEPING, {15, 3, 0, 4}},
|
||||
{1996, "gdbus", THREAD_WAITING, {5, 0, 0, 0}},
|
||||
};
|
||||
|
||||
TestFreq g_Freq[CORE_NUM + 1] = {
|
||||
{1018, 3844, 509}, {1023, 2844, 509}, {1011, 3844, 509}, {1518, 3844, 1018}, {1245, 1844, 1018}, {1767, 3044, 1018},
|
||||
};
|
||||
|
||||
class CpuDataPluginTest : public ::testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase() {}
|
||||
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
if (access(g_testPath.c_str(), F_OK) == 0) {
|
||||
std::string str = "rm -rf " + g_testPath;
|
||||
printf("TearDown--> %s\r\n", str.c_str());
|
||||
system(str.c_str());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
string Getexepath()
|
||||
{
|
||||
char buf[PATH_MAX] = "";
|
||||
std::string path = "/proc/self/exe";
|
||||
size_t rslt = readlink(path.c_str(), buf, sizeof(buf));
|
||||
if (rslt < 0 || (rslt >= sizeof(buf))) {
|
||||
return "";
|
||||
}
|
||||
buf[rslt] = '\0';
|
||||
for (int i = rslt; i >= 0; i--) {
|
||||
if (buf[i] == '/') {
|
||||
buf[i + 1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string GetFullPath(std::string path)
|
||||
{
|
||||
if (path.size() > 0 && path[0] != '/') {
|
||||
return Getexepath() + path;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
bool CreatTestResource(std::string path, std::string exepath)
|
||||
{
|
||||
std::string str = "cp -r " + path + " " + exepath;
|
||||
printf("CreatTestResource:%s\n", str.c_str());
|
||||
|
||||
pid_t status = system(str.c_str());
|
||||
if (-1 == status) {
|
||||
printf("system error!");
|
||||
} else {
|
||||
printf("exit status value = [0x%x]\n", status);
|
||||
if (WIFEXITED(status)) {
|
||||
if (WEXITSTATUS(status) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
printf("run shell script fail, script exit code: %d\n", WEXITSTATUS(status));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
printf("exit status = [%d]\n", WEXITSTATUS(status));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CheckTid(std::vector<int>& tidListTmp)
|
||||
{
|
||||
sort(g_tidList.begin(), g_tidList.end());
|
||||
for (size_t i = 0; i < g_tidList.size(); i++) {
|
||||
if (tidListTmp.at(i) != g_tidList.at(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PluginCpuinfoStub(CpuDataPlugin& cpuPlugin, CpuData& cpuData, int pid, bool unusualBuff)
|
||||
{
|
||||
CpuConfig protoConfig;
|
||||
protoConfig.set_pid(pid);
|
||||
|
||||
// serialize
|
||||
std::vector<uint8_t> configData(protoConfig.ByteSizeLong());
|
||||
int ret = protoConfig.SerializeToArray(configData.data(), configData.size());
|
||||
|
||||
// start
|
||||
ret = cpuPlugin.Start(configData.data(), configData.size());
|
||||
if (ret < 0) {
|
||||
return false;
|
||||
}
|
||||
printf("ut: serialize success start plugin ret = %d\n", ret);
|
||||
|
||||
// report
|
||||
std::vector<uint8_t> bufferData(BUF_SIZE);
|
||||
if (unusualBuff) { // buffer异常,调整缓冲区长度为1,测试异常情况
|
||||
bufferData.resize(1, 0);
|
||||
printf("ut: bufferData resize\n");
|
||||
}
|
||||
|
||||
ret = cpuPlugin.Report(bufferData.data(), bufferData.size());
|
||||
if (ret > 0) {
|
||||
cpuData.ParseFromArray(bufferData.data(), ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GetSystemCpuTime(TestSystemStat& stat, int64_t Hz, int64_t& usageTime, int64_t& time)
|
||||
{
|
||||
usageTime = (stat.user + stat.nice + stat.system + stat.irq + stat.softirq + stat.steal) * Hz;
|
||||
time = (usageTime + stat.idle + stat.iowait) * Hz;
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: cpu plugin
|
||||
* @tc.desc: Test whether the path exists.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(CpuDataPluginTest, TestPath, TestSize.Level1)
|
||||
{
|
||||
g_path = GetFullPath(DEFAULT_TEST_PATH);
|
||||
g_testPath = g_path;
|
||||
printf("g_path:%s\n", g_path.c_str());
|
||||
EXPECT_NE("", g_path);
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
if (DEFAULT_TEST_PATH != g_path) {
|
||||
if ((access(g_path.c_str(), F_OK) != 0) && (access(DEFAULT_TEST_PATH.c_str(), F_OK) == 0)) {
|
||||
EXPECT_TRUE(CreatTestResource(DEFAULT_TEST_PATH, g_path));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: cpu plugin
|
||||
* @tc.desc: Tid list test in a specific directory.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(CpuDataPluginTest, TestTidlist, TestSize.Level1)
|
||||
{
|
||||
CpuDataPlugin cpuPlugin;
|
||||
std::string path = g_path + "/proc/1872/task/";
|
||||
printf("path:%s\n", path.c_str());
|
||||
DIR* dir = cpuPlugin.OpenDestDir(path);
|
||||
EXPECT_NE(nullptr, dir);
|
||||
|
||||
std::vector<int> tidListTmp;
|
||||
while (int32_t pid = cpuPlugin.GetValidTid(dir)) {
|
||||
tidListTmp.push_back(pid);
|
||||
sort(tidListTmp.begin(), tidListTmp.end());
|
||||
}
|
||||
EXPECT_TRUE(CheckTid(tidListTmp));
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: cpu plugin
|
||||
* @tc.desc: a part of cpu information test for specific pid.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(CpuDataPluginTest, TestPluginInfo, TestSize.Level1)
|
||||
{
|
||||
CpuDataPlugin cpuPlugin;
|
||||
CpuData cpuData;
|
||||
cpuPlugin.SetFreqPath(g_path);
|
||||
g_path += "/proc/";
|
||||
cpuPlugin.SetPath(g_path);
|
||||
EXPECT_TRUE(PluginCpuinfoStub(cpuPlugin, cpuData, 1872, false));
|
||||
|
||||
int64_t systemCpuTime = 0;
|
||||
int64_t systemBootTime = 0;
|
||||
int64_t Hz = cpuPlugin.GetUserHz();
|
||||
printf("Hz : %" PRId64 "\n", Hz);
|
||||
int64_t processCpuTime = (g_pidStat.utime + g_pidStat.stime + g_pidStat.cutime + g_pidStat.cstime) * Hz;
|
||||
GetSystemCpuTime(g_systemStat[0], Hz, systemCpuTime, systemBootTime);
|
||||
|
||||
CpuUsageInfo cpuUsageInfo = cpuData.cpu_usage_info();
|
||||
EXPECT_EQ(cpuUsageInfo.prev_process_cpu_time_ms(), 0);
|
||||
EXPECT_EQ(cpuUsageInfo.prev_system_cpu_time_ms(), 0);
|
||||
EXPECT_EQ(cpuUsageInfo.prev_system_boot_time_ms(), 0);
|
||||
EXPECT_EQ(cpuUsageInfo.process_cpu_time_ms(), processCpuTime);
|
||||
EXPECT_EQ(cpuUsageInfo.system_cpu_time_ms(), systemCpuTime);
|
||||
printf("systemCpuTime = %" PRId64 "\n", systemCpuTime);
|
||||
EXPECT_EQ(cpuUsageInfo.system_boot_time_ms(), systemBootTime);
|
||||
printf("systemBootTime = %" PRId64 "\n", systemBootTime);
|
||||
|
||||
ASSERT_EQ(cpuUsageInfo.cores_size(), 6);
|
||||
for (int i = 1; i <= CORE_NUM; i++) {
|
||||
CpuCoreUsageInfo cpuCoreUsageInfo = cpuUsageInfo.cores()[i - 1];
|
||||
GetSystemCpuTime(g_systemStat[i], Hz, systemCpuTime, systemBootTime);
|
||||
EXPECT_EQ(cpuCoreUsageInfo.cpu_core(), g_systemStat[i].core);
|
||||
EXPECT_EQ(cpuCoreUsageInfo.prev_system_cpu_time_ms(), 0);
|
||||
EXPECT_EQ(cpuCoreUsageInfo.prev_system_boot_time_ms(), 0);
|
||||
EXPECT_EQ(cpuCoreUsageInfo.system_cpu_time_ms(), systemCpuTime);
|
||||
EXPECT_EQ(cpuCoreUsageInfo.system_boot_time_ms(), systemBootTime);
|
||||
|
||||
EXPECT_EQ(cpuCoreUsageInfo.frequency().min_frequency_khz(), g_Freq[i - 1].minFreq);
|
||||
EXPECT_EQ(cpuCoreUsageInfo.frequency().max_frequency_khz(), g_Freq[i - 1].maxFreq);
|
||||
EXPECT_EQ(cpuCoreUsageInfo.frequency().cur_frequency_khz(), g_Freq[i - 1].curFreq);
|
||||
if (i == 1) { // cpu0为大核
|
||||
EXPECT_EQ(cpuCoreUsageInfo.is_little_core(), false);
|
||||
} else {
|
||||
EXPECT_EQ(cpuCoreUsageInfo.is_little_core(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: cpu plugin
|
||||
* @tc.desc: cpu information test for specific pid.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(CpuDataPluginTest, TestPlugin, TestSize.Level1)
|
||||
{
|
||||
CpuDataPlugin cpuPlugin;
|
||||
CpuData cpuData;
|
||||
g_path = g_testPath;
|
||||
cpuPlugin.SetFreqPath(g_path);
|
||||
g_path += "/proc/";
|
||||
cpuPlugin.SetPath(g_path);
|
||||
EXPECT_TRUE(PluginCpuinfoStub(cpuPlugin, cpuData, 1872, false));
|
||||
|
||||
int64_t Hz = cpuPlugin.GetUserHz();
|
||||
int64_t threadCpuTime;
|
||||
ASSERT_EQ(cpuData.thread_info_size(), 7);
|
||||
for (int i = 0; i < THREAD_NUM; i++) {
|
||||
threadCpuTime = (g_tidStat[i].stat.utime + g_tidStat[i].stat.stime +
|
||||
g_tidStat[i].stat.cutime + g_tidStat[i].stat.cstime) * Hz;
|
||||
ThreadInfo threadInfo = cpuData.thread_info()[i];
|
||||
EXPECT_EQ(threadInfo.tid(), g_tidStat[i].tid);
|
||||
EXPECT_STREQ(threadInfo.thread_name().c_str(), g_tidStat[i].name.c_str());
|
||||
EXPECT_EQ(threadInfo.thread_state(), g_tidStat[i].state);
|
||||
EXPECT_EQ(threadInfo.thread_cpu_time_ms(), threadCpuTime);
|
||||
EXPECT_EQ(threadInfo.prev_thread_cpu_time_ms(), 0);
|
||||
}
|
||||
|
||||
EXPECT_EQ(cpuPlugin.Stop(), 0);
|
||||
|
||||
// 缓冲区异常
|
||||
EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin, cpuData, 1872, true));
|
||||
EXPECT_EQ(cpuPlugin.Stop(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: cpu plugin
|
||||
* @tc.desc: cpu information test for unusual path.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(CpuDataPluginTest, TestPluginBoundary, TestSize.Level1)
|
||||
{
|
||||
CpuDataPlugin cpuPlugin;
|
||||
CpuData cpuData;
|
||||
g_path += "/proc/";
|
||||
cpuPlugin.SetPath(g_path);
|
||||
EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin, cpuData, -1, false));
|
||||
EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin, cpuData, 12345, false));
|
||||
|
||||
CpuDataPlugin cpuPlugin2;
|
||||
cpuPlugin2.SetPath("123");
|
||||
EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin2, cpuData, 1872, false));
|
||||
EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin2, cpuData, -1, false));
|
||||
EXPECT_FALSE(PluginCpuinfoStub(cpuPlugin2, cpuData, 12345, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: cpu plugin
|
||||
* @tc.desc: cpu plugin registration test.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(CpuDataPluginTest, TestPluginRegister, TestSize.Level1)
|
||||
{
|
||||
void* handle = dlopen(SO_PATH.c_str(), RTLD_LAZY);
|
||||
ASSERT_NE(handle, nullptr);
|
||||
PluginModuleStruct* cpuPlugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule");
|
||||
ASSERT_NE(cpuPlugin, nullptr);
|
||||
EXPECT_STREQ(cpuPlugin->name, "cpu-plugin");
|
||||
EXPECT_EQ(cpuPlugin->resultBufferSizeHint, BUF_SIZE);
|
||||
|
||||
// Serialize config
|
||||
CpuConfig protoConfig;
|
||||
protoConfig.set_pid(TEST_PID);
|
||||
int configLength = protoConfig.ByteSizeLong();
|
||||
ASSERT_GT(configLength, 0);
|
||||
std::vector<uint8_t> configBuffer(configLength);
|
||||
EXPECT_TRUE(protoConfig.SerializeToArray(configBuffer.data(), configLength));
|
||||
|
||||
// run plugin
|
||||
std::vector<uint8_t> dataBuffer(cpuPlugin->resultBufferSizeHint);
|
||||
EXPECT_EQ(cpuPlugin->callbacks->onPluginSessionStart(configBuffer.data(), configLength), RET_SUCC);
|
||||
ASSERT_GT(cpuPlugin->callbacks->onPluginReportResult(dataBuffer.data(), cpuPlugin->resultBufferSizeHint), 0);
|
||||
EXPECT_EQ(cpuPlugin->callbacks->onPluginSessionStop(), 0);
|
||||
|
||||
// 反序列化失败导致的start失败
|
||||
EXPECT_EQ(cpuPlugin->callbacks->onPluginSessionStart(configBuffer.data(), configLength+1), RET_FAIL);
|
||||
}
|
||||
} // namespace
|
2
device/plugins/memory_plugin/BUILD.gn
Executable file → Normal file
2
device/plugins/memory_plugin/BUILD.gn
Executable file → Normal file
@ -33,7 +33,7 @@ ohos_shared_library("memdataplugin") {
|
||||
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf_lite",
|
||||
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protoc_lib",
|
||||
"${OHOS_PROFILER_DIR}/protos/types/plugins/memory_data:memory_data_cpp",
|
||||
"//utils/native/base:utilsbase",
|
||||
"//utils/native/base:utilsecurec",
|
||||
]
|
||||
if (current_toolchain != host_toolchain) {
|
||||
defines = [ "HAVE_HILOG" ]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user