From a193fd0fb47a37e666c38f8eec46ebad594f5143 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Fri, 8 Apr 2022 12:04:08 +0900 Subject: [PATCH] monitor: resource: Add timestamp support To provide timeline information of resource update, now provides timestamp as start and end time of update. It is included in resource json as "res_ts" with "start" and "end" object, and it also can be retrieved with following new libpass function: - pass_resource_monitor_get_resource_timestamp() Change-Id: Iad2cf8bb1d1100f4ded44ce5e19aeb119c65575e Signed-off-by: Dongwoo Lee --- include/util/request.h | 1 + include/util/resource.h | 15 ++++++++++++- lib/resource-monitor/resource-monitor.c | 32 ++++++++++++++++++++++++++++ lib/resource-monitor/resource-monitor.h | 11 ++++++++++ src/monitor/request-handler.c | 37 +++++++++++++++++++++++++++++++++ src/util/resource.c | 17 +++++++++++++++ 6 files changed, 112 insertions(+), 1 deletion(-) diff --git a/include/util/request.h b/include/util/request.h index fcee614..44d2047 100644 --- a/include/util/request.h +++ b/include/util/request.h @@ -44,6 +44,7 @@ enum { REQUEST_GET_VALUE_DOUBLE, REQUEST_GET_VALUE_STRING, REQUEST_GET_VALUE_ARRAY, + REQUEST_GET_RESOURCE_TS, REQUEST_MAX, }; diff --git a/include/util/resource.h b/include/util/resource.h index 71d756f..97a1b93 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -20,6 +20,7 @@ #ifndef __RESOURCE_H__ #define __RESOURCE_H__ +#include #include #include #include "common.h" @@ -136,6 +137,9 @@ struct resource { const struct resource_control *ctrls; u_int64_t attr_interest; u_int64_t attr_supported; + + int64_t ts_start; + int64_t ts_end; }; #define RESOURCE_DRIVER_REGISTER(resource_driver) \ @@ -180,8 +184,9 @@ resource_attr_supported_always(const struct resource *resource, } int get_resource_attrs_json(struct resource *resource, char **json_string); - int get_resource_attr_json(struct resource *resource, u_int64_t attr_id, char **json_string); +int get_resource_list_json(char **json_string); + int get_resource_attr_int(struct resource *resource, u_int64_t attr_id, int32_t *data); int get_resource_attr_int64(struct resource *resource, u_int64_t attr_id, int64_t *data); int get_resource_attr_uint(struct resource *resource, u_int64_t attr_id, u_int32_t *data); @@ -194,4 +199,12 @@ int get_resource_attr_ptr(struct resource *resource, u_int64_t attr_id, void **d int set_resource_attr_interest(struct resource *resource, u_int64_t interest_mask); int unset_resource_attr_interest(struct resource *resource, u_int64_t interest_mask); + +inline __attribute__((always_inline)) int64_t get_time_now(void) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + return (int64_t)tv.tv_sec * 1000000 + (int64_t)tv.tv_usec; +} #endif diff --git a/lib/resource-monitor/resource-monitor.c b/lib/resource-monitor/resource-monitor.c index af25357..02361f9 100644 --- a/lib/resource-monitor/resource-monitor.c +++ b/lib/resource-monitor/resource-monitor.c @@ -924,3 +924,35 @@ int pass_resource_monitor_get_array_string(int id, int res_id, u_int64_t attr_id { return pass_resource_monitor_get_array(id, res_id, attr_id, DATA_TYPE_STRING, (void **)array, length); } + +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; + 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) < 3) + return -EINVAL; + + if (response_req != REQUEST_GET_VALUE_INT64) { + _E("[libpass] wrong response"); + return -EINVAL; + } + + return ret; +} diff --git a/lib/resource-monitor/resource-monitor.h b/lib/resource-monitor/resource-monitor.h index 515ec10..c943dc4 100644 --- a/lib/resource-monitor/resource-monitor.h +++ b/lib/resource-monitor/resource-monitor.h @@ -266,6 +266,17 @@ int pass_resource_monitor_get_array_uint64(int id, int res_id, u_int64_t attr, u int pass_resource_monitor_get_array_double(int id, int res_id, u_int64_t attr, double **array, int *length); int pass_resource_monitor_get_array_string(int id, int res_id, u_int64_t attr, char ***array, int *length); +/** + * @brief Get timestamp of the latest resource update + * @param[in] Resource monitor id + * @param[in] Resource id + * @param[out] start time of update + * @param[out] end time of update + * @return @ 0 on success, otherwise a negative error value + */ + +int pass_resource_monitor_get_resource_timestamp(int id, int res_id, int64_t *start, int64_t *end); + #ifdef __cplusplus } #endif diff --git a/src/monitor/request-handler.c b/src/monitor/request-handler.c index 3bbea40..2bad112 100644 --- a/src/monitor/request-handler.c +++ b/src/monitor/request-handler.c @@ -454,6 +454,32 @@ handle_request_get_value_array(struct request_client *client, char *args, struct return get_resource_attr_array(res, attr_id, arr); } +static int +handle_request_get_resource_ts(struct request_client *client, char *args, + int64_t *start, int64_t *end) +{ + struct resource *res; + int resource_id; + + if (!client || !args) + return -ENOENT; + + /** + * Format of REQUEST_GET_RESOURCE_TS args: + * - + */ + resource_id = atoi(args); + + res = get_resource_by_id(client, resource_id); + if (!res) + return -EINVAL; + + *start = res->ts_start; + *end = res->ts_end; + + return 0; +} + static int split_request_type_and_args(char *buffer, char **args) { char *request_type_str; @@ -690,6 +716,17 @@ static int handle_request(struct request_client *client, char *request) } } break; + case REQUEST_GET_RESOURCE_TS: + { + int64_t start, end; + + ret = handle_request_get_resource_ts(client, args, &start, &end); + if (ret < 0) + _D("failed to get value"); + + ADD_RESPONSE(response, buffer_len, "%"PRId64"$%"PRId64"$", start, end); + } + break; default: _E("Invliad request type: %d", request_type); ret = -EINVAL; diff --git a/src/util/resource.c b/src/util/resource.c index aefe3cc..abe7b49 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -254,6 +254,8 @@ int update_resource_attrs(struct resource *resource) if (!resource || !resource->type) return -EINVAL; + resource->ts_start = get_time_now(); + if (resource->driver && resource->driver->ops.prepare_update) { ret = resource->driver->ops.prepare_update(resource); if (ret < 0) @@ -270,6 +272,8 @@ int update_resource_attrs(struct resource *resource) } } + resource->ts_end = get_time_now(); + return 0; } @@ -468,6 +472,7 @@ static void _put_resource_attr_json(json_object *jobj_attr) int get_resource_attrs_json(struct resource *resource, char **json_string) { json_object *jobj_root, *jobj_res_name, *jobj_res_type, *jobj_res_attrs, *jobj_attr; + json_object *jobj_res_ts, *jobj_ts_start, *jobj_ts_end; const struct resource_attribute *attr; const struct resource_attribute_value *attr_value; int i; @@ -493,18 +498,30 @@ int get_resource_attrs_json(struct resource *resource, char **json_string) json_object_array_add(jobj_res_attrs, jobj_attr); } + jobj_res_ts = json_object_new_object(); + jobj_ts_start = json_object_new_int64(resource->ts_start); + jobj_ts_end = json_object_new_int64(resource->ts_end); + + json_object_object_add(jobj_res_ts, "start", jobj_ts_start); + json_object_object_add(jobj_res_ts, "end", jobj_ts_end); + json_object_object_add(jobj_root, "res_name", jobj_res_name); json_object_object_add(jobj_root, "res_type", jobj_res_type); json_object_object_add(jobj_root, "res_attrs", jobj_res_attrs); + json_object_object_add(jobj_root, "res_ts", jobj_res_ts); *json_string = strdup(json_object_to_json_string(jobj_root)); + json_object_object_del(jobj_res_ts, "end"); + json_object_object_del(jobj_res_ts, "start"); + for (i = 0; i < json_object_array_length(jobj_res_attrs); i++) { jobj_attr = json_object_array_get_idx(jobj_res_attrs, i); _put_resource_attr_json(jobj_attr); } json_object_array_del_idx(jobj_res_attrs, 0, json_object_array_length(jobj_res_attrs)); + json_object_object_del(jobj_root, "res_ts"); json_object_object_del(jobj_root, "res_attrs"); json_object_object_del(jobj_root, "res_type"); json_object_object_del(jobj_root, "res_name"); -- 2.7.4