You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

544 lines
16 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
* Description: dftevent layer api define
*/
#include <stdio.h>
#include <dlfcn.h>
#include "dft_jank.h"
#include "dft_ebai.h"
#include "dft_event_handle.h"
#include "securec.h"
#include "dft_event.h"
#ifdef ANDROID
#include <android/log.h>
#endif
#undef LOG_TAG
#define LOG_TAG "DFTEVENT"
#ifdef ANDROID
#define DFTEVENT_LOGE(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, \
(const char *)"%s[%d]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define DFTEVENT_LOGW(fmt, ...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, \
(const char *)"%s[%d]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define DFTEVENT_LOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, \
(const char *)"%s[%d]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define DFTEVENT_LOGD(fmt, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, \
(const char *)"%s[%d]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define DFTEVENT_LOGV(fmt, ...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, \
(const char *)"%s[%d]:" fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define DFTEVENT_LOGE(fmt, ...) \
printf((const char *)"%s: %s[%d]:" fmt "\n", LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define DFTEVENT_LOGW(fmt, ...) \
printf((const char *)"%s: %s[%d]:" fmt "\n", LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define DFTEVENT_LOGI(fmt, ...) \
printf((const char *)"%s: %s[%d]:" fmt "\n", LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define DFTEVENT_LOGD(fmt, ...) \
printf((const char *)"%s: %s[%d]:" fmt "\n", LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define DFTEVENT_LOGV(fmt, ...) \
printf((const char *)"%s: %s[%d]:" fmt "\n", LOG_TAG, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#endif
#define LIB_DFT_EVENT_IMPL_PATH "libdftevent_impl.so"
#define PHONY_HANDLE 0xfffffff0
const unsigned int LOG_BUF_SIZE = 1024;
typedef int (*dft_event_create_fn)(int, void **);
typedef void (*dft_event_destroy_fn)(void *);
typedef int (*dft_event_set_time_fn)(void *, long long);
typedef int (*dft_event_put_integral_fn)(void *, const char *, long);
typedef int (*dft_event_put_float_fn)(void *, const char *, float);
typedef int (*dft_event_put_string_fn)(void *, const char *, const char *);
typedef int (*dft_event_put_event_fn)(void *, const char *, void *);
typedef int (*dft_event_put_event_array_fn)(void *, const char *, void *, int);
typedef int (*dft_event_add_file_path_fn)(void *, const char *);
typedef int (*dft_event_report_fn)(void *);
typedef int (*dft_event_print_fn)(const char *);
// the jank and ebai api pointer type.
typedef int (*hwlog_jank_buf_write_fn)(short prio, short tag, const char *msg);
typedef int (*hwlog_jank_chgtmbuf_write_fn)
(short prio, short tag, unsigned long ut, unsigned long rt, const char *msg);
typedef int (*dft_ebai_write_kernel_printf_fn)(short prio, const char *tag, const char *msg);
static dft_event_create_fn g_dft_event_create = NULL;
static dft_event_destroy_fn g_dft_event_destroy = NULL;
static dft_event_set_time_fn g_dft_event_set_time = NULL;
static dft_event_put_integral_fn g_dft_event_put_integral = NULL;
static dft_event_put_float_fn g_dft_event_put_float = NULL;
static dft_event_put_string_fn g_dft_event_put_string = NULL;
static dft_event_put_event_fn g_dft_event_put_event = NULL;
static dft_event_put_event_array_fn g_dft_event_put_event_array = NULL;
static dft_event_add_file_path_fn g_dft_event_add_file_path = NULL;
static dft_event_report_fn g_dft_event_report = NULL;
static dft_event_print_fn g_dft_event_print = NULL;
// the jank and ebai api pointer.
static hwlog_jank_buf_write_fn g_hwlog_jank_buf_write = NULL;
static hwlog_jank_chgtmbuf_write_fn g_hwlog_jank_chgtmbuf_write = NULL;
static dft_ebai_write_kernel_printf_fn g_dft_ebai_write_kernel_printf = NULL;
static void *g_lib = NULL;
static int check_lib(void)
{
if (g_lib == NULL) {
g_lib = dlopen(LIB_DFT_EVENT_IMPL_PATH, RTLD_LAZY);
if (g_lib == NULL) {
DFTEVENT_LOGE("dlopen %s failed. error:%s.", LIB_DFT_EVENT_IMPL_PATH, dlerror());
return FAILURE;
}
}
return SUCCESS;
}
int dft_event_create(int id, unsigned int *handle)
{
unsigned int handle_t;
void *event = NULL;
int ret;
if (handle == NULL) {
DFTEVENT_LOGE("invalid parameter.");
return FAILURE;
}
/* determine whether support dft */
if (check_lib() != SUCCESS) {
*handle = PHONY_HANDLE;
return SUCCESS; /* not support dft */
}
if (g_dft_event_create == NULL) {
g_dft_event_create = dlsym(g_lib, "dft_event_create_impl");
if (g_dft_event_create == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
ret = g_dft_event_create(id, &event);
if ((ret != SUCCESS) || (event == NULL)) {
DFTEVENT_LOGE("event create failed.");
return FAILURE;
}
handle_t = event_make_handle(event);
if (handle_t == INVALID_HANDLE) {
DFTEVENT_LOGE("make handle failed.");
return FAILURE;
}
DFTEVENT_LOGD("create succeed.");
*handle = handle_t;
return SUCCESS;
}
void dft_event_destroy(unsigned int handle)
{
void *event = NULL;
if (handle == INVALID_HANDLE) {
DFTEVENT_LOGE("invalid parameter.");
return;
}
/* determine whether support dft */
if (check_lib() != SUCCESS) {
return; /* not support dft */
}
if (g_dft_event_destroy == NULL) {
g_dft_event_destroy = dlsym(g_lib, "dft_event_destroy_impl");
if (g_dft_event_destroy == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return;
}
}
event = event_get_event_by_handle(handle);
if (event == NULL) {
DFTEVENT_LOGE("get event failed.");
return;
}
g_dft_event_destroy(event);
DFTEVENT_LOGD("destroy succeed.");
event_free_handle(handle);
}
int dft_event_set_time(unsigned int handle, long long seconds)
{
void *event = NULL;
if ((handle == INVALID_HANDLE) || (seconds == 0)) {
DFTEVENT_LOGE("invalid parameter.");
return FAILURE;
}
/* determine whether support dft */
if (check_lib() != SUCCESS) {
return SUCCESS; /* not support dft */
}
if (g_dft_event_set_time == NULL) {
g_dft_event_set_time = dlsym(g_lib, "dft_event_set_time_impl");
if (g_dft_event_set_time == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
event = event_get_event_by_handle(handle);
if (event == NULL) {
DFTEVENT_LOGE("get event failed.");
return FAILURE;
}
return g_dft_event_set_time(event, seconds);
}
int dft_event_put_integral(unsigned int handle, const char *key, long value)
{
void *event = NULL;
if ((handle == INVALID_HANDLE) || (key == NULL)) {
DFTEVENT_LOGE("invalid parameter.");
return FAILURE;
}
/* determine whether support dft */
if (check_lib() != SUCCESS) {
return SUCCESS; /* not support dft */
}
if (g_dft_event_put_integral == NULL) {
g_dft_event_put_integral = dlsym(g_lib, "dft_event_put_integral_impl");
if (g_dft_event_put_integral == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
event = event_get_event_by_handle(handle);
if (event == NULL) {
DFTEVENT_LOGE("get event failed.");
return FAILURE;
}
return g_dft_event_put_integral(event, key, value);
}
int dft_event_put_float(unsigned int handle, const char *key, float value)
{
void *event = NULL;
if ((handle == INVALID_HANDLE) || (key == NULL)) {
DFTEVENT_LOGE("invalid parameter.");
return FAILURE;
}
/* determine whether support dft */
if (check_lib() != SUCCESS) {
return SUCCESS; /* not support dft */
}
if (g_dft_event_put_float == NULL) {
g_dft_event_put_float = dlsym(g_lib, "dft_event_put_float_impl");
if (g_dft_event_put_float == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
event = event_get_event_by_handle(handle);
if (event == NULL) {
DFTEVENT_LOGE("get event failed.");
return FAILURE;
}
return g_dft_event_put_float(event, key, value);
}
int dft_event_put_string(unsigned int handle, const char *key, const char *value)
{
void *event = NULL;
if ((handle == INVALID_HANDLE) || (key == NULL) || (value == NULL)) {
DFTEVENT_LOGE("invalid parameter.");
return FAILURE;
}
/* determine whether support dft */
if (check_lib() != SUCCESS) {
return SUCCESS; /* not support dft */
}
if (g_dft_event_put_string == NULL) {
g_dft_event_put_string = dlsym(g_lib, "dft_event_put_string_impl");
if (g_dft_event_put_string == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
event = event_get_event_by_handle(handle);
if (event == NULL) {
DFTEVENT_LOGE("get event failed.");
return FAILURE;
}
return g_dft_event_put_string(event, key, value);
}
int dft_event_put_event(unsigned int handle, const char *key, unsigned int value)
{
void *event = NULL;
void *sub_event = NULL;
if ((handle == INVALID_HANDLE) || (key == NULL) || (value == INVALID_HANDLE)) {
DFTEVENT_LOGE("invalid parameter.");
return FAILURE;
}
/* determine whether support dft */
if (check_lib() != SUCCESS) {
return SUCCESS; /* not support dft */
}
if (g_dft_event_put_event == NULL) {
g_dft_event_put_event = dlsym(g_lib, "dft_event_put_event_impl");
if (g_dft_event_put_event == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
event = event_get_event_by_handle(handle);
if (event == NULL) {
DFTEVENT_LOGE("get event failed.");
return FAILURE;
}
sub_event = event_get_event_by_handle(value);
if (sub_event == NULL) {
DFTEVENT_LOGE("get sub event failed.");
return FAILURE;
}
return g_dft_event_put_event(event, key, sub_event);
}
int dft_event_put_event_array(unsigned int handle, const char *key, const unsigned int *value, int length)
{
void *event = NULL;
void *sub_event[EVENT_MAX_HANDLE_NUM] = {};
if ((handle == INVALID_HANDLE) || (key == NULL) || (value == NULL)) {
DFTEVENT_LOGE("invalid parameter.");
return FAILURE;
}
/* determine whether support dft */
if (check_lib() != SUCCESS) {
return SUCCESS; /* not support dft */
}
if (g_dft_event_put_event_array == NULL) {
g_dft_event_put_event_array = dlsym(g_lib, "dft_event_put_event_array_impl");
if (g_dft_event_put_event_array == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
event = event_get_event_by_handle(handle);
if (event == NULL) {
DFTEVENT_LOGE("get event failed.");
return FAILURE;
}
for (int i = 0; i < length; i++) {
sub_event[i] = event_get_event_by_handle(value[i]);
if (sub_event[i] == NULL) {
DFTEVENT_LOGE("get sub event failed.");
return FAILURE;
}
}
return g_dft_event_put_event_array(event, key, sub_event, length);
}
int dft_event_add_file_path(unsigned int handle, const char *path)
{
void *event = NULL;
if ((handle == INVALID_HANDLE) || (path == NULL)) {
DFTEVENT_LOGE("invalid parameter.");
return FAILURE;
}
/* determine whether support dft */
if (check_lib() != SUCCESS) {
return SUCCESS; /* not support dft */
}
if (g_dft_event_add_file_path == NULL) {
g_dft_event_add_file_path = dlsym(g_lib, "dft_event_add_file_path_impl");
if (g_dft_event_add_file_path == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
event = event_get_event_by_handle(handle);
if (event == NULL) {
DFTEVENT_LOGE("get event failed.");
return FAILURE;
}
return g_dft_event_add_file_path(event, path);
}
int dft_event_report(unsigned int handle)
{
void *event = NULL;
if (handle == INVALID_HANDLE) {
DFTEVENT_LOGE("invalid parameter.");
return FAILURE;
}
/* determine whether support dft */
if (check_lib() != SUCCESS) {
return SUCCESS; /* not support dft */
}
if (g_dft_event_report == NULL) {
g_dft_event_report = dlsym(g_lib, "dft_event_report_impl");
if (g_dft_event_report == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
event = event_get_event_by_handle(handle);
if (event == NULL) {
DFTEVENT_LOGE("get event failed.");
return FAILURE;
}
int ret = g_dft_event_report(event);
DFTEVENT_LOGD("report, ret:%d.", ret);
return ret;
}
int dft_jank_print(short prio, short tag, const char *fmt, ...)
{
va_list ap;
char buf[LOG_BUF_SIZE];
va_start(ap, fmt);
if (vsnprintf_s(buf, LOG_BUF_SIZE, LOG_BUF_SIZE - 1, fmt, ap) < 0) {
fprintf(stderr, "JLOG message is not integrated\n");
}
va_end(ap);
if (check_lib() != SUCCESS) {
return SUCCESS;
}
if (g_hwlog_jank_buf_write == NULL) {
g_hwlog_jank_buf_write = dlsym(g_lib, "hwlog_jank_buf_write_impl");
if (g_hwlog_jank_buf_write == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
int ret = g_hwlog_jank_buf_write(prio, tag, buf);
DFTEVENT_LOGD("ret: %d.", ret);
return ret;
}
int dft_jank_chgtm_print(short prio, short tag, unsigned long ut, unsigned long rt, const char *fmt, ...)
{
va_list ap;
char buf[LOG_BUF_SIZE];
va_start(ap, fmt);
if (vsnprintf_s(buf, LOG_BUF_SIZE, LOG_BUF_SIZE - 1, fmt, ap) < 0) {
fprintf(stderr, "JLOGD_CHGTM message is not integrated\n");
}
va_end(ap);
if (check_lib() != SUCCESS) {
return SUCCESS;
}
if (g_hwlog_jank_chgtmbuf_write == NULL) {
g_hwlog_jank_chgtmbuf_write = dlsym(g_lib, "hwlog_jank_chgtmbuf_write_impl");
if (g_hwlog_jank_chgtmbuf_write == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
int ret = g_hwlog_jank_chgtmbuf_write(prio, tag, ut, rt, buf);
DFTEVENT_LOGD("ret: %d.", ret);
return ret;
}
int dft_ebai_print(short prio, const char *tag, const char *fmt, ...)
{
va_list ap;
char buf[LOG_BUF_SIZE];
va_start(ap, fmt);
if (vsnprintf_s(buf, LOG_BUF_SIZE, LOG_BUF_SIZE - 1, fmt, ap) < 0) {
fprintf(stderr, "hwlog message prepared to write to kernel is not integrated\n");
}
va_end(ap);
if (check_lib() != SUCCESS) {
return SUCCESS;
}
if (g_dft_ebai_write_kernel_printf == NULL) {
g_dft_ebai_write_kernel_printf = dlsym(g_lib, "dft_ebai_write_kernel_printf_impl");
if (g_dft_ebai_write_kernel_printf == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
int ret = g_dft_ebai_write_kernel_printf(prio, tag, buf);
DFTEVENT_LOGE("ret: %d.", ret);
return ret;
}
int dft_event_print(const char *msg)
{
if (check_lib() != SUCCESS) {
return SUCCESS;
}
if (g_dft_event_print == NULL) {
g_dft_event_print = dlsym(g_lib, "dft_event_print_impl");
if (g_dft_event_print == NULL) {
DFTEVENT_LOGE("dlsym failed: %s.", dlerror());
return FAILURE;
}
}
int ret = g_dft_event_print(msg);
DFTEVENT_LOGE("ret: %d.", ret);
return ret;
}