From cbaaadba5ff71b5f90e803be814951bc6acb7e46 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 8 Aug 2022 05:02:54 +0900 Subject: [PATCH 01/16] lib: resource-monitor: Fix pass_resource_monitor_get_resource_timestamp issue Change-Id: I6730f5451b335dd8a4759d528989d846bcf686e0 Signed-off-by: Chanwoo Choi --- lib/resource-monitor/resource-monitor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/resource-monitor/resource-monitor.c b/lib/resource-monitor/resource-monitor.c index c21bdb9..594a8ed 100644 --- a/lib/resource-monitor/resource-monitor.c +++ b/lib/resource-monitor/resource-monitor.c @@ -964,10 +964,10 @@ int pass_resource_monitor_get_resource_timestamp(int id, int res_id, int64_t *st } buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%"PRId64"$%"PRId64"$%d", &response_req, start, end, &ret) < 3) + if (sscanf(buffer, "%d$%"PRId64"$%"PRId64"$%d", &response_req, start, end, &ret) < 4) return -EINVAL; - if (response_req != REQUEST_GET_VALUE_INT64) { + if (response_req != REQUEST_GET_RESOURCE_TS) { _E("[libpass] wrong response"); return -EINVAL; } -- 2.7.4 From 223555aa02867b7865436e6d3b2045bdc0fa5332 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 8 Aug 2022 05:05:12 +0900 Subject: [PATCH 02/16] lib: resource-monitor: Fix wrong data type of pass_resource_monitor_get_value_uint uint need to use '%u' instead of '%d'. Fix wrong data type format. Change-Id: Ibec1b362cca3b1ad649ee1aedbf08368f1b1db24 Signed-off-by: Chanwoo Choi --- lib/resource-monitor/resource-monitor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resource-monitor/resource-monitor.c b/lib/resource-monitor/resource-monitor.c index 594a8ed..5951465 100644 --- a/lib/resource-monitor/resource-monitor.c +++ b/lib/resource-monitor/resource-monitor.c @@ -614,7 +614,7 @@ int pass_resource_monitor_get_value_uint(int id, int resource_id, u_int64_t attr } buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%d$%d", &response_req, value, &ret) < 3) + if (sscanf(buffer, "%d$%u$%d", &response_req, value, &ret) < 3) return -EINVAL; if (response_req != REQUEST_GET_VALUE_UINT) { -- 2.7.4 From 4102b9b51776276e1e456f09a33aa50499d221ea Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 20 Jul 2022 17:52:13 +0900 Subject: [PATCH 03/16] lib: resource-monitor: Extract common function for readability and remove duplicate code Almost resource-monitor functions are composed with the following steps to communicate with resource-monitor daemon. It means that there are the many similiar code to support resource-monitor feature. 1. send request 2. recv response 3. parse data from response 4. validate the data In order to reduece the duplicate code and improve the readability, extract the common functions as handle_request with struct request_data. Change-Id: I413e3dd157093507d099892b0d3123bcf0641f4b Signed-off-by: Chanwoo Choi --- include/util/request.h | 24 ++ lib/resource-monitor/resource-monitor.c | 687 +++++++++++++------------------- 2 files changed, 311 insertions(+), 400 deletions(-) diff --git a/include/util/request.h b/include/util/request.h index c640830..6f7bfa7 100644 --- a/include/util/request.h +++ b/include/util/request.h @@ -49,4 +49,28 @@ enum { REQUEST_MAX, }; +static const char request_name[][128] = { + "REQUEST_CREATE_RESOURCE", + "REQUEST_DELETE_RESOURCE", + "REQUEST_UPDATE_RESOURCE", + "REQUEST_UPDATE_RESOURCE_ALL", + "REQUEST_GET_RESOURCE_COUNT", + "REQUEST_SET_RESOURCE_CTRL", + "REQUEST_SET_RESOURCE_ATTR", + "REQUEST_UNSET_RESOURCE_ATTR", + "REQUEST_IS_RESOURCE_ATTR_SUPPORTED", + "REQUEST_GET_RESOURCE_JSON", + "REQUEST_GET_VALUE_JSON", + "REQUEST_GET_VALUE_INT", + "REQUEST_GET_VALUE_INT64", + "REQUEST_GET_VALUE_UINT", + "REQUEST_GET_VALUE_UINT64", + "REQUEST_GET_VALUE_DOUBLE", + "REQUEST_GET_VALUE_STRING", + "REQUEST_GET_VALUE_ARRAY", + "REQUEST_GET_RESOURCE_TS", + "REQUEST_GET_RESOURCE_LIST_JSON", + "REQUEST_MAX", +}; + #endif /* __REQUEST_H__ */ diff --git a/lib/resource-monitor/resource-monitor.c b/lib/resource-monitor/resource-monitor.c index 5951465..3d6a1a9 100644 --- a/lib/resource-monitor/resource-monitor.c +++ b/lib/resource-monitor/resource-monitor.c @@ -39,8 +39,6 @@ #define REQUEST_SERVER_IP "127.0.0.1" #define REQUEST_SERVER_PORT 10001 -extern char *program_invocation_name; - #ifndef EXPORT #define EXPORT __attribute__ ((visibility("default"))) #endif @@ -93,37 +91,172 @@ static struct pass_resource_monitor_client *find_client_by_id(int id) return NULL; } -static int handle_resource_attr(int request, int id, int resource_id, u_int64_t attr_mask) +struct request_data { + int request; + int client_id; + int resource_id; + int resource_type; + u_int64_t ctrl_id; + int ctrl_value; + u_int64_t attr_mask; + u_int64_t attr_id; + + int32_t value_int32; + u_int32_t value_uint32; + int64_t value_int64; + u_int64_t value_uint64; + double value_double; + char value_string[BUFF_MAX]; + int64_t ts_start; + int64_t ts_end; +}; + +static inline int handle_request(struct request_data *data) { char buffer[GENERIC_BUFF_MAX + 1]; int buffer_len; int response_req; + int response_ret; int ret; - buffer_len = sprintf(buffer, "%d$%d$%"PRIu64, - request, resource_id, attr_mask); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); + if (!data) + return -EINVAL; + + /* Make buffer with struct request_data according to request */ + switch (data->request) { + case REQUEST_UPDATE_RESOURCE_ALL: + buffer_len = sprintf(buffer, "%d", data->request); + break; + case REQUEST_GET_VALUE_INT: + case REQUEST_GET_VALUE_INT64: + case REQUEST_GET_VALUE_UINT: + case REQUEST_GET_VALUE_UINT64: + case REQUEST_GET_VALUE_DOUBLE: + case REQUEST_GET_VALUE_STRING: + case REQUEST_IS_RESOURCE_ATTR_SUPPORTED: + buffer_len = sprintf(buffer, "%d$%d$%"PRIu64, + data->request, data->resource_id, data->attr_id); + break; + case REQUEST_UPDATE_RESOURCE: + case REQUEST_DELETE_RESOURCE: + buffer_len = sprintf(buffer, "%d$%d", + data->request, data->resource_id); + break; + case REQUEST_CREATE_RESOURCE: + case REQUEST_GET_RESOURCE_COUNT: + buffer_len = sprintf(buffer, "%d$%d", + data->request, data->resource_type); + break; + case REQUEST_SET_RESOURCE_CTRL: + buffer_len = sprintf(buffer, "%d$%d$%"PRIu64"$%d", + data->request, data->resource_id, + data->ctrl_id, data->ctrl_value); + break; + case REQUEST_SET_RESOURCE_ATTR: + case REQUEST_UNSET_RESOURCE_ATTR: + buffer_len = sprintf(buffer, "%d$%d$%"PRIu64, + data->request, data->resource_id, data->attr_mask); + break; + case REQUEST_GET_RESOURCE_TS: + buffer_len = sprintf(buffer, "%d$%d", + data->request, data->resource_id); + break; + default: + _E("[libpass] Unknown request type, client(%d) | request(%d)", + data->client_id, data->request); + return -EINVAL; + } + + /* Send request to resource-moniotor */ + if (send(data->client_id, buffer, buffer_len, 0) < 0) { + _E("[libpass] failed to send request, client(%d) | request(%35s) | res,id(%d)type(%d) | ctrl,id(%"PRId64")val(%d) ", + data->client_id, request_name[data->request], + data->resource_id, data->resource_type, + data->ctrl_id, data->ctrl_value); return -EIO; } - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); + /* Receive response from resource-moniotor */ + buffer_len = recv(data->client_id, buffer, GENERIC_BUFF_MAX, 0); if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); + _E("[libpass] failed to receive response, client(%d) | request(%35s) | res,id(%d)type(%d) | ctrl,id(%"PRId64")val(%d) ", + data->client_id, request_name[data->request], + data->resource_id, data->resource_type, + data->ctrl_id, data->ctrl_value); return -EIO; } - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%d", &response_req, &ret) < 2) - return -EINVAL; - if (response_req != request) { - _E("[libpass] wrong response"); + /* Parse received response from resource-monitor */ + ret = 0; + switch (data->request) { + case REQUEST_GET_VALUE_INT: + if (sscanf(buffer, "%d$%d$%d", &response_req, + &data->value_int32, &response_ret) < 3) + ret = EINVAL; + break; + case REQUEST_GET_VALUE_UINT: + if (sscanf(buffer, "%d$%u$%d", &response_req, + &data->value_uint32, &response_ret) < 3) + ret = -EINVAL; + break; + case REQUEST_GET_VALUE_INT64: + if (sscanf(buffer, "%d$%"PRId64"$%d", &response_req, + &data->value_int64, &response_ret) < 3) + return -EINVAL; + break; + case REQUEST_GET_VALUE_UINT64: + if (sscanf(buffer, "%d$%"PRIu64"$%d", &response_req, + &data->value_uint64, &response_ret) < 3) + ret = -EINVAL; + break; + case REQUEST_GET_VALUE_DOUBLE: + if (sscanf(buffer, "%d$%lf$%d", &response_req, + &data->value_double, &response_ret) < 3) + ret = -EINVAL; + break; + case REQUEST_GET_VALUE_STRING: + if (sscanf(buffer, "%d$%[^$]$%d", &response_req, + data->value_string, &response_ret) < 3) + ret = -EINVAL; + break; + case REQUEST_GET_RESOURCE_TS: + if (sscanf(buffer, "%d$%"PRId64"$%"PRId64"$%d", &response_req, + &data->ts_start, &data->ts_end, &response_ret) < 4) + ret =-EINVAL; + break; + default: + if (sscanf(buffer, "%d$%d", &response_req, &response_ret) < 2) + ret = -EINVAL; + break; + } + + if (ret < 0) { + _E("[libpass] failed to receive response, client(%d) | request(%35s) | res,id(%d)type(%d) | ctrl,id(%"PRId64")val(%d) ", + data->client_id, request_name[data->request], + data->resource_id, data->resource_type, + data->ctrl_id, data->ctrl_value); + return ret; + } + + if (response_ret < 0) { + _E("[libpass] failed to receive response, client(%d) | request(%35s) | res,id(%d)type(%d) | ctrl,id(%"PRId64")val(%d) ", + data->client_id, request_name[data->request], + data->resource_id, data->resource_type, + data->ctrl_id, data->ctrl_value); + return response_ret; + } + + /* Validate response request from resource-monitor */ + if (response_req != data->request) { + _E("[libpass] failed to receive response, client(%d) | request(%35s) | res,id(%d)type(%d) | ctrl,id(%"PRId64")val(%d) ", + data->client_id, request_name[data->request], + data->resource_id, data->resource_type, + data->ctrl_id, data->ctrl_value); return -EINVAL; } - return ret; + return response_ret; } EXPORT @@ -193,253 +326,117 @@ int pass_resource_monitor_exit(int id) EXPORT int pass_resource_monitor_get_resource_count(int id, int resource_type) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; - int ret; + struct request_data request = { + .request = REQUEST_GET_RESOURCE_COUNT, + .client_id = id, + .resource_type = resource_type, + }; - buffer_len = sprintf(buffer, "%d$%d", - REQUEST_GET_RESOURCE_COUNT, resource_type); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); - return -EIO; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%d", &response_req, &ret) < 2) - return -EINVAL; - - if (response_req != REQUEST_GET_RESOURCE_COUNT) { - _E("[libpass] wrong response"); - return -EINVAL; - } - - return ret; + return handle_request(&request); } EXPORT int pass_resource_monitor_create_resource(int id, int resource_type) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; - int ret; + struct request_data request = { + .request = REQUEST_CREATE_RESOURCE, + .client_id = id, + .resource_type = resource_type, + }; - buffer_len = sprintf(buffer, "%d$%d", REQUEST_CREATE_RESOURCE, resource_type); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer for create resource"); - return -EIO; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%d", &response_req, &ret) < 2) - return -EINVAL; - - if (response_req != REQUEST_CREATE_RESOURCE) { - _E("wrong response"); - return -EINVAL; - } - - return ret; + return handle_request(&request); } EXPORT int pass_resource_monitor_delete_resource(int id, int resource_id) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; - int ret; - - buffer_len = sprintf(buffer, "%d$%d", REQUEST_DELETE_RESOURCE, resource_id); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer for create resource"); - return -EIO; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%d", &response_req, &ret) < 2) - return -EINVAL; + struct request_data request = { + .request = REQUEST_DELETE_RESOURCE, + .client_id = id, + .resource_id = resource_id, + }; - if (response_req != REQUEST_DELETE_RESOURCE) { - _E("wrong response"); - return -EINVAL; - } - - return ret; + return handle_request(&request); } EXPORT int pass_resource_monitor_set_resource_ctrl(int id, int resource_id, u_int64_t ctrl_id, int value) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; - int ret; - - buffer_len = sprintf(buffer, "%d$%d$%"PRIu64"$%d", - REQUEST_SET_RESOURCE_CTRL, resource_id, ctrl_id, value); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); - return -EIO; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%d", &response_req, &ret) < 2) - return -EINVAL; + struct request_data request = { + .request = REQUEST_SET_RESOURCE_CTRL, + .client_id = id, + .resource_id = resource_id, + .ctrl_id = ctrl_id, + .ctrl_value = value, + }; - if (response_req != REQUEST_SET_RESOURCE_CTRL) { - _E("[libpass] wrong response"); - return -EINVAL; - } - - return ret; + return handle_request(&request); } EXPORT int pass_resource_monitor_set_resource_attr(int id, int resource_id, u_int64_t attr_mask) { - return handle_resource_attr(REQUEST_SET_RESOURCE_ATTR, id, resource_id, attr_mask); + struct request_data request = { + .request = REQUEST_SET_RESOURCE_ATTR, + .client_id = id, + .resource_id = resource_id, + .attr_mask = attr_mask, + }; + + return handle_request(&request); } EXPORT int pass_resource_monitor_unset_resource_attr(int id, int resource_id, u_int64_t attr_mask) { - return handle_resource_attr(REQUEST_UNSET_RESOURCE_ATTR, id, resource_id, attr_mask); + struct request_data request = { + .request = REQUEST_UNSET_RESOURCE_ATTR, + .client_id = id, + .resource_id = resource_id, + .attr_mask = attr_mask, + }; + + return handle_request(&request); } EXPORT bool pass_resource_monitor_is_resource_attr_supported(int id, int resource_id, u_int64_t attr_id) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; + struct request_data request = { + .request = REQUEST_IS_RESOURCE_ATTR_SUPPORTED, + .client_id = id, + .resource_id = resource_id, + .attr_id = attr_id, + }; int ret; - buffer_len = sprintf(buffer, "%d$%d$%"PRIu64"", - REQUEST_IS_RESOURCE_ATTR_SUPPORTED, resource_id, attr_id); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); - return false; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return false; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%d", &response_req, &ret) < 2) - return false; - - if (ret < 0) - return false; - - if (response_req != REQUEST_IS_RESOURCE_ATTR_SUPPORTED) { - _E("[libpass] wrong response"); - return false; - } - - return (bool)ret; + ret = handle_request(&request); + return (ret < 0) ? false : (bool)ret; } EXPORT int pass_resource_monitor_update(int id) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; - int ret; - - buffer_len = sprintf(buffer, "%d", REQUEST_UPDATE_RESOURCE_ALL); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); - return -EIO; - } + struct request_data request = { + .request = REQUEST_UPDATE_RESOURCE_ALL, + .client_id = id, + }; - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%d", &response_req, &ret) < 2) - return -EINVAL; - - if (response_req != REQUEST_UPDATE_RESOURCE_ALL) { - _E("[libpass] wrong response"); - return -EINVAL; - } - - return ret; + return handle_request(&request); } EXPORT int pass_resource_monitor_update_resource(int id, int resource_id) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; - int ret; + struct request_data request = { + .request = REQUEST_UPDATE_RESOURCE, + .client_id = id, + .resource_id = resource_id, + }; - buffer_len = sprintf(buffer, "%d$%d", REQUEST_UPDATE_RESOURCE, resource_id); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); - return -EIO; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%d", &response_req, &ret) < 2) - return -EINVAL; - - if (response_req != REQUEST_UPDATE_RESOURCE) { - _E("[libpass] wrong response"); - return -EINVAL; - } - - return ret; + return handle_request(&request); } - static int pass_resource_monitor_get_json(int id, char *json_string, int request_type, ...) { int buffer_len, response_req, ret, resource_id; @@ -526,211 +523,115 @@ int pass_resource_monitor_get_resource_list_json(int id, char *json_string) EXPORT int pass_resource_monitor_get_value_int(int id, int resource_id, u_int64_t attr_id, int32_t *value) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; + struct request_data request = { + .request = REQUEST_GET_VALUE_INT, + .client_id = id, + .resource_id = resource_id, + .attr_id = attr_id, + }; int ret; - buffer_len = sprintf(buffer, "%d$%d$%"PRIu64, - REQUEST_GET_VALUE_INT, resource_id, attr_id); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); - return -EIO; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%d$%d", &response_req, value, &ret) < 3) - return -EINVAL; - - if (response_req != REQUEST_GET_VALUE_INT) { - _E("[libpass] wrong response"); - return -EINVAL; - } + ret = handle_request(&request); + if (ret < 0) + return ret; - return ret; + *value = request.value_int32; + return 0; } EXPORT int pass_resource_monitor_get_value_int64(int id, int resource_id, u_int64_t attr_id, int64_t *value) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; + struct request_data request = { + .request = REQUEST_GET_VALUE_INT64, + .client_id = id, + .resource_id = resource_id, + .attr_id = attr_id, + }; int ret; - buffer_len = sprintf(buffer, "%d$%d$%"PRIu64, - REQUEST_GET_VALUE_INT64, resource_id, attr_id); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); - return -EIO; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%"PRId64"$%d", &response_req, value, &ret) < 3) - return -EINVAL; - - if (response_req != REQUEST_GET_VALUE_INT64) { - _E("[libpass] wrong response"); - return -EINVAL; - } + ret = handle_request(&request); + if (ret < 0) + return ret; - return ret; + *value = request.value_int64; + return 0; } EXPORT int pass_resource_monitor_get_value_uint(int id, int resource_id, u_int64_t attr_id, u_int32_t *value) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; + struct request_data request = { + .request = REQUEST_GET_VALUE_UINT, + .client_id = id, + .resource_id = resource_id, + .attr_id = attr_id, + }; int ret; - buffer_len = sprintf(buffer, "%d$%d$%"PRIu64, - REQUEST_GET_VALUE_UINT, resource_id, attr_id); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); - return -EIO; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%u$%d", &response_req, value, &ret) < 3) - return -EINVAL; - - if (response_req != REQUEST_GET_VALUE_UINT) { - _E("[libpass] wrong response"); - return -EINVAL; - } + ret = handle_request(&request); + if (ret < 0) + return ret; - return ret; + *value = request.value_uint32; + return 0; } EXPORT int pass_resource_monitor_get_value_uint64(int id, int resource_id, u_int64_t attr_id, u_int64_t *value) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; + struct request_data request = { + .request = REQUEST_GET_VALUE_UINT64, + .client_id = id, + .resource_id = resource_id, + .attr_id = attr_id, + }; int ret; - buffer_len = sprintf(buffer, "%d$%d$%"PRIu64, - REQUEST_GET_VALUE_UINT64, resource_id, attr_id); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); - return -EIO; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%"PRIu64"$%d", &response_req, value, &ret) < 3) - return -EINVAL; - - if (response_req != REQUEST_GET_VALUE_UINT64) { - _E("[libpass] wrong response"); - return -EINVAL; - } + ret = handle_request(&request); + if (ret < 0) + return ret; - return ret; + *value = request.value_uint64; + return 0; } EXPORT int pass_resource_monitor_get_value_double(int id, int resource_id, u_int64_t attr_id, double *value) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; + struct request_data request = { + .request = REQUEST_GET_VALUE_DOUBLE, + .client_id = id, + .resource_id = resource_id, + .attr_id = attr_id, + }; int ret; - buffer_len = sprintf(buffer, "%d$%d$%"PRIu64, - REQUEST_GET_VALUE_DOUBLE, resource_id, attr_id); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); - return -EIO; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%lf$%d", &response_req, value, &ret) < 3) - return -EINVAL; - - if (response_req != REQUEST_GET_VALUE_DOUBLE) { - _E("[libpass] wrong response"); - return -EINVAL; - } + ret = handle_request(&request); + if (ret < 0) + return ret; - return ret; + *value = request.value_double; + return 0; } EXPORT int pass_resource_monitor_get_value_string(int id, int resource_id, u_int64_t attr_id, char **value) { - char buffer[GENERIC_BUFF_MAX + 1]; - char value_string[BUFF_MAX]; - int buffer_len; - int response_req; + struct request_data request = { + .request = REQUEST_GET_VALUE_STRING, + .client_id = id, + .resource_id = resource_id, + .attr_id = attr_id, + }; int ret; - if (!value) - return -EINVAL; - - buffer_len = sprintf(buffer, "%d$%d$%"PRIu64, - REQUEST_GET_VALUE_STRING, resource_id, attr_id); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); - return -EIO; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - - buffer[buffer_len] = '\0'; - if (sscanf(buffer, "%d$%[^$]$%d", &response_req, value_string, &ret) < 3) - return -EINVAL; - - if (response_req != REQUEST_GET_VALUE_STRING) { - _E("[libpass] wrong response"); - return -EINVAL; - } - - *value = g_strdup(value_string); + ret = handle_request(&request); + if (ret < 0) + return ret; - return ret; + *value = g_strdup(request.value_string); + return 0; } static int @@ -945,32 +846,18 @@ int pass_resource_monitor_get_array_string(int id, int res_id, u_int64_t attr_id int pass_resource_monitor_get_resource_timestamp(int id, int res_id, int64_t *start, int64_t *end) { - char buffer[GENERIC_BUFF_MAX + 1]; - int buffer_len; - int response_req; + struct request_data request = { + .request = REQUEST_GET_RESOURCE_TS, + .client_id = id, + .resource_id = res_id, + }; int ret; - buffer_len = sprintf(buffer, "%d$%d", REQUEST_GET_RESOURCE_TS, res_id); - if (send(id, buffer, buffer_len, 0) < 0) { - _E("[libpass] error occurred while sending buffer"); - return -EIO; - } - - /* wait for response */ - buffer_len = recv(id, buffer, GENERIC_BUFF_MAX, 0); - if (buffer_len <= 0) { - _E("[libpass] socket disconnected"); - return -EIO; - } - buffer[buffer_len] = '\0'; - - if (sscanf(buffer, "%d$%"PRId64"$%"PRId64"$%d", &response_req, start, end, &ret) < 4) - return -EINVAL; - - if (response_req != REQUEST_GET_RESOURCE_TS) { - _E("[libpass] wrong response"); - return -EINVAL; - } + ret = handle_request(&request); + if (ret < 0) + return ret; - return ret; + *start = request.ts_start; + *end = request.ts_end; + return 0; } -- 2.7.4 From f59279ad7f63ef7be148c2ac8f1baf64f02ddfae Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Mon, 8 Aug 2022 18:53:47 -0700 Subject: [PATCH 04/16] resource: Change bytes unit attributes to kilo-bytes In order to sync up with attributes of disk resource, the remaining memory- and disk-related attributes are changed to use kilo-bytes unit from now on. As following the unit changes, the name of attributes are either changed as belows: - PROCESS_ATTR_DISK_READ_BPS -> PROCESS_ATTR_DISK_READ_PER_SEC - PROCESS_ATTR_DISK_WRITE_BPS -> PROCESS_ATTR_DISK_WRITE_PER_SEC - PROCESS_GROUP_ATTR_DISK_READ_BPS -> PROCESS_GROUP_ATTR_DISK_READ_PER_SEC - PROCESS_GROUP_ATTR_DISK_WRITE_BPS -> PROCESS_GROUP_ATTR_DISK_WRITE_PER_SEC Change-Id: I2c09a6f4ef9511c2add3a559efa19f94d0253216 Signed-off-by: Dongwoo Lee --- lib/resource-monitor/resource-monitor.h | 8 +- src/resource/resource-process-group.c | 47 ++++--- src/resource/resource-process.c | 41 +++--- src/util/kernel.c | 4 - tests/integration-test/resource-monitor-tests.cpp | 8 +- tools/resource-monitor/resource-monitor.c | 152 +++++++++++----------- 6 files changed, 127 insertions(+), 133 deletions(-) diff --git a/lib/resource-monitor/resource-monitor.h b/lib/resource-monitor/resource-monitor.h index 1311975..647ad29 100644 --- a/lib/resource-monitor/resource-monitor.h +++ b/lib/resource-monitor/resource-monitor.h @@ -124,8 +124,8 @@ extern "C" { #define PROCESS_ATTR_MEM_VIRT BIT(1) /* DATA_TYPE_UINT64 */ #define PROCESS_ATTR_MEM_RSS BIT(2) /* DATA_TYPE_UINT64 */ #define PROCESS_ATTR_MEM_RSS_PERCENT BIT(3) /* DATA_TYPE_DOUBLE */ -#define PROCESS_ATTR_DISK_READ_BPS BIT(4) /* DATA_TYPE_UINT */ -#define PROCESS_ATTR_DISK_WRITE_BPS BIT(5) /* DATA_TYPE_UINT */ +#define PROCESS_ATTR_DISK_READ_PER_SEC BIT(4) /* DATA_TYPE_DOUBLE */ +#define PROCESS_ATTR_DISK_WRITE_PER_SEC BIT(5) /* DATA_TYPE_DOUBLE */ #define PROCESS_ATTR_NAME BIT(6) /* DATA_TYPE_STRING */ #define PROCESS_ATTR_PGID BIT(7) /* DATA_TYPE_INT */ #define PROCESS_ATTR_PPID BIT(8) /* DATA_TYPE_INT */ @@ -140,8 +140,8 @@ extern "C" { #define PROCESS_GROUP_ATTR_PID_LIST BIT(0) /* DATA_TYPE_ARRAY(INT) */ #define PROCESS_GROUP_ATTR_NAME_LIST BIT(1) /* DATA_TYPE_ARRAY(STRING) */ #define PROCESS_GROUP_ATTR_CPU_UTIL BIT(2) /* DATA_TYPE_DOUBLE */ -#define PROCESS_GROUP_ATTR_DISK_READ_BPS BIT(3) /* DATA_TYPE_UINT */ -#define PROCESS_GROUP_ATTR_DISK_WRITE_BPS BIT(4) /* DATA_TYPE_UINT */ +#define PROCESS_GROUP_ATTR_DISK_READ_PER_SEC BIT(3) /* DATA_TYPE_DOUBLE */ +#define PROCESS_GROUP_ATTR_DISK_WRITE_PER_SEC BIT(4) /* DATA_TYPE_DOUBLE */ #define PROCESS_GROUP_ATTR_MEM_VIRT BIT(5) /* DATA_TYPE_UINT64 */ #define PROCESS_GROUP_ATTR_MEM_RSS BIT(6) /* DATA_TYPE_UINT64 */ #define PROCESS_GROUP_ATTR_MEM_PSS BIT(7) /* DATA_TYPE_UINT64 */ diff --git a/src/resource/resource-process-group.c b/src/resource/resource-process-group.c index 754f5e4..a8a0f41 100644 --- a/src/resource/resource-process-group.c +++ b/src/resource/resource-process-group.c @@ -39,8 +39,8 @@ struct process_group_context { double cpu_util; u_int64_t mem_rss; u_int64_t mem_virt; - u_int32_t disk_rbps; - u_int32_t disk_wbps; + double disk_read_persec; + double disk_write_persec; u_int64_t mem_pss; u_int64_t mem_swap; u_int64_t mem_swap_pss; @@ -210,12 +210,11 @@ static int process_group_get_mem(struct resource *res, return 0; } -static int process_group_get_disk_bps(struct resource *res, +static int process_group_get_disk_attrs(struct resource *res, const struct resource_attribute *attr, void *data) { struct process_group_context *ctx; - u_int32_t *bps = (u_int32_t *)data; if (!res || !attr || !data) return -EINVAL; @@ -228,11 +227,11 @@ static int process_group_get_disk_bps(struct resource *res, return -EINVAL; switch (attr->id) { - case PROCESS_GROUP_ATTR_DISK_READ_BPS: - *bps = ctx->info.disk_rbps; + case PROCESS_GROUP_ATTR_DISK_READ_PER_SEC: + *(double *)data = ctx->info.disk_read_persec; break; - case PROCESS_GROUP_ATTR_DISK_WRITE_BPS: - *bps = ctx->info.disk_wbps; + case PROCESS_GROUP_ATTR_DISK_WRITE_PER_SEC: + *(double *)data = ctx->info.disk_write_persec; break; default: return -EINVAL; @@ -272,19 +271,19 @@ static const struct resource_attribute process_group_attrs[] = { .is_supported = resource_attr_supported_always, }, }, { - .name = "PROCESS_GROUP_ATTR_DISK_READ_BPS", - .id = PROCESS_GROUP_ATTR_DISK_READ_BPS, - .type = DATA_TYPE_UINT, + .name = "PROCESS_GROUP_ATTR_DISK_READ_PER_SEC", + .id = PROCESS_GROUP_ATTR_DISK_READ_PER_SEC, + .type = DATA_TYPE_DOUBLE, .ops = { - .get = process_group_get_disk_bps, + .get = process_group_get_disk_attrs, .is_supported = resource_attr_supported_always, }, }, { - .name = "PROCESS_GROUP_ATTR_DISK_WRITE_BPS", - .id = PROCESS_GROUP_ATTR_DISK_WRITE_BPS, - .type = DATA_TYPE_UINT, + .name = "PROCESS_GROUP_ATTR_DISK_WRITE_PER_SEC", + .id = PROCESS_GROUP_ATTR_DISK_WRITE_PER_SEC, + .type = DATA_TYPE_DOUBLE, .ops = { - .get = process_group_get_disk_bps, + .get = process_group_get_disk_attrs, .is_supported = resource_attr_supported_always, }, }, { @@ -479,19 +478,19 @@ static int update_aggr_taskstats(struct process_group_context *ctx, struct resou ctx->info.cpu_util += (util / nproc); } - ctx->info.mem_virt += (curr->virtmem * 1024 * 1024) / curr->ac_stime; - ctx->info.mem_rss += (curr->coremem * 1024 * 1024) / curr->ac_stime; - ctx->info.disk_rbps += ((curr->read_bytes - prev->read_bytes) * 1000000) + ctx->info.mem_virt += (curr->virtmem * 1024) / curr->ac_stime; + ctx->info.mem_rss += (curr->coremem * 1024) / curr->ac_stime; + ctx->info.disk_read_persec += (double)((curr->read_bytes - prev->read_bytes) * 1024) / (curr->ac_etime - prev->ac_etime); - ctx->info.disk_wbps += ((curr->write_bytes - prev->write_bytes) * 1000000) + ctx->info.disk_write_persec += (double)((curr->write_bytes - prev->write_bytes) * 1024) / (curr->ac_etime - prev->ac_etime); - ctx->info.mem_pss += (u_int64_t)map_info.pss * 1024; - ctx->info.mem_swap += (u_int64_t)map_info.swap * 1024; - ctx->info.mem_swap_pss += (u_int64_t)map_info.swap_pss * 1024; + ctx->info.mem_pss += (u_int64_t)map_info.pss; + ctx->info.mem_swap += (u_int64_t)map_info.swap; + ctx->info.mem_swap_pss += (u_int64_t)map_info.swap_pss; if (include_gpu_mem) - ctx->info.mem_gpu += (u_int64_t)map_info.gpu_mem * 1024; + ctx->info.mem_gpu += (u_int64_t)map_info.gpu_mem; free(prev); node->prev = curr; diff --git a/src/resource/resource-process.c b/src/resource/resource-process.c index 073b2eb..0c00e04 100644 --- a/src/resource/resource-process.c +++ b/src/resource/resource-process.c @@ -100,32 +100,32 @@ static int process_get_mem_attrs(struct resource *res, switch (attr->id) { case PROCESS_ATTR_MEM_VIRT: curr = &ctx->curr; - *mem = (curr->virtmem * 1024 * 1024) / curr->ac_stime; + *mem = (curr->virtmem * 1024) / curr->ac_stime; break; case PROCESS_ATTR_MEM_RSS: curr = &ctx->curr; - *mem = (curr->coremem * 1024 * 1024) / curr->ac_stime; + *mem = (curr->coremem * 1024) / curr->ac_stime; break; case PROCESS_ATTR_MEM_RSS_PERCENT: { double *percent = (double *)data; curr = &ctx->curr; - *percent = (curr->coremem * 1024 * 1024) / curr->ac_stime; + *percent = (curr->coremem * 1024) / curr->ac_stime; *percent /= ctx->total_memory * 100.0; break; } case PROCESS_ATTR_MEM_PSS: - *mem = (u_int64_t)ctx->map_info.pss * 1024; + *mem = (u_int64_t)ctx->map_info.pss; break; case PROCESS_ATTR_MEM_SWAP: - *mem = (u_int64_t)ctx->map_info.swap * 1024; + *mem = (u_int64_t)ctx->map_info.swap; break; case PROCESS_ATTR_MEM_SWAP_PSS: - *mem = (u_int64_t)ctx->map_info.swap_pss * 1024; + *mem = (u_int64_t)ctx->map_info.swap_pss; break; case PROCESS_ATTR_MEM_GPU: - *mem = (u_int64_t)ctx->map_info.gpu_mem * 1024; + *mem = (u_int64_t)ctx->map_info.gpu_mem; break; default: return -EINVAL; @@ -134,14 +134,13 @@ static int process_get_mem_attrs(struct resource *res, return 0; } -static int process_get_disk_bps(struct resource *res, +static int process_get_disk_attrs(struct resource *res, const struct resource_attribute *attr, void *data) { struct process_context *ctx; struct taskstats *prev, *curr; u_int64_t period; - u_int32_t *bps = (u_int32_t *)data; if (!res || !attr || !data) return -EINVAL; @@ -162,11 +161,11 @@ static int process_get_disk_bps(struct resource *res, period = curr->ac_etime - prev->ac_etime; switch (attr->id) { - case PROCESS_ATTR_DISK_READ_BPS: - *bps = (curr->read_bytes - prev->read_bytes) * 1000000 / period; + case PROCESS_ATTR_DISK_READ_PER_SEC: + *(double *)data = (double)((curr->read_bytes - prev->read_bytes) * 1024) / period; break; - case PROCESS_ATTR_DISK_WRITE_BPS: - *bps = (curr->write_bytes - prev->write_bytes) * 1000000 / period; + case PROCESS_ATTR_DISK_WRITE_PER_SEC: + *(double *)data = (double)((curr->write_bytes - prev->write_bytes) * 1024) / period; break; default: return -EINVAL; @@ -261,19 +260,19 @@ static const struct resource_attribute process_attrs[] = { .is_supported = resource_attr_supported_always, }, }, { - .name = "PROCESS_ATTR_DISK_READ_BPS", - .id = PROCESS_ATTR_DISK_READ_BPS, - .type = DATA_TYPE_UINT, + .name = "PROCESS_ATTR_DISK_READ_PER_SEC", + .id = PROCESS_ATTR_DISK_READ_PER_SEC, + .type = DATA_TYPE_DOUBLE, .ops = { - .get = process_get_disk_bps, + .get = process_get_disk_attrs, .is_supported = resource_attr_supported_always, }, }, { - .name = "PROCESS_ATTR_DISK_WRITE_BPS", - .id = PROCESS_ATTR_DISK_WRITE_BPS, - .type = DATA_TYPE_UINT, + .name = "PROCESS_ATTR_DISK_WRITE_PER_SEC", + .id = PROCESS_ATTR_DISK_WRITE_PER_SEC, + .type = DATA_TYPE_DOUBLE, .ops = { - .get = process_get_disk_bps, + .get = process_get_disk_attrs, .is_supported = resource_attr_supported_always, }, }, { diff --git a/src/util/kernel.c b/src/util/kernel.c index d9b1d19..0baaf4a 100644 --- a/src/util/kernel.c +++ b/src/util/kernel.c @@ -191,10 +191,6 @@ int kernel_get_memory_info(const char *key, u_int64_t *val) while (fgets(buf, BUFF_MAX, fp)) { if (!strncmp(buf, key, strlen(key))) { sscanf(buf, "%*s %"PRIu64, val); - if (strstr(buf, "kB")) { - *val &= GENMASK64(53, 0); - *val <<= 10; - } break; } } diff --git a/tests/integration-test/resource-monitor-tests.cpp b/tests/integration-test/resource-monitor-tests.cpp index 2b67de4..3f2bba1 100644 --- a/tests/integration-test/resource-monitor-tests.cpp +++ b/tests/integration-test/resource-monitor-tests.cpp @@ -822,8 +822,8 @@ INSTANTIATE_TEST_CASE_P (ResourceMonitorTest, ProcessResourceMonitorTest, { .attr_id = PROCESS_ATTR_MEM_VIRT, .attr_type = DATA_TYPE_UINT64, }, { .attr_id = PROCESS_ATTR_MEM_RSS, .attr_type = DATA_TYPE_UINT64, }, { .attr_id = PROCESS_ATTR_MEM_RSS_PERCENT, .attr_type = DATA_TYPE_DOUBLE, }, - { .attr_id = PROCESS_ATTR_DISK_READ_BPS, .attr_type = DATA_TYPE_UINT, }, - { .attr_id = PROCESS_ATTR_DISK_WRITE_BPS, .attr_type = DATA_TYPE_UINT, }, + { .attr_id = PROCESS_ATTR_DISK_READ_PER_SEC, .attr_type = DATA_TYPE_DOUBLE, }, + { .attr_id = PROCESS_ATTR_DISK_WRITE_PER_SEC, .attr_type = DATA_TYPE_DOUBLE, }, { .attr_id = PROCESS_ATTR_NAME, .attr_type = DATA_TYPE_STRING, }, { .attr_id = PROCESS_ATTR_PGID, .attr_type = DATA_TYPE_INT, }, { .attr_id = PROCESS_ATTR_PPID, .attr_type = DATA_TYPE_INT, }, @@ -845,8 +845,8 @@ INSTANTIATE_TEST_CASE_P (ResourceMonitorTest, ProcessResourceMonitorTest, { .attr_id = PROCESS_GROUP_ATTR_PID_LIST, .attr_type = DATA_TYPE_ARRAY, .array_type = DATA_TYPE_INT, }, { .attr_id = PROCESS_GROUP_ATTR_NAME_LIST, .attr_type = DATA_TYPE_ARRAY, .array_type = DATA_TYPE_STRING, }, { .attr_id = PROCESS_GROUP_ATTR_CPU_UTIL, .attr_type = DATA_TYPE_DOUBLE, }, - { .attr_id = PROCESS_GROUP_ATTR_DISK_READ_BPS, .attr_type = DATA_TYPE_UINT, }, - { .attr_id = PROCESS_GROUP_ATTR_DISK_WRITE_BPS, .attr_type = DATA_TYPE_UINT, }, + { .attr_id = PROCESS_GROUP_ATTR_DISK_READ_PER_SEC, .attr_type = DATA_TYPE_DOUBLE, }, + { .attr_id = PROCESS_GROUP_ATTR_DISK_WRITE_PER_SEC, .attr_type = DATA_TYPE_DOUBLE, }, { .attr_id = PROCESS_GROUP_ATTR_MEM_VIRT, .attr_type = DATA_TYPE_UINT64, }, { .attr_id = PROCESS_GROUP_ATTR_MEM_RSS, .attr_type = DATA_TYPE_UINT64, }, { .attr_id = PROCESS_GROUP_ATTR_MEM_PSS, .attr_type = DATA_TYPE_UINT64, }, diff --git a/tools/resource-monitor/resource-monitor.c b/tools/resource-monitor/resource-monitor.c index e454859..0147aaf 100644 --- a/tools/resource-monitor/resource-monitor.c +++ b/tools/resource-monitor/resource-monitor.c @@ -51,112 +51,112 @@ struct resource_attr_data { }; static struct resource_attr_data cpu_attrs[] = { - { .id = CPU_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "CPU_ATTR_NAME", .unit = "", .desc = "CPU cluster name", }, - { .id = CPU_ATTR_CUR_FREQ, .type = DATA_TYPE_INT, .name = "CPU_ATTR_CUR_FREQ", .unit = "kHz", .desc = "Current CPU frequency", }, - { .id = CPU_ATTR_MIN_FREQ, .type = DATA_TYPE_INT, .name = "CPU_ATTR_MIN_FREQ", .unit = "kHz", .desc = "Current CPU minimum frequency", }, - { .id = CPU_ATTR_MAX_FREQ, .type = DATA_TYPE_INT, .name = "CPU_ATTR_MAX_FREQ", .unit = "kHz", .desc = "Current CPU maximum frequency", }, - { .id = CPU_ATTR_AVAILABLE_MIN_FREQ, .type = DATA_TYPE_INT, .name = "CPU_ATTR_AVAILABLE_MIN_FREQ", .unit = "kHz", .desc = "Available CPU minimum frequency", }, - { .id = CPU_ATTR_AVAILABLE_MAX_FREQ, .type = DATA_TYPE_INT, .name = "CPU_ATTR_AVAILABLE_MAX_FREQ", .unit = "kHz", .desc = "Available CPU maximum frequency", }, - { .id = CPU_ATTR_CUR_GOVERNOR, .type = DATA_TYPE_STRING, .name = "CPU_ATTR_CUR_GOVERNOR", .unit = "", .desc = "Current CPU frequency governor name", }, + { .id = CPU_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "CPU_ATTR_NAME", .unit = "", .desc = "CPU cluster name", }, + { .id = CPU_ATTR_CUR_FREQ, .type = DATA_TYPE_INT, .name = "CPU_ATTR_CUR_FREQ", .unit = "kHz", .desc = "Current CPU frequency", }, + { .id = CPU_ATTR_MIN_FREQ, .type = DATA_TYPE_INT, .name = "CPU_ATTR_MIN_FREQ", .unit = "kHz", .desc = "Current CPU minimum frequency", }, + { .id = CPU_ATTR_MAX_FREQ, .type = DATA_TYPE_INT, .name = "CPU_ATTR_MAX_FREQ", .unit = "kHz", .desc = "Current CPU maximum frequency", }, + { .id = CPU_ATTR_AVAILABLE_MIN_FREQ, .type = DATA_TYPE_INT, .name = "CPU_ATTR_AVAILABLE_MIN_FREQ", .unit = "kHz", .desc = "Available CPU minimum frequency", }, + { .id = CPU_ATTR_AVAILABLE_MAX_FREQ, .type = DATA_TYPE_INT, .name = "CPU_ATTR_AVAILABLE_MAX_FREQ", .unit = "kHz", .desc = "Available CPU maximum frequency", }, + { .id = CPU_ATTR_CUR_GOVERNOR, .type = DATA_TYPE_STRING, .name = "CPU_ATTR_CUR_GOVERNOR", .unit = "", .desc = "Current CPU frequency governor name", }, }; static struct resource_attr_data bus_attrs[] = { - { .id = BUS_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "BUS_ATTR_NAME", .unit = "", .desc = "Bus device name", }, - { .id = BUS_ATTR_CUR_FREQ, .type = DATA_TYPE_INT, .name = "BUS_ATTR_CUR_FREQ", .unit = "kHz", .desc = "Current bus frequency", }, - { .id = BUS_ATTR_MIN_FREQ, .type = DATA_TYPE_INT, .name = "BUS_ATTR_MIN_FREQ", .unit = "kHz", .desc = "Current bus minimum frequency", }, - { .id = BUS_ATTR_MAX_FREQ, .type = DATA_TYPE_INT, .name = "BUS_ATTR_MAX_FREQ", .unit = "kHz", .desc = "Current bus maximum frequency", }, - { .id = BUS_ATTR_AVAILABLE_MIN_FREQ, .type = DATA_TYPE_INT, .name = "BUS_ATTR_AVAILABLE_MIN_FREQ", .unit = "kHz", .desc = "Available bus minimum frequency", }, - { .id = BUS_ATTR_AVAILABLE_MAX_FREQ, .type = DATA_TYPE_INT, .name = "BUS_ATTR_AVAILABLE_MAX_FREQ", .unit = "kHz", .desc = "Available bus maximum frequency", }, - { .id = BUS_ATTR_CUR_GOVERNOR, .type = DATA_TYPE_STRING, .name = "BUS_ATTR_CUR_GOVERNOR", .unit = "", .desc = "Current bus frequency governor name", }, + { .id = BUS_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "BUS_ATTR_NAME", .unit = "", .desc = "Bus device name", }, + { .id = BUS_ATTR_CUR_FREQ, .type = DATA_TYPE_INT, .name = "BUS_ATTR_CUR_FREQ", .unit = "kHz", .desc = "Current bus frequency", }, + { .id = BUS_ATTR_MIN_FREQ, .type = DATA_TYPE_INT, .name = "BUS_ATTR_MIN_FREQ", .unit = "kHz", .desc = "Current bus minimum frequency", }, + { .id = BUS_ATTR_MAX_FREQ, .type = DATA_TYPE_INT, .name = "BUS_ATTR_MAX_FREQ", .unit = "kHz", .desc = "Current bus maximum frequency", }, + { .id = BUS_ATTR_AVAILABLE_MIN_FREQ, .type = DATA_TYPE_INT, .name = "BUS_ATTR_AVAILABLE_MIN_FREQ", .unit = "kHz", .desc = "Available bus minimum frequency", }, + { .id = BUS_ATTR_AVAILABLE_MAX_FREQ, .type = DATA_TYPE_INT, .name = "BUS_ATTR_AVAILABLE_MAX_FREQ", .unit = "kHz", .desc = "Available bus maximum frequency", }, + { .id = BUS_ATTR_CUR_GOVERNOR, .type = DATA_TYPE_STRING, .name = "BUS_ATTR_CUR_GOVERNOR", .unit = "", .desc = "Current bus frequency governor name", }, }; static struct resource_attr_data gpu_attrs[] = { - { .id = GPU_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "GPU_ATTR_NAME", .unit = "", .desc = "GPU device name", }, - { .id = GPU_ATTR_CUR_FREQ, .type = DATA_TYPE_INT, .name = "GPU_ATTR_CUR_FREQ", .unit = "kHz", .desc = "Current GPU frequency", }, - { .id = GPU_ATTR_MIN_FREQ, .type = DATA_TYPE_INT, .name = "GPU_ATTR_MIN_FREQ", .unit = "kHz", .desc = "Current GPU minimum frequency", }, - { .id = GPU_ATTR_MAX_FREQ, .type = DATA_TYPE_INT, .name = "GPU_ATTR_MAX_FREQ", .unit = "kHz", .desc = "Current GPU maximum frequency", }, - { .id = GPU_ATTR_AVAILABLE_MIN_FREQ, .type = DATA_TYPE_INT, .name = "GPU_ATTR_AVAILABLE_MIN_FREQ", .unit = "kHz", .desc = "Available GPU minimum frequency", }, - { .id = GPU_ATTR_AVAILABLE_MAX_FREQ, .type = DATA_TYPE_INT, .name = "GPU_ATTR_AVAILABLE_MAX_FREQ", .unit = "kHz", .desc = "Available GPU maximum frequency", }, - { .id = GPU_ATTR_CUR_GOVERNOR, .type = DATA_TYPE_STRING, .name = "GPU_ATTR_CUR_GOVERNOR", .unit = "", .desc = "Current GPU frequency governor name", }, + { .id = GPU_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "GPU_ATTR_NAME", .unit = "", .desc = "GPU device name", }, + { .id = GPU_ATTR_CUR_FREQ, .type = DATA_TYPE_INT, .name = "GPU_ATTR_CUR_FREQ", .unit = "kHz", .desc = "Current GPU frequency", }, + { .id = GPU_ATTR_MIN_FREQ, .type = DATA_TYPE_INT, .name = "GPU_ATTR_MIN_FREQ", .unit = "kHz", .desc = "Current GPU minimum frequency", }, + { .id = GPU_ATTR_MAX_FREQ, .type = DATA_TYPE_INT, .name = "GPU_ATTR_MAX_FREQ", .unit = "kHz", .desc = "Current GPU maximum frequency", }, + { .id = GPU_ATTR_AVAILABLE_MIN_FREQ, .type = DATA_TYPE_INT, .name = "GPU_ATTR_AVAILABLE_MIN_FREQ", .unit = "kHz", .desc = "Available GPU minimum frequency", }, + { .id = GPU_ATTR_AVAILABLE_MAX_FREQ, .type = DATA_TYPE_INT, .name = "GPU_ATTR_AVAILABLE_MAX_FREQ", .unit = "kHz", .desc = "Available GPU maximum frequency", }, + { .id = GPU_ATTR_CUR_GOVERNOR, .type = DATA_TYPE_STRING, .name = "GPU_ATTR_CUR_GOVERNOR", .unit = "", .desc = "Current GPU frequency governor name", }, }; static struct resource_attr_data memory_attrs[] = { - { .id = MEMORY_ATTR_TOTAL, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_TOTAL", .unit = "byte", .desc = "Memory total size", }, - { .id = MEMORY_ATTR_AVAILABLE, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_AVAILABLE", .unit = "byte", .desc = "Memory available size", }, - { .id = MEMORY_ATTR_FREE, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_FREE", .unit = "byte", .desc = "Memory free size", }, - { .id = MEMORY_ATTR_BUFFER, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_BUFFER", .unit = "byte", .desc = "Memorry buffer size", }, - { .id = MEMORY_ATTR_CACHED, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_CACHED", .unit = "byte", .desc = "Memory cached size", }, - { .id = MEMORY_ATTR_CMA_TOTAL, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_CMA_TOTAL", .unit = "byte", .desc = "CMA memory total size", }, - { .id = MEMORY_ATTR_CMA_FREE, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_CMA_FREE", .unit = "byte", .desc = "CMA memory free size", }, - { .id = MEMORY_ATTR_SWAP_TOTAL, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_SWAP_TOTAL", .unit = "byte", .desc = "Swap memory total size", }, - { .id = MEMORY_ATTR_SWAP_FREE, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_SWAP_FREE", .unit = "byte", .desc = "Swap memory free size", }, + { .id = MEMORY_ATTR_TOTAL, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_TOTAL", .unit = "kB", .desc = "Memory total size", }, + { .id = MEMORY_ATTR_AVAILABLE, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_AVAILABLE", .unit = "kB", .desc = "Memory available size", }, + { .id = MEMORY_ATTR_FREE, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_FREE", .unit = "kB", .desc = "Memory free size", }, + { .id = MEMORY_ATTR_BUFFER, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_BUFFER", .unit = "kB", .desc = "Memorry buffer size", }, + { .id = MEMORY_ATTR_CACHED, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_CACHED", .unit = "kB", .desc = "Memory cached size", }, + { .id = MEMORY_ATTR_CMA_TOTAL, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_CMA_TOTAL", .unit = "kB", .desc = "CMA memory total size", }, + { .id = MEMORY_ATTR_CMA_FREE, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_CMA_FREE", .unit = "kB", .desc = "CMA memory free size", }, + { .id = MEMORY_ATTR_SWAP_TOTAL, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_SWAP_TOTAL", .unit = "kB", .desc = "Swap memory total size", }, + { .id = MEMORY_ATTR_SWAP_FREE, .type = DATA_TYPE_UINT64, .name = "MEMORY_ATTR_SWAP_FREE", .unit = "kB", .desc = "Swap memory free size", }, }; static struct resource_attr_data battery_attrs[] = { - { .id = BATTERY_ATTR_CAPACITY, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_CAPACITY", .unit = "%", .desc = "Battery capacity", }, - { .id = BATTERY_ATTR_STATUS, .type = DATA_TYPE_STRING, .name = "BATTERY_ATTR_STATUS", .unit = "", .desc = "Battery status", }, - { .id = BATTERY_ATTR_TEMPERATURE, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_TEMPERATURE", .unit = "", .desc = "Battery temperature", }, - { .id = BATTERY_ATTR_VOLTAGE_NOW, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_VOLTAGE_NOW", .unit = "uV", .desc = "Battery voltage figure", }, - { .id = BATTERY_ATTR_CURRENT_NOW, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_CURRENT_NOW", .unit = "uA", .desc = "Battery current figure", }, - { .id = BATTERY_ATTR_PRESENT, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_PRESENT", .unit = "", .desc = "Battery connected status", }, + { .id = BATTERY_ATTR_CAPACITY, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_CAPACITY", .unit = "%", .desc = "Battery capacity", }, + { .id = BATTERY_ATTR_STATUS, .type = DATA_TYPE_STRING, .name = "BATTERY_ATTR_STATUS", .unit = "", .desc = "Battery status", }, + { .id = BATTERY_ATTR_TEMPERATURE, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_TEMPERATURE", .unit = "", .desc = "Battery temperature", }, + { .id = BATTERY_ATTR_VOLTAGE_NOW, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_VOLTAGE_NOW", .unit = "uV", .desc = "Battery voltage figure", }, + { .id = BATTERY_ATTR_CURRENT_NOW, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_CURRENT_NOW", .unit = "uA", .desc = "Battery current figure", }, + { .id = BATTERY_ATTR_PRESENT, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_PRESENT", .unit = "", .desc = "Battery connected status", }, }; static struct resource_attr_data display_attrs[] = { - { .id = DISPLAY_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "DISPLAY_ATTR_NAME", .unit = "", .desc = "Display device name", }, - { .id = DISPLAY_ATTR_FPS, .type = DATA_TYPE_DOUBLE, .name = "DISPLAY_ATTR_FPS", .unit = "fps", .desc = "Frame per second", }, + { .id = DISPLAY_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "DISPLAY_ATTR_NAME", .unit = "", .desc = "Display device name", }, + { .id = DISPLAY_ATTR_FPS, .type = DATA_TYPE_DOUBLE, .name = "DISPLAY_ATTR_FPS", .unit = "fps", .desc = "Frame per second", }, }; static struct resource_attr_data system_attrs[] = { - { .id = SYSTEM_ATTR_CPU_UTIL, .type = DATA_TYPE_DOUBLE, .name = "SYSTEM_ATTR_CPU_UTIL", .unit = "%", .desc = "CPU average utilization", }, - { .id = SYSTEM_ATTR_CPU_USER_UTIL, .type = DATA_TYPE_DOUBLE, .name = "SYSTEM_ATTR_CPU_USER_UTIL", .unit = "%", .desc = "CPU average utilization on user", }, - { .id = SYSTEM_ATTR_CPU_SYS_UTIL, .type = DATA_TYPE_DOUBLE, .name = "SYSTEM_ATTR_CPU_SYS_UTIL", .unit = "%", .desc = "CPU average utilization on system", }, - { .id = SYSTEM_ATTR_PER_CPU_UTIL, .type = DATA_TYPE_ARRAY, .name = "SYSTEM_ATTR_PER_CPU_UTIL", .unit = "%", .desc = "Per-CPU utilization", .array_type = DATA_TYPE_DOUBLE, }, - { .id = SYSTEM_ATTR_PER_CPU_USER_UTIL, .type = DATA_TYPE_ARRAY, .name = "SYSTEM_ATTR_PER_CPU_USER_UTIL", .unit = "%", .desc = "Per-CPU utilization on user", .array_type = DATA_TYPE_DOUBLE, }, - { .id = SYSTEM_ATTR_PER_CPU_SYS_UTIL, .type = DATA_TYPE_ARRAY, .name = "SYSTEM_ATTR_PER_CPU_SYS_UTIL", .unit = "%", .desc = "Per-CPU utilization on system", .array_type = DATA_TYPE_DOUBLE, }, - { .id = SYSTEM_ATTR_POSSIBLE_CPU, .type = DATA_TYPE_INT, .name = "SYSTEM_ATTR_POSSIBLE_CPU", .unit = "ea", .desc = "Number of possible CPU", }, - { .id = SYSTEM_ATTR_ONLINE_CPU, .type = DATA_TYPE_INT, .name = "SYSTEM_ATTR_ONLINE_CPU", .unit = "ea", .desc = "Number of online CPU", }, + { .id = SYSTEM_ATTR_CPU_UTIL, .type = DATA_TYPE_DOUBLE, .name = "SYSTEM_ATTR_CPU_UTIL", .unit = "%", .desc = "CPU average utilization", }, + { .id = SYSTEM_ATTR_CPU_USER_UTIL, .type = DATA_TYPE_DOUBLE, .name = "SYSTEM_ATTR_CPU_USER_UTIL", .unit = "%", .desc = "CPU average utilization on user", }, + { .id = SYSTEM_ATTR_CPU_SYS_UTIL, .type = DATA_TYPE_DOUBLE, .name = "SYSTEM_ATTR_CPU_SYS_UTIL", .unit = "%", .desc = "CPU average utilization on system", }, + { .id = SYSTEM_ATTR_PER_CPU_UTIL, .type = DATA_TYPE_ARRAY, .name = "SYSTEM_ATTR_PER_CPU_UTIL", .unit = "%", .desc = "Per-CPU utilization", .array_type = DATA_TYPE_DOUBLE, }, + { .id = SYSTEM_ATTR_PER_CPU_USER_UTIL, .type = DATA_TYPE_ARRAY, .name = "SYSTEM_ATTR_PER_CPU_USER_UTIL", .unit = "%", .desc = "Per-CPU utilization on user", .array_type = DATA_TYPE_DOUBLE, }, + { .id = SYSTEM_ATTR_PER_CPU_SYS_UTIL, .type = DATA_TYPE_ARRAY, .name = "SYSTEM_ATTR_PER_CPU_SYS_UTIL", .unit = "%", .desc = "Per-CPU utilization on system", .array_type = DATA_TYPE_DOUBLE, }, + { .id = SYSTEM_ATTR_POSSIBLE_CPU, .type = DATA_TYPE_INT, .name = "SYSTEM_ATTR_POSSIBLE_CPU", .unit = "ea", .desc = "Number of possible CPU", }, + { .id = SYSTEM_ATTR_ONLINE_CPU, .type = DATA_TYPE_INT, .name = "SYSTEM_ATTR_ONLINE_CPU", .unit = "ea", .desc = "Number of online CPU", }, }; struct resource_attr_data process_attrs[] = { - { .id = PROCESS_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "PROCESS_ATTR_NAME", .unit = "", .desc = "Process name", }, - { .id = PROCESS_ATTR_CPU_UTIL, .type = DATA_TYPE_DOUBLE, .name = "PROCESS_ATTR_CPU_UTIL", .unit = "%", .desc = "Process CPU utilization", }, - { .id = PROCESS_ATTR_MEM_VIRT, .type = DATA_TYPE_UINT64, .name = "PROCESS_ATTR_MEM_VIRT", .unit = "byte", .desc = "Process VIRT memory size", }, - { .id = PROCESS_ATTR_MEM_RSS, .type = DATA_TYPE_UINT64, .name = "PROCESS_ATTR_MEM_RSS", .unit = "byte", .desc = "Process RSS(Resident Set Size) memory size", }, - { .id = PROCESS_ATTR_MEM_RSS_PERCENT, .type = DATA_TYPE_DOUBLE, .name = "PROCESS_ATTR_MEM_RSS_PERCENT", .unit = "%", .desc = "Process RSS(Resident Set Size) memory percent", }, - { .id = PROCESS_ATTR_DISK_READ_BPS, .type = DATA_TYPE_UINT, .name = "PROCESS_ATTR_DISK_READ_BPS", .unit = "b/s", .desc = "Process disk read per second", }, - { .id = PROCESS_ATTR_DISK_WRITE_BPS, .type = DATA_TYPE_UINT, .name = "PROCESS_ATTR_DISK_WRITE_BPS", .unit = "b/s", .desc = "Process disk write per second", }, - { .id = PROCESS_ATTR_PGID, .type = DATA_TYPE_INT, .name = "PROCESS_ATTR_PGID", .unit = "", .desc = "Process group ID", }, - { .id = PROCESS_ATTR_PPID, .type = DATA_TYPE_INT, .name = "PROCESS_ATTR_PPID", .unit = "", .desc = "Process parent PID(Process ID)", }, - { .id = PROCESS_ATTR_MEM_PSS, .type = DATA_TYPE_UINT64, .name = "PROCESS_ATTR_MEM_PSS", .unit = "byte", .desc = "Process PSS(Propotional Set Size) memory size", }, - { .id = PROCESS_ATTR_MEM_SWAP, .type = DATA_TYPE_UINT64, .name = "PROCESS_ATTR_MEM_SWAP", .unit = "byte", .desc = "Process Swap memory size", }, - { .id = PROCESS_ATTR_MEM_SWAP_PSS, .type = DATA_TYPE_UINT64, .name = "PROCESS_ATTR_MEM_SWAP_PSS", .unit = "byte", .desc = "Process Swap PSS(Propotional Set Size) memory size", }, - { .id = PROCESS_ATTR_MEM_GPU, .type = DATA_TYPE_UINT64, .name = "PROCESS_ATTR_MEM_GPU", .unit = "byte", .desc = "Process GPU memory size", }, + { .id = PROCESS_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "PROCESS_ATTR_NAME", .unit = "", .desc = "Process name", }, + { .id = PROCESS_ATTR_CPU_UTIL, .type = DATA_TYPE_DOUBLE, .name = "PROCESS_ATTR_CPU_UTIL", .unit = "%", .desc = "Process CPU utilization", }, + { .id = PROCESS_ATTR_MEM_VIRT, .type = DATA_TYPE_UINT64, .name = "PROCESS_ATTR_MEM_VIRT", .unit = "kB", .desc = "Process VIRT memory size", }, + { .id = PROCESS_ATTR_MEM_RSS, .type = DATA_TYPE_UINT64, .name = "PROCESS_ATTR_MEM_RSS", .unit = "kB", .desc = "Process RSS(Resident Set Size) memory size", }, + { .id = PROCESS_ATTR_MEM_RSS_PERCENT, .type = DATA_TYPE_DOUBLE, .name = "PROCESS_ATTR_MEM_RSS_PERCENT", .unit = "%", .desc = "Process RSS(Resident Set Size) memory percent", }, + { .id = PROCESS_ATTR_DISK_READ_PER_SEC, .type = DATA_TYPE_DOUBLE, .name = "PROCESS_ATTR_DISK_READ_PER_SEC", .unit = "kB/s", .desc = "Process disk read per second", }, + { .id = PROCESS_ATTR_DISK_WRITE_PER_SEC, .type = DATA_TYPE_DOUBLE, .name = "PROCESS_ATTR_DISK_WRITE_PER_SEC", .unit = "kB/s", .desc = "Process disk write per second", }, + { .id = PROCESS_ATTR_PGID, .type = DATA_TYPE_INT, .name = "PROCESS_ATTR_PGID", .unit = "", .desc = "Process group ID", }, + { .id = PROCESS_ATTR_PPID, .type = DATA_TYPE_INT, .name = "PROCESS_ATTR_PPID", .unit = "", .desc = "Process parent PID(Process ID)", }, + { .id = PROCESS_ATTR_MEM_PSS, .type = DATA_TYPE_UINT64, .name = "PROCESS_ATTR_MEM_PSS", .unit = "kB", .desc = "Process PSS(Propotional Set Size) memory size", }, + { .id = PROCESS_ATTR_MEM_SWAP, .type = DATA_TYPE_UINT64, .name = "PROCESS_ATTR_MEM_SWAP", .unit = "kB", .desc = "Process Swap memory size", }, + { .id = PROCESS_ATTR_MEM_SWAP_PSS, .type = DATA_TYPE_UINT64, .name = "PROCESS_ATTR_MEM_SWAP_PSS", .unit = "kB", .desc = "Process Swap PSS(Propotional Set Size) memory size", }, + { .id = PROCESS_ATTR_MEM_GPU, .type = DATA_TYPE_UINT64, .name = "PROCESS_ATTR_MEM_GPU", .unit = "kB", .desc = "Process GPU memory size", }, }; struct resource_attr_data process_group_attrs[] = { - { .id = PROCESS_GROUP_ATTR_PID_LIST, .type = DATA_TYPE_ARRAY, .name = "PROCESS_GROUP_ATTR_PID_LIST", .unit = "", .desc = "Process-group PID(Process ID) list", .array_type = DATA_TYPE_INT, }, - { .id = PROCESS_GROUP_ATTR_NAME_LIST, .type = DATA_TYPE_ARRAY, .name = "PROCESS_GROUP_ATTR_NAME_LIST", .unit = "", .desc = "Process-group name list", .array_type = DATA_TYPE_STRING, }, - { .id = PROCESS_GROUP_ATTR_CPU_UTIL, .type = DATA_TYPE_DOUBLE, .name = "PROCESS_GROUP_ATTR_CPU_UTIL", .unit = "%", .desc = "Process-group CPU utilization", }, - { .id = PROCESS_GROUP_ATTR_DISK_READ_BPS, .type = DATA_TYPE_UINT, .name = "PROCESS_GROUP_ATTR_DISK_READ_BPS", .unit = "b/s", .desc = "Process-group disk read per second", }, - { .id = PROCESS_GROUP_ATTR_DISK_WRITE_BPS, .type = DATA_TYPE_UINT, .name = "PROCESS_GROUP_ATTR_DISK_WRITE_BPS", .unit = "b/s", .desc = "Process-group disk write per second", }, - { .id = PROCESS_GROUP_ATTR_MEM_VIRT, .type = DATA_TYPE_UINT64, .name = "PROCESS_GROUP_ATTR_MEM_VIRT", .unit = "byte", .desc = "Process-group VIRT memory size", }, - { .id = PROCESS_GROUP_ATTR_MEM_RSS, .type = DATA_TYPE_UINT64, .name = "PROCESS_GROUP_ATTR_MEM_RSS", .unit = "byte", .desc = "Process-group RSS(Resident Set Size) memory size", }, - { .id = PROCESS_GROUP_ATTR_MEM_PSS, .type = DATA_TYPE_UINT64, .name = "PROCESS_GROUP_ATTR_MEM_PSS", .unit = "byte", .desc = "Process-group PSS(Propotional Set Size) memory size", }, - { .id = PROCESS_GROUP_ATTR_MEM_SWAP, .type = DATA_TYPE_UINT64, .name = "PROCESS_GROUP_ATTR_MEM_SWAP", .unit = "byte", .desc = "Process-group Swap memory size", }, - { .id = PROCESS_GROUP_ATTR_MEM_SWAP_PSS, .type = DATA_TYPE_UINT64, .name = "PROCESS_GROUP_ATTR_MEM_SWAP_PSS", .unit = "byte", .desc = "Process-group Swap PSS(Propotional Set Size) memory size", }, - { .id = PROCESS_GROUP_ATTR_MEM_GPU, .type = DATA_TYPE_UINT64, .name = "PROCESS_GROUP_ATTR_MEM_GPU", .unit = "byte", .desc = "Process-group GPU memory size", }, + { .id = PROCESS_GROUP_ATTR_PID_LIST, .type = DATA_TYPE_ARRAY, .name = "PROCESS_GROUP_ATTR_PID_LIST", .unit = "", .desc = "Process-group PID(Process ID) list", .array_type = DATA_TYPE_INT, }, + { .id = PROCESS_GROUP_ATTR_NAME_LIST, .type = DATA_TYPE_ARRAY, .name = "PROCESS_GROUP_ATTR_NAME_LIST", .unit = "", .desc = "Process-group name list", .array_type = DATA_TYPE_STRING, }, + { .id = PROCESS_GROUP_ATTR_CPU_UTIL, .type = DATA_TYPE_DOUBLE, .name = "PROCESS_GROUP_ATTR_CPU_UTIL", .unit = "%", .desc = "Process-group CPU utilization", }, + { .id = PROCESS_GROUP_ATTR_DISK_READ_PER_SEC, .type = DATA_TYPE_DOUBLE, .name = "PROCESS_GROUP_ATTR_DISK_READ_PER_SEC", .unit = "kB/s", .desc = "Process-group disk read per second", }, + { .id = PROCESS_GROUP_ATTR_DISK_WRITE_PER_SEC, .type = DATA_TYPE_DOUBLE, .name = "PROCESS_GROUP_ATTR_DISK_WRITE_PER_SEC", .unit = "kB/s", .desc = "Process-group disk write per second", }, + { .id = PROCESS_GROUP_ATTR_MEM_VIRT, .type = DATA_TYPE_UINT64, .name = "PROCESS_GROUP_ATTR_MEM_VIRT", .unit = "kB", .desc = "Process-group VIRT memory size", }, + { .id = PROCESS_GROUP_ATTR_MEM_RSS, .type = DATA_TYPE_UINT64, .name = "PROCESS_GROUP_ATTR_MEM_RSS", .unit = "kB", .desc = "Process-group RSS(Resident Set Size) memory size", }, + { .id = PROCESS_GROUP_ATTR_MEM_PSS, .type = DATA_TYPE_UINT64, .name = "PROCESS_GROUP_ATTR_MEM_PSS", .unit = "kB", .desc = "Process-group PSS(Propotional Set Size) memory size", }, + { .id = PROCESS_GROUP_ATTR_MEM_SWAP, .type = DATA_TYPE_UINT64, .name = "PROCESS_GROUP_ATTR_MEM_SWAP", .unit = "kB", .desc = "Process-group Swap memory size", }, + { .id = PROCESS_GROUP_ATTR_MEM_SWAP_PSS, .type = DATA_TYPE_UINT64, .name = "PROCESS_GROUP_ATTR_MEM_SWAP_PSS", .unit = "kB", .desc = "Process-group Swap PSS(Propotional Set Size) memory size", }, + { .id = PROCESS_GROUP_ATTR_MEM_GPU, .type = DATA_TYPE_UINT64, .name = "PROCESS_GROUP_ATTR_MEM_GPU", .unit = "kB", .desc = "Process-group GPU memory size", }, }; struct resource_attr_data disk_attrs[] = { - { .id = DISK_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "DISK_ATTR_NAME", .unit = "", .desc = "Disk device name", }, - { .id = DISK_ATTR_READ_PER_SEC, .type = DATA_TYPE_DOUBLE, .name = "DISK_ATTR_READ_PER_SEC", .unit = "kB/s", .desc = "Disk read per second", }, - { .id = DISK_ATTR_WRITE_PER_SEC, .type = DATA_TYPE_DOUBLE, .name = "DISK_ATTR_WRITE_PER_SEC", .unit = "kB/s", .desc = "Disk write per second", }, - { .id = DISK_ATTR_READ_TOTAL, .type = DATA_TYPE_UINT64, .name = "DISK_ATTR_READ_TOTAL", .unit = "kB", .desc = "Disk read total size", }, - { .id = DISK_ATTR_WRITE_TOTAL, .type = DATA_TYPE_UINT64, .name = "DISK_ATTR_WRITE_TOTAL", .unit = "kB", .desc = "Disk write total size", }, + { .id = DISK_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "DISK_ATTR_NAME", .unit = "", .desc = "Disk device name", }, + { .id = DISK_ATTR_READ_PER_SEC, .type = DATA_TYPE_DOUBLE, .name = "DISK_ATTR_READ_PER_SEC", .unit = "kB/s", .desc = "Disk read per second", }, + { .id = DISK_ATTR_WRITE_PER_SEC, .type = DATA_TYPE_DOUBLE, .name = "DISK_ATTR_WRITE_PER_SEC", .unit = "kB/s", .desc = "Disk write per second", }, + { .id = DISK_ATTR_READ_TOTAL, .type = DATA_TYPE_UINT64, .name = "DISK_ATTR_READ_TOTAL", .unit = "kB", .desc = "Disk read total size", }, + { .id = DISK_ATTR_WRITE_TOTAL, .type = DATA_TYPE_UINT64, .name = "DISK_ATTR_WRITE_TOTAL", .unit = "kB", .desc = "Disk write total size", }, }; struct resource_attr_data network_attrs[] = { - { .id = NETWORK_ATTR_NAME, .type =DATA_TYPE_STRING, .name = "NETWORK_ATTR_NAME", .unit = "", .desc = "Network device name", }, + { .id = NETWORK_ATTR_NAME, .type = DATA_TYPE_STRING, .name = "NETWORK_ATTR_NAME", .unit = "", .desc = "Network device name", }, }; struct resource_data { -- 2.7.4 From 262596e61b09dbaf32a8f4de62f56163826f869e Mon Sep 17 00:00:00 2001 From: Sung-hun Kim Date: Tue, 9 Aug 2022 11:01:48 +0900 Subject: [PATCH 05/16] util: thread: Use wait_for_completion without result Change-Id: I3969491c2ce9d8ecccfdb064bc65274cb05cb53f Signed-off-by: Sung-hun Kim --- src/util/thread.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/util/thread.c b/src/util/thread.c index 8bcef56..0bf45ec 100644 --- a/src/util/thread.c +++ b/src/util/thread.c @@ -196,7 +196,8 @@ int wait_for_completion(struct thread *thread, void **result) if (ret == THREAD_RETURN_ERROR) return ret; - *result = ctx->result; + if (result) + *result = ctx->result; cnd_destroy(&ctx->wait); mtx_destroy(&ctx->lock); -- 2.7.4 From 7332663441031588dbc3cbf6de9d4c75d90f02a5 Mon Sep 17 00:00:00 2001 From: Sung-hun Kim Date: Tue, 9 Aug 2022 14:45:55 +0900 Subject: [PATCH 06/16] resource: display: Add a display monitor thread to deal with multiple clients When multiple clients request to get fps concurrently, unacceptable delays (upto tens of seconds for hundred clients) are incurred. I guess that the dbus function g_dbus_connection_send_message_with_reply_sync() cannot deal with multiple concurrent calls. This patch added a monitor thread to read current fps value via dbus. The thread shares read fps value to clients. By doing so, multiple clients can get the fps value without delays. Change-Id: I726092658ef79af3610baa6fa356d8a54c6cf299 Signed-off-by: Sung-hun Kim --- src/resource/resource-display.c | 122 ++++++++++++++++++++++++++++++++-------- 1 file changed, 100 insertions(+), 22 deletions(-) diff --git a/src/resource/resource-display.c b/src/resource/resource-display.c index 0f5a82a..724b5df 100644 --- a/src/resource/resource-display.c +++ b/src/resource/resource-display.c @@ -23,6 +23,7 @@ */ #include +#include #include @@ -30,6 +31,7 @@ #include #include #include +#include #include @@ -38,6 +40,8 @@ #define DBUS_ENLIGHTENMENT_INTERFACE "org.enlightenment.wm.info" #define DBUS_ENLIGHTENMENT_FPS_FUNC "get_fps_info" +#define DISPLAY_SAMPLE_RATE_MSEC 1000 + struct display_context { char *device_name; int index; @@ -51,31 +55,24 @@ struct display_fps_data { double fps; }; -static int display_get_fps(struct resource *res, - const struct resource_attribute *attr, - void *data) +struct display_fps_monitor { + int holder; + int resource_count; + double *last_fps; + struct thread *thread; + GMutex display_lock; +}; + +static struct display_fps_monitor g_fps_monitor; + +static int display_read_fps(int resource_index) { - struct display_context *ctx; + int ret = 0; GDBusConnection *conn; GDBusMessage *msg, *reply; GVariant *result, *value; GError *err = NULL; struct display_fps_data fps_data; - double *fps = (double *)data; - int ret = 0; - - if (!res || !attr || !data) - return -EINVAL; - - ctx = get_resource_privdata(res); - if (!ctx) - return -EINVAL; - - if (!ctx->device_name) { - _E("%s: DISPLAY_CTRL_DEVICE_ID is not yet initialized\n", - get_resource_name(res)); - return -EINVAL; - } /* Connect dbus interface and receive message */ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); @@ -115,13 +112,14 @@ static int display_get_fps(struct resource *res, } /* Get the fps information according to the index of resource_device */ - value = g_variant_get_child_value(result, ctx->index); + value = g_variant_get_child_value(result, resource_index); g_variant_get(value, "(usiud)", &fps_data.type, fps_data.output, &fps_data.zpos, &fps_data.window, &fps_data.fps); out: - *fps = fps_data.fps; + __atomic_store((&g_fps_monitor.last_fps[resource_index]), + &fps_data.fps, __ATOMIC_RELEASE); err_reply: g_object_unref(reply); @@ -133,6 +131,31 @@ err_conn: return ret; } +static int display_get_fps(struct resource *res, + const struct resource_attribute *attr, + void *data) +{ + struct display_context *ctx; + double *fps = (double *)data; + + if (!res || !attr || !data) + return -EINVAL; + + ctx = get_resource_privdata(res); + if (!ctx) + return -EINVAL; + + if (!ctx->device_name) { + _E("%s: DISPLAY_CTRL_DEVICE_ID is not yet initialized\n", + get_resource_name(res)); + return -EINVAL; + } + + __atomic_load(&g_fps_monitor.last_fps[ctx->index], fps, __ATOMIC_ACQUIRE); + + return 0; +} + static int display_get_name(struct resource *res, const struct resource_attribute *attr, void *data) @@ -217,8 +240,49 @@ static const struct resource_control display_ctrls[] = { }, }; +static int display_monitor_func(void *data, void **result) +{ + int i; + + for (i = 0; i < g_fps_monitor.resource_count; i++) + display_read_fps(i); + + return THREAD_RETURN_CONTINUE; +} + +static int init_display_monitor_thread(struct resource *res) +{ + int ret; + + g_fps_monitor.resource_count = get_resource_device_count(get_resource_type(res)); + g_fps_monitor.last_fps = calloc(g_fps_monitor.resource_count, sizeof(double)); + if (!g_fps_monitor.last_fps) + return -ENOMEM; + + ret = create_timer_thread(&g_fps_monitor.thread, DISPLAY_SAMPLE_RATE_MSEC, + display_monitor_func, NULL); + + return ret; +} + +static void __DESTRUCTOR__ exit_display_monitor_thread(void) +{ + if (g_fps_monitor.thread != NULL) { + destroy_thread(g_fps_monitor.thread); + g_fps_monitor.thread = NULL; + } + + if (g_fps_monitor.last_fps) { + free(g_fps_monitor.last_fps); + g_fps_monitor.last_fps = NULL; + } + + g_fps_monitor.resource_count = 0; +} + static int display_init(struct resource *res) { + int ret = 0; struct display_context *ctx; ctx = calloc(1, sizeof(struct display_context)); @@ -229,7 +293,16 @@ static int display_init(struct resource *res) set_resource_privdata(res, ctx); - return 0; + g_mutex_lock(&g_fps_monitor.display_lock); + if (g_fps_monitor.holder++ == 0) { + if (!g_fps_monitor.thread) + ret = init_display_monitor_thread(res); + else + resume_thread(g_fps_monitor.thread); + } + g_mutex_unlock(&g_fps_monitor.display_lock); + + return ret; } static void display_exit(struct resource *res) @@ -248,6 +321,11 @@ static void display_exit(struct resource *res) free(ctx); set_resource_privdata(res, NULL); + + g_mutex_lock(&g_fps_monitor.display_lock); + if (--g_fps_monitor.holder == 0 && g_fps_monitor.thread != NULL) + suspend_thread(g_fps_monitor.thread); + g_mutex_unlock(&g_fps_monitor.display_lock); } static const struct resource_driver display_resource_driver = { -- 2.7.4 From a155d4bce4d1ebc58dc1d287b8f9f87fcfc50c87 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Sat, 6 Aug 2022 02:31:24 +0900 Subject: [PATCH 07/16] lib: resource-monitor: Change prototype of pass_resource_monitor_get_resource_count Almost get_value functions get the value by using l-value parameter. In order to keep the consistent function prototype stule, change the prototype of pass_resource_monitor_get_resource_count function as following: - before: int pass_resource_monitor_get_resource_count(int id, int resource_type); - after : int pass_resource_monitor_get_resource_count(int id, int resource_type, int *resource_count); Change-Id: Ic18f45a1ee4bbd4f9320751541cf00b3f4d9f5c8 Signed-off-by: Chanwoo Choi --- lib/resource-monitor/resource-monitor.c | 11 +++- lib/resource-monitor/resource-monitor.h | 3 +- src/monitor/request-handler.c | 13 ++++- tests/integration-test/resource-monitor-tests.cpp | 69 ++++++++++++----------- tools/resource-monitor/resource-monitor.c | 11 ++-- 5 files changed, 64 insertions(+), 43 deletions(-) diff --git a/lib/resource-monitor/resource-monitor.c b/lib/resource-monitor/resource-monitor.c index 3d6a1a9..62e42cf 100644 --- a/lib/resource-monitor/resource-monitor.c +++ b/lib/resource-monitor/resource-monitor.c @@ -191,6 +191,7 @@ static inline int handle_request(struct request_data *data) ret = 0; switch (data->request) { case REQUEST_GET_VALUE_INT: + case REQUEST_GET_RESOURCE_COUNT: if (sscanf(buffer, "%d$%d$%d", &response_req, &data->value_int32, &response_ret) < 3) ret = EINVAL; @@ -324,15 +325,21 @@ int pass_resource_monitor_exit(int id) } EXPORT -int pass_resource_monitor_get_resource_count(int id, int resource_type) +int pass_resource_monitor_get_resource_count(int id, int resource_type, int *resource_count) { struct request_data request = { .request = REQUEST_GET_RESOURCE_COUNT, .client_id = id, .resource_type = resource_type, }; + int ret; - return handle_request(&request); + ret = handle_request(&request); + if (ret < 0) + return ret; + + *resource_count = request.value_int32; + return 0; } EXPORT diff --git a/lib/resource-monitor/resource-monitor.h b/lib/resource-monitor/resource-monitor.h index 647ad29..97b11e0 100644 --- a/lib/resource-monitor/resource-monitor.h +++ b/lib/resource-monitor/resource-monitor.h @@ -182,9 +182,10 @@ int pass_resource_monitor_exit(int id); * @brief Get the count of supported resources according to resource type * @param[in] Resource monitor id * @param[in] Resource type + * @param[out] Resource count retrieved from resource monitor * @return @c positive integer as resource count on success, otherwise a negative error value */ -int pass_resource_monitor_get_resource_count(int id, int resource_type); +int pass_resource_monitor_get_resource_count(int id, int resource_type, int *resource_count); /** * @brief Create resource for given resource_type diff --git a/src/monitor/request-handler.c b/src/monitor/request-handler.c index 033ce16..2074fde 100644 --- a/src/monitor/request-handler.c +++ b/src/monitor/request-handler.c @@ -153,7 +153,7 @@ static int handle_request_update_resource(struct request_client *client, char *a return 0; } -static int handle_request_get_resource_count(struct request_client *client, char *args) +static int handle_request_get_resource_count(struct request_client *client, char *args, int *value) { int resource_type; int ret; @@ -174,8 +174,9 @@ static int handle_request_get_resource_count(struct request_client *client, char _E("failed to get resource device count, res:type(%d)\n", resource_type); return ret; } + *value = ret; - return ret; + return 0; } static int handle_request_update_resource_all(struct request_client *client, char *args) @@ -749,7 +750,13 @@ static int handle_request(struct request_client *client, char *request) ret = handle_request_update_resource(client, args); break; case REQUEST_GET_RESOURCE_COUNT: - ret = handle_request_get_resource_count(client, args); + { + int32_t value; + + ret = handle_request_get_resource_count(client, args, &value); + + ADD_RESPONSE(response, buffer_len, "%d$", value); + } break; case REQUEST_UPDATE_RESOURCE_ALL: ret = handle_request_update_resource_all(client, args); diff --git a/tests/integration-test/resource-monitor-tests.cpp b/tests/integration-test/resource-monitor-tests.cpp index 3f2bba1..5bc4189 100644 --- a/tests/integration-test/resource-monitor-tests.cpp +++ b/tests/integration-test/resource-monitor-tests.cpp @@ -76,8 +76,9 @@ TEST_F(ResourceMonitorTest, pass_resource_monitor_get_resource_count_valid) EXPECT_TRUE(id > 0); for (i = 0; i < (int)ARRAY_SIZE(res_types); i++) { - int ret = pass_resource_monitor_get_resource_count(id, res_types[i]); - EXPECT_TRUE(ret >= 0); + int count; + int ret = pass_resource_monitor_get_resource_count(id, res_types[i], &count); + EXPECT_EQ(ret, 0); } int ret = pass_resource_monitor_exit(id); @@ -96,7 +97,8 @@ TEST_F(ResourceMonitorTest, pass_resource_monitor_get_resource_count_invalid) EXPECT_TRUE(id > 0); for (i = 0; i < (int)ARRAY_SIZE(res_types); i++) { - int ret = pass_resource_monitor_get_resource_count(id, res_types[i]); + int count; + int ret = pass_resource_monitor_get_resource_count(id, res_types[i], &count); EXPECT_EQ(ret, 0); } @@ -118,14 +120,15 @@ TEST_F(ResourceMonitorTest, int id = pass_resource_monitor_init(); EXPECT_TRUE(id > 0); - int count = pass_resource_monitor_get_resource_count(id, res_type); - EXPECT_TRUE(count >= 0); + int count; + int ret = pass_resource_monitor_get_resource_count(id, res_type, &count); + EXPECT_EQ(ret, 0); for (i = 0; i < count; i++) { int res_id = pass_resource_monitor_create_resource(id, res_type); EXPECT_TRUE(res_id >= 0); - int ret = pass_resource_monitor_set_resource_ctrl(id, res_id, + ret = pass_resource_monitor_set_resource_ctrl(id, res_id, CPU_CTRL_CLUSTER_ID, i); EXPECT_EQ(ret, 0); @@ -150,7 +153,7 @@ TEST_F(ResourceMonitorTest, EXPECT_EQ(ret, 0); } - int ret = pass_resource_monitor_exit(id); + ret = pass_resource_monitor_exit(id); EXPECT_EQ(ret, 0); } @@ -365,8 +368,8 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_create_resource_and_de res.mon_id = pass_resource_monitor_init(); ASSERT_TRUE(res.mon_id > 0); - res.count = pass_resource_monitor_get_resource_count(res.mon_id, res.type); - EXPECT_TRUE(res.count >= 0); + int ret = pass_resource_monitor_get_resource_count(res.mon_id, res.type, &res.count); + EXPECT_EQ(ret, 0); for (i = 0; i < res.count; i++) { /* Test pass_resource_monitor_create_resource */ @@ -374,7 +377,7 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_create_resource_and_de EXPECT_TRUE(res.res_id >= 0); /* Test pass_resource_monitor_delete_resource */ - int ret = pass_resource_monitor_delete_resource(res.mon_id, res.res_id); + ret = pass_resource_monitor_delete_resource(res.mon_id, res.res_id); EXPECT_EQ(ret, 0); } @@ -389,8 +392,8 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_get_resource_timestamp res.mon_id = pass_resource_monitor_init(); ASSERT_TRUE(res.mon_id > 0); - res.count = pass_resource_monitor_get_resource_count(res.mon_id, res.type); - EXPECT_TRUE(res.count >= 0); + int ret = pass_resource_monitor_get_resource_count(res.mon_id, res.type, &res.count); + EXPECT_EQ(ret, 0); for (i = 0; i < res.count; i++) { int64_t start, end; @@ -399,7 +402,7 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_get_resource_timestamp EXPECT_TRUE(res.res_id >= 0); /* Test pass_resource_monitor_get_resource_timestamp */ - int ret = pass_resource_monitor_get_resource_timestamp( + ret = pass_resource_monitor_get_resource_timestamp( res.mon_id, res.res_id, &start, &end); EXPECT_EQ(ret, 0); @@ -419,15 +422,15 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_set_resource_ctrl) res.mon_id = pass_resource_monitor_init(); ASSERT_TRUE(res.mon_id > 0); - res.count = pass_resource_monitor_get_resource_count(res.mon_id, res.type); - EXPECT_TRUE(res.count >= 0); + int ret = pass_resource_monitor_get_resource_count(res.mon_id, res.type, &res.count); + EXPECT_EQ(ret, 0); for (i = 0; i < res.count; i++) { res.res_id = pass_resource_monitor_create_resource(res.mon_id, res.type); EXPECT_TRUE(res.res_id >= 0); /* Test pass_resource_monitor_set_resource_ctrl */ - int ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id, + ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id, res.ctrl_id, i); if (res.ctrl_id > 0) EXPECT_EQ(ret, 0); @@ -438,7 +441,7 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_set_resource_ctrl) EXPECT_EQ(ret, 0); } - int ret = pass_resource_monitor_exit(res.mon_id); + ret = pass_resource_monitor_exit(res.mon_id); EXPECT_EQ(ret, 0); } @@ -488,8 +491,8 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_set_resource_attr) res.mon_id = pass_resource_monitor_init(); ASSERT_TRUE(res.mon_id > 0); - res.count = pass_resource_monitor_get_resource_count(res.mon_id, res.type); - EXPECT_TRUE(res.count >= 0); + int ret = pass_resource_monitor_get_resource_count(res.mon_id, res.type, &res.count); + EXPECT_EQ(ret, 0); for (i = 0; i < res.count; i++) { res.res_id = pass_resource_monitor_create_resource(res.mon_id, res.type); @@ -499,7 +502,7 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_set_resource_attr) * Test both pass_resource_monitor_set_resource_attr * and pass_resource_monitor_is_resource_attr_supported * */ - int ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id, + ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id, res.ctrl_id, i); if (res.ctrl_id > 0) EXPECT_EQ(ret, 0); @@ -516,7 +519,7 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_set_resource_attr) EXPECT_EQ(ret, 0); } - int ret = pass_resource_monitor_exit(res.mon_id); + ret = pass_resource_monitor_exit(res.mon_id); EXPECT_EQ(ret, 0); } @@ -528,14 +531,14 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_unset_resource_attr_va res.mon_id = pass_resource_monitor_init(); ASSERT_TRUE(res.mon_id > 0); - res.count = pass_resource_monitor_get_resource_count(res.mon_id, res.type); - EXPECT_TRUE(res.count >= 0); + int ret = pass_resource_monitor_get_resource_count(res.mon_id, res.type, &res.count); + EXPECT_EQ(ret, 0); for (i = 0; i < res.count; i++) { res.res_id = pass_resource_monitor_create_resource(res.mon_id, res.type); EXPECT_TRUE(res.res_id >= 0); - int ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id, + ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id, res.ctrl_id, i); if (res.ctrl_id > 0) EXPECT_EQ(ret, 0); @@ -559,7 +562,7 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_unset_resource_attr_va EXPECT_EQ(ret, 0); } - int ret = pass_resource_monitor_exit(res.mon_id); + ret = pass_resource_monitor_exit(res.mon_id); EXPECT_EQ(ret, 0); } @@ -571,14 +574,14 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_unset_resource_attr_in res.mon_id = pass_resource_monitor_init(); ASSERT_TRUE(res.mon_id > 0); - res.count = pass_resource_monitor_get_resource_count(res.mon_id, res.type); - EXPECT_TRUE(res.count >= 0); + int ret = pass_resource_monitor_get_resource_count(res.mon_id, res.type, &res.count); + EXPECT_EQ(ret, 0); for (i = 0; i < res.count; i++) { res.res_id = pass_resource_monitor_create_resource(res.mon_id, res.type); EXPECT_TRUE(res.res_id >= 0); - int ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id, + ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id, res.ctrl_id, i); if (res.ctrl_id > 0) EXPECT_EQ(ret, 0); @@ -601,7 +604,7 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_unset_resource_attr_in EXPECT_EQ(ret, 0); } - int ret = pass_resource_monitor_exit(res.mon_id); + ret = pass_resource_monitor_exit(res.mon_id); EXPECT_EQ(ret, 0); } @@ -738,14 +741,14 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_get_value) res.mon_id = pass_resource_monitor_init(); ASSERT_TRUE(res.mon_id > 0); - res.count = pass_resource_monitor_get_resource_count(res.mon_id, res.type); - EXPECT_TRUE(res.count >= 0); + int ret = pass_resource_monitor_get_resource_count(res.mon_id, res.type, &res.count); + EXPECT_EQ(ret, 0); for (i = 0; i < res.count; i++) { res.res_id = pass_resource_monitor_create_resource(res.mon_id, res.type); EXPECT_TRUE(res.res_id >= 0); - int ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id, + ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id, res.ctrl_id, i); if (res.ctrl_id > 0) EXPECT_EQ(ret, 0); @@ -775,7 +778,7 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_get_value) EXPECT_EQ(ret, 0); } - int ret = pass_resource_monitor_exit(res.mon_id); + ret = pass_resource_monitor_exit(res.mon_id); EXPECT_EQ(ret, 0); } diff --git a/tools/resource-monitor/resource-monitor.c b/tools/resource-monitor/resource-monitor.c index 0147aaf..fe2675a 100644 --- a/tools/resource-monitor/resource-monitor.c +++ b/tools/resource-monitor/resource-monitor.c @@ -445,7 +445,7 @@ static void resource_monitor_exit(int signal) static int resource_monitor_init(void) { - int id, i, j, count; + int id, i, j, count, ret; /* 1. Initialize resource-monitor */ id = pass_resource_monitor_init(); @@ -453,10 +453,13 @@ static int resource_monitor_init(void) /* 2. Get resource count */ for (i = 0; i < ARRAY_SIZE(g_resource_type); i++) { - if (g_resource_type[i].res_count) + if (g_resource_type[i].res_count) { count = g_resource_type[i].res_count; - else - count = pass_resource_monitor_get_resource_count(id, g_resource_type[i].type); + } else { + ret = pass_resource_monitor_get_resource_count(id, g_resource_type[i].type, &count); + if (ret < 0) + continue; + } if (g_resource_type[i].ctrl_val < 0) continue; -- 2.7.4 From afefb9aafdcb6a6fd5a695e7e08f268a99a4d05d Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 9 Aug 2022 03:46:42 +0900 Subject: [PATCH 08/16] util: resource: Add resource flag to express the specific features Each resource are able to have the non-common features. The resource flag will be used to indicate the characteristics of resource. - RESOURCE_FLAG_COUNT_ONLY_ONE : Some resource's resource count is only one on all board such as system and memory resources. Add this flag when want to return 1 as resource count. - RESOURCE_FLAG_PROCESS : process and process-group are not physical resource like CPU/GPU/Memory. Sometimes, it should be handled by the different handling. In order to separate out them, use this flag. Change-Id: Ic7df2cae2105b14382c0f084c30fbbcde5efdac4 Signed-off-by: Chanwoo Choi --- include/util/resource.h | 14 ++++++++ src/resource/resource-memory.c | 1 + src/resource/resource-process-group.c | 1 + src/resource/resource-process.c | 1 + src/resource/resource-system.c | 1 + src/util/resource.c | 39 +++++++++++++++-------- tests/integration-test/resource-monitor-tests.cpp | 6 ++-- tools/resource-monitor/resource-monitor.c | 1 - 8 files changed, 47 insertions(+), 17 deletions(-) diff --git a/include/util/resource.h b/include/util/resource.h index 95cd10b..888943e 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -25,6 +25,19 @@ #include #include "common.h" +/* Resource flags */ +/* + * This flags indicates that the resource has the only one resource count + * such as system/memory resources. + */ +#define RESOURCE_FLAG_COUNT_ONLY_ONE BIT(0) + +/* + * This flag incidates that resource is either process or process-group + * and is not physical h/w resource. + */ +#define RESOURCE_FLAG_PROCESS BIT(1) + struct resource; struct resource_attribute; @@ -91,6 +104,7 @@ struct resource_driver_ops { struct resource_driver { const char *name; const int type; + const u_int64_t flag; const int num_attrs; const struct resource_attribute *attrs; const int num_ctrls; diff --git a/src/resource/resource-memory.c b/src/resource/resource-memory.c index a9218d2..c3e89d7 100644 --- a/src/resource/resource-memory.c +++ b/src/resource/resource-memory.c @@ -194,6 +194,7 @@ static const struct resource_attribute memory_attrs[] = { static const struct resource_driver memory_resource_driver = { .name = "MEMORY", .type = RESOURCE_TYPE_MEMORY, + .flag = RESOURCE_FLAG_COUNT_ONLY_ONE, .attrs = memory_attrs, .num_attrs = ARRAY_SIZE(memory_attrs), }; diff --git a/src/resource/resource-process-group.c b/src/resource/resource-process-group.c index a8a0f41..0ee9d90 100644 --- a/src/resource/resource-process-group.c +++ b/src/resource/resource-process-group.c @@ -693,6 +693,7 @@ static void process_group_exit(struct resource *res) static const struct resource_driver process_group_driver = { .name = "PROCESS_GROUP", .type = RESOURCE_TYPE_PROCESS_GROUP, + .flag = RESOURCE_FLAG_PROCESS, .attrs = process_group_attrs, .num_attrs = ARRAY_SIZE(process_group_attrs), .ctrls = process_group_ctrls, diff --git a/src/resource/resource-process.c b/src/resource/resource-process.c index 0c00e04..633fc78 100644 --- a/src/resource/resource-process.c +++ b/src/resource/resource-process.c @@ -486,6 +486,7 @@ static void process_exit(struct resource *res) static const struct resource_driver process_resource_driver = { .name = "PROCESS", .type = RESOURCE_TYPE_PROCESS, + .flag = RESOURCE_FLAG_PROCESS, .attrs = process_attrs, .num_attrs = ARRAY_SIZE(process_attrs), .ctrls = process_ctrls, diff --git a/src/resource/resource-system.c b/src/resource/resource-system.c index d45ccae..dcbb343 100644 --- a/src/resource/resource-system.c +++ b/src/resource/resource-system.c @@ -320,6 +320,7 @@ static int system_driver_prepare_update(struct resource *res) static const struct resource_driver system_resource_driver = { .name = "SYSTEM", .type = RESOURCE_TYPE_SYSTEM, + .flag = RESOURCE_FLAG_COUNT_ONLY_ONE, .attrs = system_attrs, .num_attrs = ARRAY_SIZE(system_attrs), .ops = { diff --git a/src/util/resource.c b/src/util/resource.c index b71e67f..59f22aa 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -63,6 +63,18 @@ static gint __compare_resource_type(gconstpointer data, gconstpointer input) return -1; } +static const struct resource_driver *find_resource_driver(int resource_type) +{ + GList *node; + + node = g_list_find_custom(g_resource_driver_head, + &resource_type, __compare_resource_type); + + if (!node) + return NULL; + return (struct resource_driver *)node->data; +} + void add_resource_driver(const struct resource_driver *driver) { if (!driver) @@ -90,6 +102,7 @@ int get_resource_device_count(int resource_type) { GList *node; struct resource_device *device; + const struct resource_driver *driver; int count = 0; for (node = g_resource_device_head; node != NULL; node = node->next) { @@ -98,7 +111,19 @@ int get_resource_device_count(int resource_type) count++; } - return count; + if (count > 0) + return count; + + driver = find_resource_driver(resource_type); + if (!driver) + return -EINVAL; + + if (driver->flag & RESOURCE_FLAG_COUNT_ONLY_ONE) + return 1; + else if (driver->flag & RESOURCE_FLAG_PROCESS) + return -EINVAL; + + return 0; } const struct resource_device *find_resource_device(int resource_type, @@ -142,18 +167,6 @@ void remove_resource_device(struct resource_device *device) g_list_remove(g_resource_device_head, (gpointer)device); } -static const struct resource_driver *find_resource_driver(int resource_type) -{ - GList *node; - - node = g_list_find_custom(g_resource_driver_head, - &resource_type, __compare_resource_type); - - if (!node) - return NULL; - return (struct resource_driver *)node->data; -} - static void do_delete_resource(struct resource *resource) { if (!resource->name) diff --git a/tests/integration-test/resource-monitor-tests.cpp b/tests/integration-test/resource-monitor-tests.cpp index 5bc4189..8c87b27 100644 --- a/tests/integration-test/resource-monitor-tests.cpp +++ b/tests/integration-test/resource-monitor-tests.cpp @@ -64,10 +64,8 @@ TEST_F(ResourceMonitorTest, pass_resource_monitor_get_resource_count_valid) RESOURCE_TYPE_GPU, RESOURCE_TYPE_MEMORY, RESOURCE_TYPE_BATTERY, - RESOURCE_TYPE_PROCESS, RESOURCE_TYPE_DISPLAY, RESOURCE_TYPE_SYSTEM, - RESOURCE_TYPE_PROCESS_GROUP, RESOURCE_TYPE_DISK, RESOURCE_TYPE_NETWORK, }; @@ -91,6 +89,8 @@ TEST_F(ResourceMonitorTest, pass_resource_monitor_get_resource_count_invalid) int res_types[] = { RESOURCE_TYPE_UNKNOWN, RESOURCE_TYPE_NONSTANDARD, + RESOURCE_TYPE_PROCESS, + RESOURCE_TYPE_PROCESS_GROUP, }; int id = pass_resource_monitor_init(); @@ -99,7 +99,7 @@ TEST_F(ResourceMonitorTest, pass_resource_monitor_get_resource_count_invalid) for (i = 0; i < (int)ARRAY_SIZE(res_types); i++) { int count; int ret = pass_resource_monitor_get_resource_count(id, res_types[i], &count); - EXPECT_EQ(ret, 0); + EXPECT_NE(ret, 0); } int ret = pass_resource_monitor_exit(id); diff --git a/tools/resource-monitor/resource-monitor.c b/tools/resource-monitor/resource-monitor.c index fe2675a..558b5e2 100644 --- a/tools/resource-monitor/resource-monitor.c +++ b/tools/resource-monitor/resource-monitor.c @@ -198,7 +198,6 @@ struct __resource_type { .ctrl_id = 0, .attrs = system_attrs, .num_attrs = ARRAY_SIZE(system_attrs), - .res_count = 1, }, { .type = RESOURCE_TYPE_MEMORY, .ctrl_id = 0, -- 2.7.4 From 826ca1bdc99fd4b22f586c7498b9c88fe53cf5a1 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 20 Jul 2022 17:53:37 +0900 Subject: [PATCH 09/16] lib: resource-monitor: Add pass_resource_monitor_is_resource_attr_set Provide pass_resource_monitor_is_resource_attr_set function to check whether some attributes are set or not. And fix the comment of pass_resource_monitor_is_resource_attr_supported. Change-Id: I3b1372ecc1138d2244da66e79745ca6454ff67eb Signed-off-by: Chanwoo Choi --- include/util/request.h | 1 + lib/resource-monitor/resource-monitor.c | 16 ++++++ lib/resource-monitor/resource-monitor.h | 13 ++++- src/monitor/request-handler.c | 4 ++ tests/integration-test/resource-monitor-tests.cpp | 59 +++++++++++++++++++++++ 5 files changed, 91 insertions(+), 2 deletions(-) diff --git a/include/util/request.h b/include/util/request.h index 6f7bfa7..f33640b 100644 --- a/include/util/request.h +++ b/include/util/request.h @@ -46,6 +46,7 @@ enum { REQUEST_GET_VALUE_ARRAY, REQUEST_GET_RESOURCE_TS, REQUEST_GET_RESOURCE_LIST_JSON, + REQUEST_IS_RESOURCE_ATTR_SET, REQUEST_MAX, }; diff --git a/lib/resource-monitor/resource-monitor.c b/lib/resource-monitor/resource-monitor.c index 62e42cf..b3c22c1 100644 --- a/lib/resource-monitor/resource-monitor.c +++ b/lib/resource-monitor/resource-monitor.c @@ -154,6 +154,7 @@ static inline int handle_request(struct request_data *data) break; case REQUEST_SET_RESOURCE_ATTR: case REQUEST_UNSET_RESOURCE_ATTR: + case REQUEST_IS_RESOURCE_ATTR_SET: buffer_len = sprintf(buffer, "%d$%d$%"PRIu64, data->request, data->resource_id, data->attr_mask); break; @@ -422,6 +423,21 @@ bool pass_resource_monitor_is_resource_attr_supported(int id, int resource_id, u } EXPORT +bool pass_resource_monitor_is_resource_attr_set(int id, int resource_id, u_int64_t attr_mask) +{ + struct request_data request = { + .request = REQUEST_IS_RESOURCE_ATTR_SET, + .client_id = id, + .resource_id = resource_id, + .attr_mask = attr_mask, + }; + int ret; + + ret = handle_request(&request); + return (ret < 0) ? false : (bool)ret; +} + +EXPORT int pass_resource_monitor_update(int id) { struct request_data request = { diff --git a/lib/resource-monitor/resource-monitor.h b/lib/resource-monitor/resource-monitor.h index 97b11e0..b32c452 100644 --- a/lib/resource-monitor/resource-monitor.h +++ b/lib/resource-monitor/resource-monitor.h @@ -232,11 +232,20 @@ int pass_resource_monitor_set_resource_attr(int id, int resource_id, u_int64_t a int pass_resource_monitor_unset_resource_attr(int id, int resource_id, u_int64_t attr_mask); /** - * @brief Check whether a resouce attribute is supported or not + * @brief Check whether a resource attributes are interested or not + * @param[in] Resource monitor id + * @param[in] Resource id + * @param[in] Attribute mask including the various attributes + * @return @c true on success, otherwise false + */ +bool pass_resource_monitor_is_resource_attr_set(int id, int resource_id, u_int64_t attr_mask); + +/** + * @brief Check whether a resource attribute is supported or not * @param[in] Resource monitor id * @param[in] Resource id * @param[in] Resource attribute id - * @return @c 0 on success, otherwise a negative error value + * @return @c true on success, otherwise false */ bool pass_resource_monitor_is_resource_attr_supported(int id, int resource_id, u_int64_t attr_id); diff --git a/src/monitor/request-handler.c b/src/monitor/request-handler.c index 2074fde..2497a15 100644 --- a/src/monitor/request-handler.c +++ b/src/monitor/request-handler.c @@ -240,6 +240,9 @@ static int handle_request_set_resource_attr(struct request_client *client, char client->socket_fd, get_resource_name(res), resource_id); break; + case REQUEST_IS_RESOURCE_ATTR_SET: + ret = (int)is_resource_attr_interested(res, interest_masks); + break; default: return -EINVAL; } @@ -766,6 +769,7 @@ static int handle_request(struct request_client *client, char *request) break; case REQUEST_SET_RESOURCE_ATTR: case REQUEST_UNSET_RESOURCE_ATTR: + case REQUEST_IS_RESOURCE_ATTR_SET: ret = handle_request_set_resource_attr(client, args, request_type); break; case REQUEST_IS_RESOURCE_ATTR_SUPPORTED: diff --git a/tests/integration-test/resource-monitor-tests.cpp b/tests/integration-test/resource-monitor-tests.cpp index 8c87b27..9435295 100644 --- a/tests/integration-test/resource-monitor-tests.cpp +++ b/tests/integration-test/resource-monitor-tests.cpp @@ -483,6 +483,28 @@ static int __pass_resource_monitor_unset_resource_attr(int mon_id, int res_id, i return ret; } +static bool __pass_resource_monitor_is_resource_attr_set(int mon_id, int res_id, int num_attrs, + std::vector attrs) +{ + int i, ret; + u_int64_t mask = 0; + + for (i = 0; i < num_attrs; i++) { + bool supported = pass_resource_monitor_is_resource_attr_supported( + mon_id, res_id, attrs[i].attr_id); + if (supported) + mask |= attrs[i].attr_id; + } + + ret = pass_resource_monitor_set_resource_attr(mon_id, res_id, mask); + EXPECT_EQ(ret, 0); + + bool set = pass_resource_monitor_is_resource_attr_set(mon_id, res_id, mask); + EXPECT_EQ(set, true); + + return set; +} + TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_set_resource_attr) { auto res = GetParam(); @@ -608,6 +630,43 @@ TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_unset_resource_attr_in EXPECT_EQ(ret, 0); } +TEST_P(PhysicalResourceMonitorTest, pass_resource_monitor_is_resource_attr_set) +{ + auto res = GetParam(); + int i; + + res.mon_id = pass_resource_monitor_init(); + ASSERT_TRUE(res.mon_id > 0); + + int ret = pass_resource_monitor_get_resource_count(res.mon_id, res.type, &res.count); + EXPECT_EQ(ret, 0); + + for (i = 0; i < res.count; i++) { + res.res_id = pass_resource_monitor_create_resource(res.mon_id, res.type); + EXPECT_TRUE(res.res_id >= 0); + + ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id, + res.ctrl_id, i); + if (res.ctrl_id > 0) + EXPECT_EQ(ret, 0); + else + EXPECT_NE(ret, 0); + + /* Test pass_resource_monitor_is_resource_attr_set */ + bool set = __pass_resource_monitor_is_resource_attr_set(res.mon_id, + res.res_id, + res.num_attrs, + res.attrs); + EXPECT_EQ(set, true); + + ret = pass_resource_monitor_delete_resource(res.mon_id, res.res_id); + EXPECT_EQ(ret, 0); + } + + ret = pass_resource_monitor_exit(res.mon_id); + EXPECT_EQ(ret, 0); +} + static int __pass_resource_monitor_get_value(int mon_id, int res_id, int num_attrs, std::vector attrs) { -- 2.7.4 From dd27cae217fd2390e908f3048a4d6aa558097a83 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 9 Aug 2022 04:41:13 +0900 Subject: [PATCH 10/16] lib: resource-monitor: Add missing request for the readability Add missing request for the readability to switch statement to improve the readability when handling the request. Change-Id: I1b322bd30d4db913fd438394089e95b4716133a6 Signed-off-by: Chanwoo Choi --- lib/resource-monitor/resource-monitor.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/resource-monitor/resource-monitor.c b/lib/resource-monitor/resource-monitor.c index b3c22c1..938c9dc 100644 --- a/lib/resource-monitor/resource-monitor.c +++ b/lib/resource-monitor/resource-monitor.c @@ -227,10 +227,24 @@ static inline int handle_request(struct request_data *data) &data->ts_start, &data->ts_end, &response_ret) < 4) ret =-EINVAL; break; - default: + case REQUEST_UPDATE_RESOURCE_ALL: + case REQUEST_UPDATE_RESOURCE: + case REQUEST_DELETE_RESOURCE: + case REQUEST_CREATE_RESOURCE: + case REQUEST_SET_RESOURCE_CTRL: + case REQUEST_IS_RESOURCE_ATTR_SUPPORTED: + case REQUEST_SET_RESOURCE_ATTR: + case REQUEST_UNSET_RESOURCE_ATTR: + case REQUEST_IS_RESOURCE_ATTR_SET: if (sscanf(buffer, "%d$%d", &response_req, &response_ret) < 2) ret = -EINVAL; break; + default: + _E("[libpass] Unknown request type, client(%d) | request(%35s) | res,id(%d)type(%d) | ctrl,id(%"PRId64")val(%d) ", + data->client_id, request_name[data->request], + data->resource_id, data->resource_type, + data->ctrl_id, data->ctrl_value); + return -EINVAL; } if (ret < 0) { -- 2.7.4 From 74ba69b58160a7f9bfd2bd260d5530e94ffb3f01 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 9 Aug 2022 15:00:23 +0900 Subject: [PATCH 11/16] tools: resource-monitor: Add missing BATTERY_ATTR_ONLINE attribute Change-Id: I37cea2d7cfd3b5f3b4478d152c1fa84682da021e Signed-off-by: Chanwoo Choi --- tools/resource-monitor/resource-monitor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/resource-monitor/resource-monitor.c b/tools/resource-monitor/resource-monitor.c index 558b5e2..f89a60d 100644 --- a/tools/resource-monitor/resource-monitor.c +++ b/tools/resource-monitor/resource-monitor.c @@ -99,6 +99,7 @@ static struct resource_attr_data battery_attrs[] = { { .id = BATTERY_ATTR_VOLTAGE_NOW, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_VOLTAGE_NOW", .unit = "uV", .desc = "Battery voltage figure", }, { .id = BATTERY_ATTR_CURRENT_NOW, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_CURRENT_NOW", .unit = "uA", .desc = "Battery current figure", }, { .id = BATTERY_ATTR_PRESENT, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_PRESENT", .unit = "", .desc = "Battery connected status", }, + { .id = BATTERY_ATTR_ONLINE, .type = DATA_TYPE_INT, .name = "BATTERY_ATTR_ONLINE", .unit = "", .desc = "Battery charger connector status", }, }; static struct resource_attr_data display_attrs[] = { -- 2.7.4 From 441c327e698ece05465bdc884af59f9df9805419 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Thu, 11 Aug 2022 16:29:49 +0900 Subject: [PATCH 12/16] tests: resource-monitor-tests: Add missing array data type if DATA_TYPE_ARRAY Change-Id: I3606a29597ba9cd16c47defba5b99055b25b5d22 Signed-off-by: Chanwoo Choi --- tests/integration-test/resource-monitor-tests.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integration-test/resource-monitor-tests.cpp b/tests/integration-test/resource-monitor-tests.cpp index 9435295..2901648 100644 --- a/tests/integration-test/resource-monitor-tests.cpp +++ b/tests/integration-test/resource-monitor-tests.cpp @@ -320,9 +320,9 @@ INSTANTIATE_TEST_CASE_P (ResourceMonitorTest, PhysicalResourceMonitorTest, { .attr_id = SYSTEM_ATTR_CPU_UTIL, .attr_type = DATA_TYPE_DOUBLE, }, { .attr_id = SYSTEM_ATTR_CPU_USER_UTIL, .attr_type = DATA_TYPE_DOUBLE, }, { .attr_id = SYSTEM_ATTR_CPU_SYS_UTIL, .attr_type = DATA_TYPE_DOUBLE, }, - { .attr_id = SYSTEM_ATTR_PER_CPU_UTIL, .attr_type = DATA_TYPE_ARRAY, }, - { .attr_id = SYSTEM_ATTR_PER_CPU_USER_UTIL, .attr_type = DATA_TYPE_ARRAY, }, - { .attr_id = SYSTEM_ATTR_PER_CPU_SYS_UTIL, .attr_type = DATA_TYPE_ARRAY, }, + { .attr_id = SYSTEM_ATTR_PER_CPU_UTIL, .attr_type = DATA_TYPE_ARRAY, .array_type = DATA_TYPE_DOUBLE, }, + { .attr_id = SYSTEM_ATTR_PER_CPU_USER_UTIL, .attr_type = DATA_TYPE_ARRAY, .array_type = DATA_TYPE_DOUBLE, }, + { .attr_id = SYSTEM_ATTR_PER_CPU_SYS_UTIL, .attr_type = DATA_TYPE_ARRAY, .array_type = DATA_TYPE_DOUBLE, }, { .attr_id = SYSTEM_ATTR_POSSIBLE_CPU, .attr_type = DATA_TYPE_INT, }, { .attr_id = SYSTEM_ATTR_ONLINE_CPU, .attr_type = DATA_TYPE_INT, }, } -- 2.7.4 From 62cdb7e9f1db48d40361c6f0640ca1ea2df235c6 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Fri, 12 Aug 2022 11:48:03 +0900 Subject: [PATCH 13/16] PASS v2.0.0 Changes from v1.2.0 1. Add new resource-monitor framework with daemon and various resource drivers 2. Provide libpass-resource-monitor library for resource monitoring 3. Provide resource-monitor tool and resource-monitor-tests Change-Id: I5d6ccbeb08d29a15181e2c74112b509f99769c58 Signed-off-by: Chanwoo Choi --- packaging/pass.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/pass.spec b/packaging/pass.spec index e50b60f..bde3967 100644 --- a/packaging/pass.spec +++ b/packaging/pass.spec @@ -7,7 +7,7 @@ Name: %{daemon_name} Summary: Power Aware System Service -Version: 1.2.0 +Version: 2.0.0 Release: 1 Group: System/Kernel License: Apache-2.0 -- 2.7.4 From a7b9c03b96f647e4d3c1939fba9ac0ed78dd93fb Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Wed, 17 Aug 2022 15:31:53 +0900 Subject: [PATCH 14/16] util: kernel: Add check whether taskstats is supported Since taskstats has various version by kernel, handling it should be taken by considering versions. However, some task accounting is not supported by older kernel, we should check whether it is supported or not. This adds check procedure into constructor. Change-Id: Ib18f01b1a3060baaba3212fdc728cd7a7ff77849 Signed-off-by: Dongwoo Lee --- include/util/kernel.h | 1 + src/util/kernel.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/util/kernel.h b/include/util/kernel.h index 12ae6e9..a1d13d9 100644 --- a/include/util/kernel.h +++ b/include/util/kernel.h @@ -69,4 +69,5 @@ int kernel_get_thread_group_taskstats(struct taskstats *stats, pid_t tgid, bool int kernel_get_thread_group_map_info(struct proc_map_info *map_info, pid_t tgid, bool include_gpu_mem); bool kernel_check_gpu_support(void); +bool kernel_check_taskstat_support(void); #endif diff --git a/src/util/kernel.c b/src/util/kernel.c index 0baaf4a..40fd869 100644 --- a/src/util/kernel.c +++ b/src/util/kernel.c @@ -31,6 +31,7 @@ static int have_smaps_rollup; static bool need_tgid_taskstat_add_time; static struct gpu_mem_node *gpu_mem_node; +static bool taskstat_support; static int __get_cpu_num(char *path) { @@ -501,14 +502,25 @@ bool kernel_check_gpu_support(void) return !!gpu_mem_node; } +bool kernel_check_taskstat_support(void) +{ + return taskstat_support; +} + static void __CONSTRUCTOR__ kernel_init(void) { struct taskstats self; + int ret; have_smaps_rollup = !access("/proc/self/smaps_rollup", R_OK); gpu_mem_node = get_system_gpu_mem_node(); - kernel_get_thread_group_taskstats(&self, getpid(), false); + ret = kernel_get_thread_group_taskstats(&self, getpid(), false); + if (ret < 0) { + _I("taskstat is not supported.\n"); + return; + } + taskstat_support = true; if (self.ac_etime == 0) need_tgid_taskstat_add_time = true; } -- 2.7.4 From 70b1d1682bcb6bb58d98d9479431d1dc7bfc0bc2 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Wed, 17 Aug 2022 15:33:18 +0900 Subject: [PATCH 15/16] resource: process-group: Handle the case that target cannot support taskstats all attributes in PROCESS_GROUP resource require taskstats, all attributes are mark to unsupported when the target does not support taskstats. Change-Id: I21a36949e34e7cf3fb050694b1cbddd31e954247 Signed-off-by: Dongwoo Lee --- src/resource/resource-process-group.c | 37 +++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/resource/resource-process-group.c b/src/resource/resource-process-group.c index 0ee9d90..f0a9a4d 100644 --- a/src/resource/resource-process-group.c +++ b/src/resource/resource-process-group.c @@ -51,6 +51,7 @@ struct process_group_context { static u_int64_t total_memory; static long jiffy; +static int taskstat_support = -1; static int process_group_get_pid_list(struct resource *res, const struct resource_attribute *attr, @@ -239,10 +240,16 @@ static int process_group_get_disk_attrs(struct resource *res, return 0; } +static bool process_group_check_taskstat_support(struct resource *resource, + const struct resource_attribute *attr) +{ + return !!taskstat_support; +} + static bool process_group_check_gpu_support(struct resource *resource, const struct resource_attribute *attr) { - return kernel_check_gpu_support(); + return !!taskstat_support && kernel_check_gpu_support(); } static const struct resource_attribute process_group_attrs[] = { @@ -252,7 +259,7 @@ static const struct resource_attribute process_group_attrs[] = { .type = DATA_TYPE_ARRAY, .ops = { .get = process_group_get_pid_list, - .is_supported = resource_attr_supported_always, + .is_supported = process_group_check_taskstat_support, }, }, { .name = "PROCESS_GROUP_ATTR_NAME_LIST", @@ -260,7 +267,7 @@ static const struct resource_attribute process_group_attrs[] = { .type = DATA_TYPE_ARRAY, .ops = { .get = process_group_get_name_list, - .is_supported = resource_attr_supported_always, + .is_supported = process_group_check_taskstat_support, }, }, { .name = "PROCESS_GROUP_ATTR_CPU_UTIL", @@ -268,7 +275,7 @@ static const struct resource_attribute process_group_attrs[] = { .type = DATA_TYPE_DOUBLE, .ops = { .get = process_group_get_cpu_util, - .is_supported = resource_attr_supported_always, + .is_supported = process_group_check_taskstat_support, }, }, { .name = "PROCESS_GROUP_ATTR_DISK_READ_PER_SEC", @@ -276,7 +283,7 @@ static const struct resource_attribute process_group_attrs[] = { .type = DATA_TYPE_DOUBLE, .ops = { .get = process_group_get_disk_attrs, - .is_supported = resource_attr_supported_always, + .is_supported = process_group_check_taskstat_support, }, }, { .name = "PROCESS_GROUP_ATTR_DISK_WRITE_PER_SEC", @@ -284,7 +291,7 @@ static const struct resource_attribute process_group_attrs[] = { .type = DATA_TYPE_DOUBLE, .ops = { .get = process_group_get_disk_attrs, - .is_supported = resource_attr_supported_always, + .is_supported = process_group_check_taskstat_support, }, }, { .name = "PROCESS_GROUP_ATTR_MEM_VIRT", @@ -292,7 +299,7 @@ static const struct resource_attribute process_group_attrs[] = { .type = DATA_TYPE_UINT64, .ops = { .get = process_group_get_mem, - .is_supported = resource_attr_supported_always, + .is_supported = process_group_check_taskstat_support, }, }, { .name = "PROCESS_GROUP_ATTR_MEM_RSS", @@ -300,7 +307,7 @@ static const struct resource_attribute process_group_attrs[] = { .type = DATA_TYPE_UINT64, .ops = { .get = process_group_get_mem, - .is_supported = resource_attr_supported_always, + .is_supported = process_group_check_taskstat_support, }, }, { .name = "PROCESS_GROUP_ATTR_MEM_PSS", @@ -308,7 +315,7 @@ static const struct resource_attribute process_group_attrs[] = { .type = DATA_TYPE_UINT64, .ops = { .get = process_group_get_mem, - .is_supported = resource_attr_supported_always, + .is_supported = process_group_check_taskstat_support, }, }, { .name = "PROCESS_GROUP_ATTR_MEM_SWAP", @@ -316,7 +323,7 @@ static const struct resource_attribute process_group_attrs[] = { .type = DATA_TYPE_UINT64, .ops = { .get = process_group_get_mem, - .is_supported = resource_attr_supported_always, + .is_supported = process_group_check_taskstat_support, }, }, { .name = "PROCESS_GROUP_ATTR_MEM_SWAP_PSS", @@ -324,7 +331,7 @@ static const struct resource_attribute process_group_attrs[] = { .type = DATA_TYPE_UINT64, .ops = { .get = process_group_get_mem, - .is_supported = resource_attr_supported_always, + .is_supported = process_group_check_taskstat_support, }, }, { .name = "PROCESS_GROUP_ATTR_MEM_GPU", @@ -355,7 +362,7 @@ static int process_group_setup_root_pid(struct resource *res, target_pid = (int)(intptr_t)data; - if (target_pid < 0) { + if (target_pid < 0 || !taskstat_support) { ctx->pid = -1; return 0; } @@ -519,6 +526,9 @@ static int process_group_prepare_update(struct resource *res) if (!ctx) return -EINVAL; + if (!taskstat_support) + return 0; + task_dir = opendir(PROC_DIR_PATH); if (!task_dir) return -ESRCH; @@ -644,6 +654,9 @@ static int process_group_init(struct resource *res) struct process_group_context *ctx; int ret; + if (taskstat_support < 0) + taskstat_support = (int)kernel_check_taskstat_support(); + if (jiffy == 0) { /* get system USER_HZ at once */ jiffy = sysconf(_SC_CLK_TCK); -- 2.7.4 From 86164a3a81ee70908d38b8120448030ac316df66 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Wed, 17 Aug 2022 17:42:43 +0900 Subject: [PATCH 16/16] resource: process: Handle the case that target cannot support taskstats Since PROCESS resource has some attributes which require taskstats, those attributes are mark to unsupported or provided by other methods when the target does not support taskstats. Change-Id: I83a0eab243367f59c518d1b1c422b741f3e611bb Signed-off-by: Dongwoo Lee --- src/resource/resource-process.c | 87 ++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 19 deletions(-) diff --git a/src/resource/resource-process.c b/src/resource/resource-process.c index 633fc78..192d91e 100644 --- a/src/resource/resource-process.c +++ b/src/resource/resource-process.c @@ -41,6 +41,7 @@ struct process_context { }; static long jiffy; +static int taskstat_support = -1; static int process_get_cpu_util(struct resource *res, const struct resource_attribute *attr, @@ -194,6 +195,21 @@ static int process_get_context_data(struct resource *res, switch (attr->id) { case PROCESS_ATTR_NAME: + if (!taskstat_support && (strlen(ctx->comm) == 0)) { + char *stat_fields[PROCESS_STAT_FIELD_MAX]; + char buffer[BUFF_MAX]; + int ret, len; + + ret = kernel_get_process_stat_fields(ctx->tgid, buffer, + BUFF_MAX, stat_fields); + if (ret < 0) + break; + + len = strlen(stat_fields[PROCESS_STAT_FIELD_COMM]) - 2/* '(', ')' */; + len = (len < TS_COMM_LEN - 1) ? len : TS_COMM_LEN - 1; + strncpy(ctx->comm, stat_fields[PROCESS_STAT_FIELD_COMM] + 1, len); + } + strncpy((char *)data, ctx->comm, TS_COMM_LEN); break; case PROCESS_ATTR_PGID: @@ -213,6 +229,19 @@ static int process_get_context_data(struct resource *res, *((int *)data) = ctx->pgid; break; case PROCESS_ATTR_PPID: + if (ctx->ppid < 0) { + char *stat_fields[PROCESS_STAT_FIELD_MAX]; + char buffer[BUFF_MAX]; + int ret; + + ret = kernel_get_process_stat_fields(ctx->tgid, buffer, + BUFF_MAX, stat_fields); + if (ret < 0) + break; + + ctx->ppid = atoi(stat_fields[PROCESS_STAT_FIELD_PPID]); + } + *((int *)data) = ctx->ppid; break; } @@ -220,6 +249,12 @@ static int process_get_context_data(struct resource *res, return 0; } +static bool process_check_taskstat_support(struct resource *resource, + const struct resource_attribute *attr) +{ + return !!taskstat_support; +} + static bool process_check_gpu_support(struct resource *resource, const struct resource_attribute *attr) { @@ -233,7 +268,7 @@ static const struct resource_attribute process_attrs[] = { .type = DATA_TYPE_DOUBLE, .ops = { .get = process_get_cpu_util, - .is_supported = resource_attr_supported_always, + .is_supported = process_check_taskstat_support, }, }, { .name = "PROCESS_ATTR_MEM_VIRT", @@ -241,7 +276,7 @@ static const struct resource_attribute process_attrs[] = { .type = DATA_TYPE_UINT64, .ops = { .get = process_get_mem_attrs, - .is_supported = resource_attr_supported_always, + .is_supported = process_check_taskstat_support, }, }, { .name = "PROCESS_ATTR_MEM_RSS", @@ -249,7 +284,7 @@ static const struct resource_attribute process_attrs[] = { .type = DATA_TYPE_UINT64, .ops = { .get = process_get_mem_attrs, - .is_supported = resource_attr_supported_always, + .is_supported = process_check_taskstat_support, }, }, { .name = "PROCESS_ATTR_MEM_RSS_PERCENT", @@ -257,7 +292,7 @@ static const struct resource_attribute process_attrs[] = { .type = DATA_TYPE_DOUBLE, .ops = { .get = process_get_mem_attrs, - .is_supported = resource_attr_supported_always, + .is_supported = process_check_taskstat_support, }, }, { .name = "PROCESS_ATTR_DISK_READ_PER_SEC", @@ -265,7 +300,7 @@ static const struct resource_attribute process_attrs[] = { .type = DATA_TYPE_DOUBLE, .ops = { .get = process_get_disk_attrs, - .is_supported = resource_attr_supported_always, + .is_supported = process_check_taskstat_support, }, }, { .name = "PROCESS_ATTR_DISK_WRITE_PER_SEC", @@ -273,7 +308,7 @@ static const struct resource_attribute process_attrs[] = { .type = DATA_TYPE_DOUBLE, .ops = { .get = process_get_disk_attrs, - .is_supported = resource_attr_supported_always, + .is_supported = process_check_taskstat_support, }, }, { .name = "PROCESS_ATTR_NAME", @@ -379,19 +414,29 @@ static int process_setup_tgid(struct resource *res, ctx->prev_total_time = get_total_cpu_time(); /* update initial status */ - ret = kernel_get_thread_group_taskstats(&ctx->curr, ctx->tgid, true); - if (ret < 0) - return ret; + if (taskstat_support) { + ret = kernel_get_thread_group_taskstats(&ctx->curr, ctx->tgid, true); + if (ret < 0) + return ret; + + memcpy(ctx->comm, ctx->curr.ac_comm, strlen(ctx->curr.ac_comm) + 1); + ctx->ppid = ctx->curr.ac_ppid; + } else { + /* + * if taskstat is not supported, comm, pgid and ppid is retrieved + * from procfs status lazily. + * + * ctx->comm is now "\0" so it is treated as not initialized. + */ + ctx->ppid = -1; + } + + ctx->pgid = -1; ret = kernel_get_thread_group_map_info(&ctx->map_info, ctx->tgid, include_gpu_mem); if (ret < 0) return ret; - memcpy(ctx->comm, ctx->curr.ac_comm, strlen(ctx->curr.ac_comm) + 1); - - ctx->pgid = -1; - ctx->ppid = ctx->curr.ac_ppid; - return 0; } @@ -421,11 +466,12 @@ static int process_prepare_update(struct resource *res) include_gpu_mem = is_resource_attr_interested(res, PROCESS_GROUP_ATTR_MEM_GPU); - memcpy(&ctx->prev, &ctx->curr, sizeof(struct taskstats)); - - ret = kernel_get_thread_group_taskstats(&ctx->curr, ctx->tgid, false); - if (ret < 0) - return ret; + if (taskstat_support) { + memcpy(&ctx->prev, &ctx->curr, sizeof(struct taskstats)); + ret = kernel_get_thread_group_taskstats(&ctx->curr, ctx->tgid, false); + if (ret < 0) + return ret; + } ret = kernel_get_thread_group_map_info(&ctx->map_info, ctx->tgid, include_gpu_mem); if (ret < 0) @@ -453,6 +499,9 @@ static int process_init(struct resource *res) return -EINVAL; } + if (taskstat_support < 0) + taskstat_support = (int)kernel_check_taskstat_support(); + ctx = calloc(1, sizeof(struct process_context)); if (!ctx) return -ENOMEM; -- 2.7.4