2 * PASS (Power Aware System Service)
4 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
24 #include <util/common.h>
25 #include <util/resource.h>
28 #define RESOURCE_ATTR_MASK (ULLONG_MAX)
29 #define BIT64_INDEX(id) (63 - __builtin_clzll(id))
30 #define RESOURCE_ATTR_INDEX(id) BIT64_INDEX(id)
31 #define RESOURCE_CTRL_INDEX(id) BIT64_INDEX(id)
36 const struct resource_driver *driver;
41 const struct resource_attribute *attrs;
42 struct resource_attribute_value *attrs_value;
44 const struct resource_control *ctrls;
45 u_int64_t attr_interest;
46 u_int64_t attr_supported;
52 static int g_resource_id;
53 static GList *g_resource_driver_head;
54 static GList *g_resource_device_head;
56 static gint __compare_resource_type(gconstpointer data, gconstpointer input)
58 struct resource_driver *driver = (struct resource_driver *)data;
59 int type = *(int *)input;
61 if (driver->type == type)
66 static const struct resource_driver *find_resource_driver(int resource_type)
70 node = g_list_find_custom(g_resource_driver_head,
71 &resource_type, __compare_resource_type);
75 return (struct resource_driver *)node->data;
78 void add_resource_driver(const struct resource_driver *driver)
83 g_resource_driver_head =
84 g_list_append(g_resource_driver_head, (gpointer)driver);
87 void remove_resource_driver(const struct resource_driver *driver)
92 g_resource_driver_head =
93 g_list_remove(g_resource_driver_head, (gpointer)driver);
96 int get_resource_device_count_all(void)
98 return g_list_length(g_resource_device_head);
101 int get_resource_device_count(int resource_type)
104 struct resource_device *device;
105 const struct resource_driver *driver;
108 for (node = g_resource_device_head; node != NULL; node = node->next) {
110 if (device->type == resource_type)
117 driver = find_resource_driver(resource_type);
121 if (driver->flag & RESOURCE_FLAG_COUNT_ONLY_ONE)
123 else if (driver->flag & RESOURCE_FLAG_PROCESS)
129 const struct resource_device *find_resource_device(int resource_type,
133 const struct resource_device *device;
135 for (node = g_resource_device_head; node != NULL; node = node->next) {
137 if (device->type == resource_type &&
138 device->index == resource_index)
145 int add_resource_device(struct resource_device *device)
152 count = get_resource_device_count(device->type);
153 device->index = count;
155 g_resource_device_head =
156 g_list_append(g_resource_device_head, (gpointer)device);
161 void remove_resource_device(struct resource_device *device)
166 g_resource_device_head =
167 g_list_remove(g_resource_device_head, (gpointer)device);
170 static void do_delete_resource(struct resource *resource)
173 free(resource->name);
174 if (!resource->attrs_value)
175 free(resource->attrs_value);
176 resource->attrs = NULL;
177 resource->num_attrs = 0;
182 void delete_resource(struct resource *resource)
187 if (resource->driver && resource->driver->ops.delete)
188 resource->driver->ops.delete(resource);
190 unset_resource_attr_interest(resource, RESOURCE_ATTR_MASK);
192 do_delete_resource(resource);
195 static int clear_sign_bit(unsigned int val)
197 return (int)((val << 1) >> 1);
200 void init_resource_id(void)
206 * Initial g_resource_id is set by a combination of
207 * tv_sec and tv_usec values of gettimeofday().
208 * It ensures that PASS assigns a unique resource id
209 * for each create_resource request.
211 * Even PASS is restarted, a newly initialized value
212 * of g_resource_id reflects the current value of
213 * gettimeofday(). Thus, the uniqueness in resource
214 * id is kept unless the number of created resources
215 * crosses the time consumed (in msecs) before
218 gettimeofday(&tv, NULL);
219 val = tv.tv_sec * 1000 + tv.tv_usec / 1000;
220 g_resource_id = clear_sign_bit(val);
223 struct resource *create_resource(int resource_type)
225 const struct resource_driver *driver = NULL;
226 struct resource *resource = NULL;
229 driver = find_resource_driver(resource_type);
231 _E("failed to find resource driver, res:type(%d)\n",
236 resource = calloc(1, sizeof(*resource));
240 resource->id = clear_sign_bit(
241 (unsigned int)__sync_fetch_and_add(&g_resource_id, 1));
242 resource->type = resource_type;
243 resource->name = g_strdup(driver->name);
244 resource->driver = driver;
245 resource->num_attrs = driver->num_attrs;
246 resource->attrs = driver->attrs;
247 resource->attrs_value = calloc(resource->num_attrs,
248 sizeof(*resource->attrs_value));
249 if (!resource->attrs_value) {
250 do_delete_resource(resource);
254 for (i = 0; i < resource->num_attrs; i++)
255 resource->attrs_value[i].type = driver->attrs[i].type;
257 resource->ctrls = driver->ctrls;
258 resource->num_ctrls = driver->num_ctrls;
260 if (driver->ops.create) {
261 ret = driver->ops.create(resource);
263 _E("failed to initialize resource driver, res:type(%s)id(%d)\n",
264 resource->name, resource->id);
265 do_delete_resource(resource);
273 int set_resource_control(struct resource *resource, u_int64_t ctrl_id, const void *data)
275 const struct resource_control *ctrl;
276 int ctrl_index = RESOURCE_CTRL_INDEX(ctrl_id);
279 if (!resource || ctrl_index < 0 || ctrl_index >= resource->num_ctrls) {
280 _E("Invalid parameter\n");
284 ctrl = &resource->ctrls[ctrl_index];
288 ret = ctrl->ops.set(resource, ctrl, data);
295 const char *get_resource_control_name(struct resource *resource, u_int64_t ctrl_id)
297 const struct resource_control *ctrl;
298 int ctrl_index = RESOURCE_CTRL_INDEX(ctrl_id);
300 if (!resource || ctrl_index < 0 || ctrl_index >= resource->num_ctrls) {
301 _E("Invalid parameter\n");
305 ctrl = &resource->ctrls[ctrl_index];
310 static int update_resource_attr(struct resource *resource, u_int64_t attr_id)
312 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
313 const struct resource_attribute *attr = NULL;
314 struct resource_attribute_value *attr_value = NULL;
317 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs) {
318 _E("Invalid parameter\n");
322 attr = &resource->attrs[attr_index];
324 if (!attr->ops.get) {
325 _E("don't support get ops of resource attribute value, res:type(%s)id(%d) | attr:name(%s)id(%"PRId64")\n",
326 resource->name, resource->id,
327 attr->name, attr_id);
331 attr_value = &resource->attrs_value[attr_index];
333 ret = attr->ops.get(resource, attr, attr_value->data);
335 _E("failed to get resource attribute value, res:type(%s)id(%d) | attr:name(%s)id(%"PRId64")\n",
336 resource->name, resource->id,
337 attr->name, attr_id);
344 int update_resource_attrs(struct resource *resource)
348 if (!resource || !resource->type)
351 resource->ts_start = get_time_now();
353 if (resource->driver && resource->driver->ops.prepare_update) {
354 ret = resource->driver->ops.prepare_update(resource);
356 _E("failed to prepare_update resource driver, res:type(%s)id(%d)\n",
357 resource->name, resource->id);
362 for (i = 0; i < resource->num_attrs; i++) {
363 if (!(resource->attrs[i].id & resource->attr_interest))
365 ret = update_resource_attr(resource, resource->attrs[i].id);
367 _E("failed to update resource attribute, res:type(%s)id(%d) | attr:name(%s)id(%"PRId64")\n",
368 resource->name, resource->id,
369 resource->attrs[i].name, resource->attrs[i].id);
373 resource->ts_end = get_time_now();
378 const struct resource_attribute *
379 get_resource_attr(struct resource *resource, u_int64_t attr_id)
381 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
383 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs) {
384 _E("Invalid parameter\n");
388 return &resource->attrs[attr_index];
391 struct resource_attribute_value *
392 get_resource_attr_value(struct resource *resource, u_int64_t attr_id)
394 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
396 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs) {
397 _E("Invalid parameter\n");
401 return &resource->attrs_value[attr_index];
404 int is_resource_attr_supported(struct resource *resource, u_int64_t attr_id, bool *supported)
406 const struct resource_attribute *attr = NULL;
407 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
409 bool is_supported = false;
411 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs) {
412 _E("Invalid parameter\n");
416 attr = &resource->attrs[attr_index];
418 if (attr->id & resource->attr_supported) {
420 } else if (attr->ops.is_supported) {
421 is_supported = attr->ops.is_supported(resource, attr);
422 } else if (attr->ops.get) {
424 * Optionally, if .is_supported ops is not implemented,
425 * use .get ops in order to check whether the resource attribute
426 * is supported or not.
428 char data[BUFF_MAX] = {0, };
430 ret = attr->ops.get(resource, attr, (void *)data);
431 is_supported = (ret < 0) ? false : true;
435 resource->attr_supported |= attr->id;
437 *supported = is_supported;
442 static bool check_attr_validate(struct resource *resource, u_int64_t attr_id, int type)
444 const struct resource_attribute *attr = get_resource_attr(resource, attr_id);
447 _E("Invalid parameter\n");
451 if (attr->type != type) {
452 _E("Invalid data type(%d), res:type(%s)id(%d) | attr:name(%s)id(%"PRId64",%d)\n",
454 resource->name, resource->id,
455 attr->name, attr->id, attr->type);
459 if (!(attr->id & resource->attr_interest)) {
460 _E("Invalid interest state, res:type(%s)id(%d) | attr:name(%s)id(%"PRId64")type(%d)\n",
461 resource->name, resource->id,
462 attr->name, attr->id, attr->type);
469 static json_object *_get_resource_attr_json(const struct resource_attribute *attr,
470 const struct resource_attribute_value *attr_value)
472 json_object *jobj_attr, *jobj_attr_name, *jobj_attr_type, *jobj_attr_value, *jobj_temp;
473 struct array_value *array;
476 switch (attr->type) {
478 jobj_attr_value = json_object_new_int(*((int32_t *)attr_value->data));
481 jobj_attr_value = json_object_new_int(*((u_int32_t *)attr_value->data));
483 case DATA_TYPE_INT64:
484 jobj_attr_value = json_object_new_int64(*((int64_t *)attr_value->data));
486 case DATA_TYPE_UINT64:
487 jobj_attr_value = json_object_new_uint64(*((u_int64_t *)attr_value->data));
489 case DATA_TYPE_DOUBLE:
490 jobj_attr_value = json_object_new_double(*((double *)attr_value->data));
492 case DATA_TYPE_STRING:
493 jobj_attr_value = json_object_new_string((char *)attr_value->data);
495 case DATA_TYPE_ARRAY:
496 array = attr_value->data;
498 jobj_attr_value = json_object_new_array();
500 switch (array->type) {
502 for (i = 0; i < array->length; i++) {
503 int32_t *item = array->data;
505 jobj_temp = json_object_new_int(item[i]);
506 json_object_array_add(jobj_attr_value, jobj_temp);
510 for (i = 0; i < array->length; i++) {
511 u_int32_t *item = array->data;
513 jobj_temp = json_object_new_int(item[i]);
514 json_object_array_add(jobj_attr_value, jobj_temp);
517 case DATA_TYPE_INT64:
518 for (i = 0; i < array->length; i++) {
519 int64_t *item = array->data;
521 jobj_temp = json_object_new_int64(item[i]);
522 json_object_array_add(jobj_attr_value, jobj_temp);
525 case DATA_TYPE_UINT64:
526 for (i = 0; i < array->length; i++) {
527 u_int64_t *item = array->data;
529 jobj_temp = json_object_new_uint64(item[i]);
530 json_object_array_add(jobj_attr_value, jobj_temp);
533 case DATA_TYPE_DOUBLE:
534 for (i = 0; i < array->length; i++) {
535 double *item = array->data;
537 jobj_temp = json_object_new_double(item[i]);
538 json_object_array_add(jobj_attr_value, jobj_temp);
541 case DATA_TYPE_STRING:
542 for (i = 0; i < array->length; i++) {
543 char **item = array->data;
545 jobj_temp = json_object_new_string(item[i]);
546 json_object_array_add(jobj_attr_value, jobj_temp);
550 _E("wrong attribute data type in array\n");
551 json_object_put(jobj_attr_value);
552 jobj_attr_value = json_object_new_null();
556 _E("wrong attribute data type\n");
557 jobj_attr_value = json_object_new_null();
559 jobj_attr = json_object_new_object();
561 jobj_attr_name = json_object_new_string(attr->name);
563 * Since actually JSON format has no data type limitation itself, in many
564 * cases except converting JSON into json-c, type is not required. So,
565 * for the case of converting JSON generated here to json-c object again
566 * json_type is stored in each attributes.
568 jobj_attr_type = json_object_new_int(json_object_get_type(jobj_attr_value));
570 json_object_object_add(jobj_attr, "name", jobj_attr_name);
571 json_object_object_add(jobj_attr, "json_type", jobj_attr_type);
572 json_object_object_add(jobj_attr, "value", jobj_attr_value);
577 static void _put_resource_attr_json(json_object *jobj_attr)
579 json_object *jobj_attr_value;
581 json_object_object_del(jobj_attr, "name");
582 json_object_object_del(jobj_attr, "json_type");
584 if (json_object_object_get_ex(jobj_attr, "value", &jobj_attr_value) &&
585 json_object_is_type(jobj_attr_value, json_type_array))
586 json_object_array_del_idx(jobj_attr_value, 0,
587 json_object_array_length(jobj_attr_value));
589 json_object_object_del(jobj_attr, "value");
592 int get_resource_attrs_json(struct resource *resource, char **json_string)
594 json_object *jobj_root, *jobj_res_name, *jobj_res_type, *jobj_res_attrs, *jobj_attr;
595 json_object *jobj_res_ts, *jobj_ts_start, *jobj_ts_end;
596 const struct resource_attribute *attr;
597 const struct resource_attribute_value *attr_value;
600 if (!resource || !resource->type)
603 jobj_root = json_object_new_object();
605 jobj_res_name = json_object_new_string(resource->name);
606 jobj_res_type = json_object_new_int(resource->type);
607 jobj_res_attrs = json_object_new_array();
609 for (i = 0; i < resource->num_attrs; i++) {
610 if (!(resource->attrs[i].id & resource->attr_interest))
613 attr = &resource->attrs[i];
614 attr_value = &resource->attrs_value[i];
616 jobj_attr = _get_resource_attr_json(attr, attr_value);
618 json_object_array_add(jobj_res_attrs, jobj_attr);
621 jobj_res_ts = json_object_new_object();
622 jobj_ts_start = json_object_new_int64(resource->ts_start);
623 jobj_ts_end = json_object_new_int64(resource->ts_end);
625 json_object_object_add(jobj_res_ts, "start", jobj_ts_start);
626 json_object_object_add(jobj_res_ts, "end", jobj_ts_end);
628 json_object_object_add(jobj_root, "res_name", jobj_res_name);
629 json_object_object_add(jobj_root, "res_type", jobj_res_type);
630 json_object_object_add(jobj_root, "res_attrs", jobj_res_attrs);
631 json_object_object_add(jobj_root, "res_ts", jobj_res_ts);
633 *json_string = strdup(json_object_to_json_string(jobj_root));
635 json_object_object_del(jobj_res_ts, "end");
636 json_object_object_del(jobj_res_ts, "start");
638 for (i = 0; i < json_object_array_length(jobj_res_attrs); i++) {
639 jobj_attr = json_object_array_get_idx(jobj_res_attrs, i);
640 _put_resource_attr_json(jobj_attr);
642 json_object_array_del_idx(jobj_res_attrs, 0, json_object_array_length(jobj_res_attrs));
644 json_object_object_del(jobj_root, "res_ts");
645 json_object_object_del(jobj_root, "res_attrs");
646 json_object_object_del(jobj_root, "res_type");
647 json_object_object_del(jobj_root, "res_name");
648 json_object_put(jobj_root);
653 int get_resource_attr_json(struct resource *resource, u_int64_t attr_id, char **json_string)
655 const struct resource_attribute *attr;
656 const struct resource_attribute_value *attr_value;
657 json_object *jobj_attr;
659 attr = get_resource_attr(resource, attr_id);
660 attr_value = get_resource_attr_value(resource, attr_id);
662 if (!attr || !attr_value)
665 jobj_attr = _get_resource_attr_json(attr, attr_value);
667 *json_string = strdup(json_object_to_json_string(jobj_attr));
669 _put_resource_attr_json(jobj_attr);
674 static json_object *get_resource_driver_json(const struct resource_driver *driver)
676 json_object *jobj_drv, *jobj_drv_name, *jobj_drv_type;
677 json_object *jobj_drv_attrs_array, *jobj_drv_attr, *jobj_drv_ctrls_array, *jobj_drv_ctrl;
678 json_object *jobj_drv_attr_name, *jobj_drv_attr_type, *jobj_drv_attr_id;
679 json_object *jobj_drv_ctrl_name, *jobj_drv_ctrl_id;
680 const struct resource_attribute *attr;
681 const struct resource_control *ctrl;
684 jobj_drv = json_object_new_object();
686 jobj_drv_name = json_object_new_string(driver->name);
687 jobj_drv_type = json_object_new_int(driver->type);
689 jobj_drv_attrs_array = json_object_new_array();
691 for (i = 0; i < driver->num_attrs; i++) {
692 attr = &driver->attrs[i];
694 jobj_drv_attr = json_object_new_object();
696 jobj_drv_attr_name = json_object_new_string(attr->name);
697 jobj_drv_attr_type = json_object_new_int(attr->type);
698 jobj_drv_attr_id = json_object_new_uint64(attr->id);
700 json_object_object_add(jobj_drv_attr, "name", jobj_drv_attr_name);
701 json_object_object_add(jobj_drv_attr, "type", jobj_drv_attr_type);
702 json_object_object_add(jobj_drv_attr, "id", jobj_drv_attr_id);
704 json_object_array_add(jobj_drv_attrs_array, jobj_drv_attr);
707 jobj_drv_ctrls_array = json_object_new_array();
709 for (i = 0; i < driver->num_ctrls; i++) {
710 ctrl = &driver->ctrls[i];
712 jobj_drv_ctrl = json_object_new_object();
714 jobj_drv_ctrl_name = json_object_new_string(ctrl->name);
715 jobj_drv_ctrl_id = json_object_new_uint64(ctrl->id);
717 json_object_object_add(jobj_drv_ctrl, "name", jobj_drv_ctrl_name);
718 json_object_object_add(jobj_drv_ctrl, "id", jobj_drv_ctrl_id);
720 json_object_array_add(jobj_drv_ctrls_array, jobj_drv_ctrl);
723 json_object_object_add(jobj_drv, "name", jobj_drv_name);
724 json_object_object_add(jobj_drv, "type", jobj_drv_type);
725 json_object_object_add(jobj_drv, "attrs", jobj_drv_attrs_array);
726 json_object_object_add(jobj_drv, "ctrls", jobj_drv_ctrls_array);
731 void put_resource_driver_json(json_object *jobj_drv)
733 json_object *jobj_array, *jobj_obj;
736 if (json_object_object_get_ex(jobj_drv, "ctrls", &jobj_array)) {
737 for (i = 0; i < json_object_array_length(jobj_array); i++) {
738 jobj_obj = json_object_array_get_idx(jobj_array, i);
740 json_object_object_del(jobj_obj, "id");
741 json_object_object_del(jobj_obj, "name");
743 json_object_array_del_idx(jobj_array, 0, json_object_array_length(jobj_array));
746 if (json_object_object_get_ex(jobj_drv, "attrs", &jobj_array)) {
747 for (i = 0; i < json_object_array_length(jobj_array); i++) {
748 jobj_obj = json_object_array_get_idx(jobj_array, i);
750 json_object_object_del(jobj_obj, "id");
751 json_object_object_del(jobj_obj, "type");
752 json_object_object_del(jobj_obj, "name");
754 json_object_array_del_idx(jobj_array, 0, json_object_array_length(jobj_array));
757 json_object_object_del(jobj_drv, "ctrls");
758 json_object_object_del(jobj_drv, "attrs");
759 json_object_object_del(jobj_drv, "type");
760 json_object_object_del(jobj_drv, "name");
763 int get_resource_list_json(char **json_string)
765 const struct resource_driver *driver;
766 json_object *jobj_root, *jobj_drvs_array, *jobj_drv;
769 jobj_root = json_object_new_object();
770 jobj_drvs_array = json_object_new_array();
772 for (i = 0; i < g_list_length(g_resource_driver_head); i++) {
773 driver = g_list_nth(g_list_first(g_resource_driver_head), i)->data;
775 jobj_drv = get_resource_driver_json(driver);
776 json_object_array_add(jobj_drvs_array, jobj_drv);
779 json_object_object_add(jobj_root, "resources", jobj_drvs_array);
781 *json_string = strdup(json_object_to_json_string(jobj_root));
783 for (i = 0; i < json_object_array_length(jobj_drvs_array); i++) {
784 jobj_drv = json_object_array_get_idx(jobj_drvs_array, i);
786 put_resource_driver_json(jobj_drv);
788 json_object_array_del_idx(jobj_drvs_array, 0, json_object_array_length(jobj_drvs_array));
790 json_object_object_del(jobj_root, "resources");
791 json_object_put(jobj_root);
796 int get_resource_attr_int(struct resource *resource, u_int64_t attr_id, int32_t *data)
798 struct resource_attribute_value *attr_value = NULL;
800 if (!check_attr_validate(resource, attr_id, DATA_TYPE_INT))
803 attr_value = get_resource_attr_value(resource, attr_id);
807 *data = *((int32_t *)attr_value->data);
812 int get_resource_attr_int64(struct resource *resource, u_int64_t attr_id, int64_t *data)
814 struct resource_attribute_value *attr_value = NULL;
816 if (!check_attr_validate(resource, attr_id, DATA_TYPE_INT64))
819 attr_value = get_resource_attr_value(resource, attr_id);
823 *data = *((int64_t *)attr_value->data);
828 int get_resource_attr_uint(struct resource *resource, u_int64_t attr_id, u_int32_t *data)
830 struct resource_attribute_value *attr_value = NULL;
832 if (!check_attr_validate(resource, attr_id, DATA_TYPE_UINT))
835 attr_value = get_resource_attr_value(resource, attr_id);
839 *data = *((u_int32_t *)attr_value->data);
844 int get_resource_attr_uint64(struct resource *resource, u_int64_t attr_id, u_int64_t *data)
846 struct resource_attribute_value *attr_value = NULL;
848 if (!check_attr_validate(resource, attr_id, DATA_TYPE_UINT64))
851 attr_value = get_resource_attr_value(resource, attr_id);
855 *data = *((u_int64_t *)attr_value->data);
860 int get_resource_attr_double(struct resource *resource, u_int64_t attr_id, double *data)
862 struct resource_attribute_value *attr_value = NULL;
864 if (!check_attr_validate(resource, attr_id, DATA_TYPE_DOUBLE))
867 attr_value = get_resource_attr_value(resource, attr_id);
871 *data = *((double *)attr_value->data);
876 int get_resource_attr_string(struct resource *resource, u_int64_t attr_id, char *data)
878 struct resource_attribute_value *attr_value = NULL;
880 if (!check_attr_validate(resource, attr_id, DATA_TYPE_STRING)) {
881 _E("Invalid parameter\n");
885 attr_value = get_resource_attr_value(resource, attr_id);
887 _E("failed to get attribute value\n");
891 strncpy(data, (char *)attr_value->data, BUFF_MAX);
896 int get_resource_attr_array(struct resource *resource, u_int64_t attr_id, struct array_value **data)
898 struct resource_attribute_value *attr_value = NULL;
900 if (!check_attr_validate(resource, attr_id, DATA_TYPE_ARRAY))
903 attr_value = get_resource_attr_value(resource, attr_id);
907 *data = (struct array_value *)attr_value->data;
912 int get_resource_attr_ptr(struct resource *resource, u_int64_t attr_id, void **data)
914 struct resource_attribute_value *attr_value = NULL;
916 if (!check_attr_validate(resource, attr_id, DATA_TYPE_PTR))
919 attr_value = get_resource_attr_value(resource, attr_id);
923 *data = attr_value->data;
928 int set_resource_attr_interest(struct resource *resource, u_int64_t interest_mask)
930 struct resource_attribute_value *attr_value;
937 for (i = 0; i < resource->num_attrs; i++) {
938 if (!(resource->attrs[i].id & interest_mask))
941 ret = is_resource_attr_supported(resource, resource->attrs[i].id,
945 } else if (!supported){
950 attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
952 _E("failed to get attribute value, res:type(%s) | attr:name(%s)",
953 resource->name, resource->attrs[i].name);
959 * In resource monitor, each resource has a lot of attributes, but
960 * only updated attributes are selected by clients on demand. So,
961 * instead of allocating memory at the resource creation, allocate
962 * at the set interest.
964 if (!attr_value->data) {
965 switch (attr_value->type) {
967 attr_value->data = calloc(1, sizeof(int32_t));
969 case DATA_TYPE_INT64:
970 attr_value->data = calloc(1, sizeof(int64_t));
973 attr_value->data = calloc(1, sizeof(u_int32_t));
975 case DATA_TYPE_UINT64:
976 attr_value->data = calloc(1, sizeof(u_int64_t));
978 case DATA_TYPE_DOUBLE:
979 attr_value->data = calloc(1, sizeof(double));
981 case DATA_TYPE_STRING:
982 attr_value->data = calloc(BUFF_MAX, sizeof(char));
984 case DATA_TYPE_ARRAY:
985 attr_value->data = calloc(1, sizeof(struct array_value));
988 _E("Not supported data type(%d)", attr_value->type);
993 if (!attr_value->data) {
994 _E("failed to allocate attr_value memory, res:type(%s) | attr:name(%s)",
995 resource->name, resource->attrs[i].name);
1002 resource->attr_interest |= interest_mask;
1007 for (; i >= 0; i--) {
1008 if (!(resource->attrs[i].id & interest_mask))
1011 attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
1015 if (attr_value->data) {
1016 free(attr_value->data);
1017 attr_value->data = NULL;
1024 int unset_resource_attr_interest(struct resource *resource, u_int64_t interest_mask)
1026 struct resource_attribute_value *attr_value;
1032 if (!is_resource_attr_interested(resource, interest_mask))
1035 for (i = 0; i < resource->num_attrs; i++) {
1036 if (!(resource->attrs[i].id & interest_mask))
1039 attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
1041 _E("failed to get attribute value, res:type(%s) | attr:name(%s)",
1042 resource->name, resource->attrs[i].name);
1046 if (attr_value->data) {
1047 switch (attr_value->type) {
1048 case DATA_TYPE_ARRAY:
1050 struct array_value *array = attr_value->data;
1059 case DATA_TYPE_INT64:
1060 case DATA_TYPE_UINT:
1061 case DATA_TYPE_UINT64:
1062 case DATA_TYPE_DOUBLE:
1063 case DATA_TYPE_STRING:
1064 free(attr_value->data);
1065 attr_value->data = NULL;
1068 _E("Not supported data type(%d)", attr_value->type);
1074 resource->attr_interest &= ~interest_mask;
1079 bool is_resource_attr_interested(struct resource *resource, u_int64_t interest_mask)
1084 if (resource->attr_interest != (resource->attr_interest | interest_mask))
1090 const char *get_resource_attr_name(struct resource *resource, u_int64_t attr_id)
1092 const struct resource_attribute *attr;
1094 attr = get_resource_attr(resource, attr_id);
1101 const char *get_resource_name(struct resource *resource)
1103 return resource ? resource->name : NULL;
1106 void *get_resource_privdata(struct resource *resource)
1108 return resource ? resource->priv : NULL;
1111 int get_resource_id(struct resource *resource)
1113 return resource ? resource->id : -EINVAL;
1116 int get_resource_type(struct resource *resource)
1118 return resource ? resource->type : -EINVAL;
1121 int get_resource_ts(struct resource *resource, int64_t *ts_start, int64_t *ts_end)
1126 *ts_start = resource->ts_start;
1127 *ts_end = resource->ts_end;
1132 int set_resource_privdata(struct resource *resource, void *priv)
1137 resource->priv = priv;