3 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is furnished
10 * to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 #include "resource-manager.h"
31 #include "resource-type.h"
33 #define BIT64_INDEX(id) (63 - __builtin_clzll(id))
34 #define RESOURCE_ATTR_INDEX(id) BIT64_INDEX(id)
35 #define RESOURCE_CTRL_INDEX(id) BIT64_INDEX(id)
36 #define RESOURCE_FLAG_VISIBILITY_MASK (SYSCOMMON_RESMAN_RESOURCE_FLAG_PRIVATE \
37 | SYSCOMMON_RESMAN_RESOURCE_FLAG_PUBLIC)
38 #define RESOURCE_ATTR_FLAG_VISIBILITY_MASK (SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PRIVATE \
39 | SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC)
41 #define INSTANCE_TYPE_NORMAL 0
42 #define INSTANCE_TYPE_MONITOR 1
44 struct syscommon_resman_resource {
47 const struct syscommon_resman_resource_driver *driver;
48 int resource_type; /* which type of resource */
49 int instance_type; /* how resource instance operates */
52 const struct syscommon_resman_resource_attribute *attrs;
53 struct syscommon_resman_resource_attribute_value *attrs_value;
55 const struct syscommon_resman_resource_control *ctrls;
61 u_int64_t attr_interest;
62 u_int64_t attr_supported;
65 struct attribute_is_supported_ops {
66 bool (*is_supported)(int resource_id,
67 const struct syscommon_resman_resource_attribute *attr);
68 int (*get)(int resource_id,
69 const struct syscommon_resman_resource_attribute *attr,
73 static int set_resource_attr_interest(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
74 static int unset_resource_attr_interest(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
75 static bool is_resource_attr_interested(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
77 static GList *g_resource_driver_head;
78 static GHashTable *g_resource_hash_table;
80 static int clear_sign_bit(unsigned int val)
82 return (int)((val << 1) >> 1);
85 static int init_resource_id(void)
90 gettimeofday(&tv, NULL);
91 val = tv.tv_sec * 1000 + tv.tv_usec / 1000;
92 return clear_sign_bit(val);
95 static int alloc_resource_id(void)
97 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
98 static int resource_id = -1;
101 pthread_mutex_lock(&lock);
104 resource_id = init_resource_id();
107 resource_id = clear_sign_bit(resource_id + 1);
109 pthread_mutex_unlock(&lock);
114 static void free_resource(struct syscommon_resman_resource *resource)
116 free(resource->name);
117 resource->name = NULL;
119 unset_resource_attr_interest(resource, resource->attr_interest);
120 free(resource->attrs_value);
121 resource->attrs_value = NULL;
123 resource->attrs = NULL;
124 resource->num_attrs = 0;
129 static void delete_resource(void *data)
131 struct syscommon_resman_resource *resource = (struct syscommon_resman_resource *) data;
136 if (resource->driver && resource->driver->ops.delete)
137 resource->driver->ops.delete(resource->id);
139 free_resource(resource);
142 static int add_resource(struct syscommon_resman_resource *resource)
147 if (!g_resource_hash_table) {
148 g_resource_hash_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, delete_resource);
149 if (!g_resource_hash_table)
153 g_hash_table_insert(g_resource_hash_table, GINT_TO_POINTER(resource->id), resource);
158 static struct syscommon_resman_resource * find_resource(int id)
160 if (!g_resource_hash_table)
163 return g_hash_table_lookup(g_resource_hash_table, GINT_TO_POINTER(id));
166 static gint __compare_resource_type(gconstpointer data, gconstpointer input)
168 struct syscommon_resman_resource_driver *driver;
169 int type = *(int *)input;
171 driver = (struct syscommon_resman_resource_driver *)data;
173 if (driver && driver->type == type)
178 const struct syscommon_resman_resource_driver *
179 syscommon_resman_find_resource_driver(int resource_type)
183 node = g_list_find_custom(g_resource_driver_head,
184 &resource_type, __compare_resource_type);
188 return (struct syscommon_resman_resource_driver *)node->data;
192 syscommon_resman_add_resource_driver(const struct syscommon_resman_resource_driver *driver)
197 g_resource_driver_head =
198 g_list_append(g_resource_driver_head, (gpointer)driver);
202 syscommon_resman_remove_resource_driver(const struct syscommon_resman_resource_driver *driver)
207 g_resource_driver_head =
208 g_list_remove(g_resource_driver_head, (gpointer)driver);
211 void syscommon_resman_delete_resource(int resource_id)
213 if (!g_resource_hash_table)
216 g_hash_table_remove(g_resource_hash_table, GINT_TO_POINTER(resource_id));
220 create_resource(int *resource_id, int resource_type, int instance_type)
222 const struct syscommon_resman_resource_driver *driver = NULL;
223 struct syscommon_resman_resource *resource = NULL;
229 driver = syscommon_resman_find_resource_driver(resource_type);
233 resource = calloc(1, sizeof(*resource));
237 resource->id = alloc_resource_id();
238 resource->resource_type = resource_type;
239 resource->instance_type = instance_type;
240 resource->name = g_strdup(driver->name);
241 resource->driver = driver;
242 resource->num_attrs = driver->num_attrs;
243 resource->attrs = driver->attrs;
244 resource->attrs_value = calloc(resource->num_attrs,
245 sizeof(*resource->attrs_value));
246 if (!resource->attrs_value) {
247 free_resource(resource);
251 ret = add_resource(resource);
253 free_resource(resource);
257 for (i = 0; i < resource->num_attrs; i++)
258 resource->attrs_value[i].type = driver->attrs[i].type;
260 resource->ctrls = driver->ctrls;
261 resource->num_ctrls = driver->num_ctrls;
262 resource->flag = SYSCOMMON_RESMAN_RESOURCE_FLAG_PRIVATE;
264 if (driver->ops.create) {
265 ret = driver->ops.create(resource->id);
267 free_resource(resource);
272 *resource_id = resource->id;
277 static int set_resource_attr_interest_all(struct syscommon_resman_resource *resource)
281 if (!resource || !resource->num_attrs)
284 all = (1ULL << resource->num_attrs) - 1;
286 return set_resource_attr_interest(resource, all);
290 syscommon_resman_create_resource(int *resource_id, int resource_type)
293 struct syscommon_resman_resource *resource = NULL;
295 ret = create_resource(resource_id, resource_type, INSTANCE_TYPE_NORMAL);
299 resource = find_resource(*resource_id);
302 ret = set_resource_attr_interest_all(resource);
304 free_resource(resource);
312 syscommon_resman_monitor_create_resource(int *resource_id, int resource_type)
314 return create_resource(resource_id, resource_type, INSTANCE_TYPE_MONITOR);
318 syscommon_resman_set_resource_flag(int resource_id, u_int64_t flag_mask)
320 struct syscommon_resman_resource *resource = find_resource(resource_id);
325 resource->flag = flag_mask;
330 syscommon_resman_set_resource_control(int resource_id, u_int64_t ctrl_id, const void *data)
332 const struct syscommon_resman_resource_control *ctrl;
333 int ctrl_index = RESOURCE_CTRL_INDEX(ctrl_id);
335 struct syscommon_resman_resource *resource = find_resource(resource_id);
337 if (!resource || ctrl_index < 0 || ctrl_index >= resource->num_ctrls)
340 ctrl = &resource->ctrls[ctrl_index];
344 ret = ctrl->ops.set(resource_id, ctrl, data);
352 syscommon_resman_get_resource_control_name(int resource_id, u_int64_t ctrl_id)
354 const struct syscommon_resman_resource_control *ctrl;
355 int ctrl_index = RESOURCE_CTRL_INDEX(ctrl_id);
356 struct syscommon_resman_resource *resource = find_resource(resource_id);
358 if (!resource || ctrl_index < 0 || ctrl_index >= resource->num_ctrls)
361 ctrl = &resource->ctrls[ctrl_index];
367 monitor_update_resource_attr(struct syscommon_resman_resource *resource,
370 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
371 const struct syscommon_resman_resource_attribute *attr = NULL;
372 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
375 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs)
378 attr = &resource->attrs[attr_index];
380 if (!attr->monitor_ops.get)
383 attr_value = &resource->attrs_value[attr_index];
385 ret = attr->monitor_ops.get(resource->id, attr, attr_value->data);
392 static bool is_valid_resource(struct syscommon_resman_resource *resource, int instance_type)
394 return (resource && resource->instance_type == instance_type);
398 syscommon_resman_monitor_update_resource_attrs(int resource_id)
401 struct syscommon_resman_resource *resource = find_resource(resource_id);
403 if (!is_valid_resource(resource, INSTANCE_TYPE_MONITOR))
406 if (resource->driver && resource->driver->ops.prepare_update) {
407 ret = resource->driver->ops.prepare_update(resource->id);
412 for (i = 0; i < resource->num_attrs; i++) {
413 if (!(resource->attrs[i].id & resource->attr_interest))
415 monitor_update_resource_attr(resource, resource->attrs[i].id);
421 static const struct syscommon_resman_resource_attribute *
422 get_resource_attr(struct syscommon_resman_resource *resource, u_int64_t attr_id)
424 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
426 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs)
429 return &resource->attrs[attr_index];
432 const struct syscommon_resman_resource_attribute *
433 syscommon_resman_get_resource_attr(int resource_id, u_int64_t attr_id)
435 struct syscommon_resman_resource *resource = find_resource(resource_id);
437 return get_resource_attr(resource, attr_id);
441 static struct syscommon_resman_resource_attribute_value *
442 get_resource_attr_value(struct syscommon_resman_resource *resource, u_int64_t attr_id)
444 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
446 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs)
449 return &resource->attrs_value[attr_index];
452 struct syscommon_resman_resource_attribute_value *
453 syscommon_resman_get_resource_attr_value(int resource_id, u_int64_t attr_id)
455 struct syscommon_resman_resource *resource = find_resource(resource_id);
457 return get_resource_attr_value(resource, attr_id);
460 static int select_attribute_is_supported_ops(int instance_type,
461 const struct syscommon_resman_resource_attribute *attr, struct attribute_is_supported_ops *ops)
466 switch (instance_type) {
467 case INSTANCE_TYPE_NORMAL:
468 ops->is_supported = attr->ops.is_supported;
469 ops->get = attr->ops.get;
471 case INSTANCE_TYPE_MONITOR:
472 ops->is_supported = attr->monitor_ops.is_supported;
473 ops->get = attr->monitor_ops.get;
476 assert(0); // unreachable
482 static int is_resource_attr_supported(struct syscommon_resman_resource *resource, u_int64_t attr_id, bool *supported)
484 const struct syscommon_resman_resource_attribute *attr = NULL;
485 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
487 bool is_supported = false;
488 struct attribute_is_supported_ops ops = { 0 , };
490 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs) {
495 attr = &resource->attrs[attr_index];
497 /* Select ops for testing support by instance type */
498 ret = select_attribute_is_supported_ops(resource->instance_type, attr, &ops);
504 if (attr->id & resource->attr_supported) {
506 } else if (ops.is_supported) {
507 is_supported = ops.is_supported(resource->id, attr);
508 } else if (ops.get) {
510 * Optionally, if .is_supported ops is not implemented,
511 * use .get ops in order to check whether the resource attribute
512 * is supported or not.
514 char data[SYSCOMMON_RESMAN_BUFF_MAX] = {0, };
516 ret = ops.get(resource->id, attr, (void *)data);
517 is_supported = (ret < 0) ? false : true;
521 resource->attr_supported |= attr->id;
523 *supported = is_supported;
529 syscommon_resman_is_resource_attr_supported(int resource_id, u_int64_t attr_id, bool *supported)
531 struct syscommon_resman_resource *resource = find_resource(resource_id);
533 if (!is_valid_resource(resource, INSTANCE_TYPE_NORMAL))
536 return is_resource_attr_supported(resource, attr_id, supported);
540 syscommon_resman_monitor_is_resource_attr_supported(int resource_id, u_int64_t attr_id, bool *supported)
542 struct syscommon_resman_resource *resource = find_resource(resource_id);
544 if (!is_valid_resource(resource, INSTANCE_TYPE_MONITOR))
547 return is_resource_attr_supported(resource, attr_id, supported);
551 check_attr_validate(struct syscommon_resman_resource *resource,
552 u_int64_t attr_id, int type)
554 const struct syscommon_resman_resource_attribute *attr;
556 attr = get_resource_attr(resource, attr_id);
560 if (attr->type != type)
563 if (!(attr->id & resource->attr_interest))
570 _get_resource_attr_json(const struct syscommon_resman_resource_attribute *attr,
571 const struct syscommon_resman_resource_attribute_value *attr_value)
573 json_object *jobj_attr, *jobj_attr_name, *jobj_attr_type, *jobj_attr_value, *jobj_temp;
574 struct syscommon_resman_array_value *array;
577 switch (attr->type) {
578 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
579 jobj_attr_value = json_object_new_int(*((int32_t *)attr_value->data));
581 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
582 jobj_attr_value = json_object_new_int(*((u_int32_t *)attr_value->data));
584 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
585 jobj_attr_value = json_object_new_int64(*((int64_t *)attr_value->data));
587 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
588 jobj_attr_value = json_object_new_uint64(*((u_int64_t *)attr_value->data));
590 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
591 jobj_attr_value = json_object_new_double(*((double *)attr_value->data));
593 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
594 jobj_attr_value = json_object_new_string((char *)attr_value->data);
596 case SYSCOMMON_RESMAN_DATA_TYPE_ARRAY:
597 array = attr_value->data;
599 jobj_attr_value = json_object_new_array();
601 switch (array->type) {
602 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
603 for (i = 0; i < array->length; i++) {
604 int32_t *item = array->data;
606 jobj_temp = json_object_new_int(item[i]);
607 json_object_array_add(jobj_attr_value, jobj_temp);
610 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
611 for (i = 0; i < array->length; i++) {
612 u_int32_t *item = array->data;
614 jobj_temp = json_object_new_int(item[i]);
615 json_object_array_add(jobj_attr_value, jobj_temp);
618 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
619 for (i = 0; i < array->length; i++) {
620 int64_t *item = array->data;
622 jobj_temp = json_object_new_int64(item[i]);
623 json_object_array_add(jobj_attr_value, jobj_temp);
626 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
627 for (i = 0; i < array->length; i++) {
628 u_int64_t *item = array->data;
630 jobj_temp = json_object_new_uint64(item[i]);
631 json_object_array_add(jobj_attr_value, jobj_temp);
634 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
635 for (i = 0; i < array->length; i++) {
636 double *item = array->data;
638 jobj_temp = json_object_new_double(item[i]);
639 json_object_array_add(jobj_attr_value, jobj_temp);
642 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
643 for (i = 0; i < array->length; i++) {
644 char **item = array->data;
646 jobj_temp = json_object_new_string(item[i]);
647 json_object_array_add(jobj_attr_value, jobj_temp);
651 json_object_put(jobj_attr_value);
652 jobj_attr_value = json_object_new_null();
656 jobj_attr_value = json_object_new_null();
658 jobj_attr = json_object_new_object();
660 jobj_attr_name = json_object_new_string(attr->name);
662 * Since actually JSON format has no data type limitation itself, in many
663 * cases except converting JSON into json-c, type is not required. So,
664 * for the case of converting JSON generated here to json-c object again
665 * json_type is stored in each attributes.
667 jobj_attr_type = json_object_new_int(json_object_get_type(jobj_attr_value));
669 json_object_object_add(jobj_attr, "name", jobj_attr_name);
670 json_object_object_add(jobj_attr, "json_type", jobj_attr_type);
671 json_object_object_add(jobj_attr, "value", jobj_attr_value);
676 static void _put_resource_attr_json(json_object *jobj_attr)
678 json_object *jobj_attr_value;
680 json_object_object_del(jobj_attr, "name");
681 json_object_object_del(jobj_attr, "json_type");
683 if (json_object_object_get_ex(jobj_attr, "value", &jobj_attr_value) &&
684 json_object_is_type(jobj_attr_value, json_type_array))
685 json_object_array_del_idx(jobj_attr_value, 0,
686 json_object_array_length(jobj_attr_value));
688 json_object_object_del(jobj_attr, "value");
692 syscommon_resman_monitor_get_resource_attrs_json(int resource_id, char **json_string)
694 json_object *jobj_root, *jobj_res_name, *jobj_res_type, *jobj_res_attrs, *jobj_attr;
695 const struct syscommon_resman_resource_attribute *attr;
696 const struct syscommon_resman_resource_attribute_value *attr_value;
697 struct syscommon_resman_resource *resource = find_resource(resource_id);
700 if (!is_valid_resource(resource, INSTANCE_TYPE_MONITOR))
703 jobj_root = json_object_new_object();
705 jobj_res_name = json_object_new_string(resource->name);
706 jobj_res_type = json_object_new_int(resource->resource_type);
707 jobj_res_attrs = json_object_new_array();
709 for (i = 0; i < resource->num_attrs; i++) {
710 if (!(resource->attrs[i].id & resource->attr_interest))
713 attr = &resource->attrs[i];
714 attr_value = &resource->attrs_value[i];
716 jobj_attr = _get_resource_attr_json(attr, attr_value);
718 json_object_array_add(jobj_res_attrs, jobj_attr);
721 json_object_object_add(jobj_root, "res_name", jobj_res_name);
722 json_object_object_add(jobj_root, "res_type", jobj_res_type);
723 json_object_object_add(jobj_root, "res_attrs", jobj_res_attrs);
725 *json_string = strdup(json_object_to_json_string(jobj_root));
727 for (i = 0; i < json_object_array_length(jobj_res_attrs); i++) {
728 jobj_attr = json_object_array_get_idx(jobj_res_attrs, i);
729 _put_resource_attr_json(jobj_attr);
731 json_object_array_del_idx(jobj_res_attrs, 0, json_object_array_length(jobj_res_attrs));
733 json_object_object_del(jobj_root, "res_attrs");
734 json_object_object_del(jobj_root, "res_type");
735 json_object_object_del(jobj_root, "res_name");
736 json_object_put(jobj_root);
742 syscommon_resman_monitor_get_resource_attr_json(int resource_id, u_int64_t attr_id, char **json_string)
744 const struct syscommon_resman_resource_attribute *attr;
745 const struct syscommon_resman_resource_attribute_value *attr_value;
746 json_object *jobj_attr;
747 struct syscommon_resman_resource *resource = find_resource(resource_id);
749 if (!is_valid_resource(resource, INSTANCE_TYPE_MONITOR))
752 attr = get_resource_attr(resource, attr_id);
753 attr_value = get_resource_attr_value(resource, attr_id);
755 if (!attr || !attr_value)
758 jobj_attr = _get_resource_attr_json(attr, attr_value);
760 *json_string = strdup(json_object_to_json_string(jobj_attr));
762 _put_resource_attr_json(jobj_attr);
768 get_resource_driver_json(const struct syscommon_resman_resource_driver *driver)
770 json_object *jobj_drv, *jobj_drv_name, *jobj_drv_type;
771 json_object *jobj_drv_attrs_array, *jobj_drv_attr, *jobj_drv_ctrls_array, *jobj_drv_ctrl;
772 json_object *jobj_drv_attr_name, *jobj_drv_attr_type, *jobj_drv_attr_id;
773 json_object *jobj_drv_ctrl_name, *jobj_drv_ctrl_id;
774 const struct syscommon_resman_resource_attribute *attr;
775 const struct syscommon_resman_resource_control *ctrl;
778 jobj_drv = json_object_new_object();
780 jobj_drv_name = json_object_new_string(driver->name);
781 jobj_drv_type = json_object_new_int(driver->type);
783 jobj_drv_attrs_array = json_object_new_array();
785 for (i = 0; i < driver->num_attrs; i++) {
786 attr = &driver->attrs[i];
788 jobj_drv_attr = json_object_new_object();
790 jobj_drv_attr_name = json_object_new_string(attr->name);
791 jobj_drv_attr_type = json_object_new_int(attr->type);
792 jobj_drv_attr_id = json_object_new_uint64(attr->id);
794 json_object_object_add(jobj_drv_attr, "name", jobj_drv_attr_name);
795 json_object_object_add(jobj_drv_attr, "type", jobj_drv_attr_type);
796 json_object_object_add(jobj_drv_attr, "id", jobj_drv_attr_id);
798 json_object_array_add(jobj_drv_attrs_array, jobj_drv_attr);
801 jobj_drv_ctrls_array = json_object_new_array();
803 for (i = 0; i < driver->num_ctrls; i++) {
804 ctrl = &driver->ctrls[i];
806 jobj_drv_ctrl = json_object_new_object();
808 jobj_drv_ctrl_name = json_object_new_string(ctrl->name);
809 jobj_drv_ctrl_id = json_object_new_uint64(ctrl->id);
811 json_object_object_add(jobj_drv_ctrl, "name", jobj_drv_ctrl_name);
812 json_object_object_add(jobj_drv_ctrl, "id", jobj_drv_ctrl_id);
814 json_object_array_add(jobj_drv_ctrls_array, jobj_drv_ctrl);
817 json_object_object_add(jobj_drv, "name", jobj_drv_name);
818 json_object_object_add(jobj_drv, "type", jobj_drv_type);
819 json_object_object_add(jobj_drv, "attrs", jobj_drv_attrs_array);
820 json_object_object_add(jobj_drv, "ctrls", jobj_drv_ctrls_array);
825 static void put_resource_driver_json(json_object *jobj_drv)
827 json_object *jobj_array, *jobj_obj;
830 if (json_object_object_get_ex(jobj_drv, "ctrls", &jobj_array)) {
831 for (i = 0; i < json_object_array_length(jobj_array); i++) {
832 jobj_obj = json_object_array_get_idx(jobj_array, i);
834 json_object_object_del(jobj_obj, "id");
835 json_object_object_del(jobj_obj, "name");
837 json_object_array_del_idx(jobj_array, 0, json_object_array_length(jobj_array));
840 if (json_object_object_get_ex(jobj_drv, "attrs", &jobj_array)) {
841 for (i = 0; i < json_object_array_length(jobj_array); i++) {
842 jobj_obj = json_object_array_get_idx(jobj_array, i);
844 json_object_object_del(jobj_obj, "id");
845 json_object_object_del(jobj_obj, "type");
846 json_object_object_del(jobj_obj, "name");
848 json_object_array_del_idx(jobj_array, 0, json_object_array_length(jobj_array));
851 json_object_object_del(jobj_drv, "ctrls");
852 json_object_object_del(jobj_drv, "attrs");
853 json_object_object_del(jobj_drv, "type");
854 json_object_object_del(jobj_drv, "name");
857 int syscommon_resman_get_resource_list_json(char **json_string)
859 const struct syscommon_resman_resource_driver *driver;
860 json_object *jobj_root, *jobj_drvs_array, *jobj_drv;
863 jobj_root = json_object_new_object();
864 jobj_drvs_array = json_object_new_array();
866 for (i = 0; i < g_list_length(g_resource_driver_head); i++) {
867 driver = g_list_nth(g_list_first(g_resource_driver_head), i)->data;
869 jobj_drv = get_resource_driver_json(driver);
870 json_object_array_add(jobj_drvs_array, jobj_drv);
873 json_object_object_add(jobj_root, "resources", jobj_drvs_array);
875 *json_string = strdup(json_object_to_json_string(jobj_root));
877 for (i = 0; i < json_object_array_length(jobj_drvs_array); i++) {
878 jobj_drv = json_object_array_get_idx(jobj_drvs_array, i);
880 put_resource_driver_json(jobj_drv);
882 json_object_array_del_idx(jobj_drvs_array, 0, json_object_array_length(jobj_drvs_array));
884 json_object_object_del(jobj_root, "resources");
885 json_object_put(jobj_root);
891 get_resource_attr_value_data(struct syscommon_resman_resource *resource, u_int64_t attr_id, enum syscommon_resman_data_type type, void *data)
893 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
895 if (!check_attr_validate(resource, attr_id, type))
898 attr_value = get_resource_attr_value(resource, attr_id);
903 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
904 *(int *) data = *((int32_t *) attr_value->data);
906 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
907 *(int64_t *) data = *((int64_t *) attr_value->data);
909 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
910 *(u_int32_t *) data = *((u_int32_t *)attr_value->data);
912 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
913 *(u_int64_t *) data = *((u_int64_t *)attr_value->data);
915 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
916 *(double *) data = *((double *)attr_value->data);
918 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
919 strncpy(data, (char *)attr_value->data, SYSCOMMON_RESMAN_BUFF_MAX);
921 case SYSCOMMON_RESMAN_DATA_TYPE_ARRAY:
922 *(struct syscommon_resman_array_value **) data = (struct syscommon_resman_array_value *)attr_value->data;
924 case SYSCOMMON_RESMAN_DATA_TYPE_PTR:
925 *(void **) data = attr_value->data;
927 case SYSCOMMON_RESMAN_DATA_TYPE_BOOLEAN:
928 case SYSCOMMON_RESMAN_DATA_TYPE_NUM:
937 syscommon_resman_monitor_get_resource_attr_int(int resource_id, u_int64_t attr_id, int32_t *data)
939 struct syscommon_resman_resource *resource = find_resource(resource_id);
941 if (!is_valid_resource(resource, INSTANCE_TYPE_MONITOR))
944 return get_resource_attr_value_data(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_INT, data);
948 syscommon_resman_monitor_get_resource_attr_int64(int resource_id, u_int64_t attr_id, int64_t *data)
950 struct syscommon_resman_resource *resource = find_resource(resource_id);
952 if (!is_valid_resource(resource, INSTANCE_TYPE_MONITOR))
955 return get_resource_attr_value_data(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_INT64, data);
959 syscommon_resman_monitor_get_resource_attr_uint(int resource_id, u_int64_t attr_id, u_int32_t *data)
961 struct syscommon_resman_resource *resource = find_resource(resource_id);
963 if (!is_valid_resource(resource, INSTANCE_TYPE_MONITOR))
966 return get_resource_attr_value_data(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_UINT, data);
970 syscommon_resman_monitor_get_resource_attr_uint64(int resource_id, u_int64_t attr_id, u_int64_t *data)
972 struct syscommon_resman_resource *resource = find_resource(resource_id);
974 if (!is_valid_resource(resource, INSTANCE_TYPE_MONITOR))
977 return get_resource_attr_value_data(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_UINT64, data);
981 syscommon_resman_monitor_get_resource_attr_double(int resource_id, u_int64_t attr_id, double *data)
983 struct syscommon_resman_resource *resource = find_resource(resource_id);
985 if (!is_valid_resource(resource, INSTANCE_TYPE_MONITOR))
988 return get_resource_attr_value_data(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE, data);
992 syscommon_resman_monitor_get_resource_attr_string(int resource_id, u_int64_t attr_id, char *data)
994 struct syscommon_resman_resource *resource = find_resource(resource_id);
996 if (!is_valid_resource(resource, INSTANCE_TYPE_MONITOR))
999 return get_resource_attr_value_data(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_STRING, data);
1003 syscommon_resman_monitor_get_resource_attr_array(int resource_id, u_int64_t attr_id, struct syscommon_resman_array_value **data)
1005 struct syscommon_resman_resource *resource = find_resource(resource_id);
1007 if (!is_valid_resource(resource, INSTANCE_TYPE_MONITOR))
1010 return get_resource_attr_value_data(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_ARRAY, data);
1014 syscommon_resman_monitor_get_resource_attr_ptr(int resource_id, u_int64_t attr_id, void **data)
1016 struct syscommon_resman_resource *resource = find_resource(resource_id);
1018 if (!is_valid_resource(resource, INSTANCE_TYPE_MONITOR))
1021 return get_resource_attr_value_data(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_PTR, data);
1025 is_resource_attr_visible(struct syscommon_resman_resource *resource,
1026 const struct syscommon_resman_resource_attribute *attr)
1028 u_int64_t res_visibility, attr_visibility;
1030 res_visibility = resource->flag & RESOURCE_FLAG_VISIBILITY_MASK;
1031 attr_visibility = attr->flag & RESOURCE_ATTR_FLAG_VISIBILITY_MASK;
1033 /* bigger visibility means smaller privilege */
1034 if (res_visibility > attr_visibility)
1041 set_resource_attr_interest(struct syscommon_resman_resource *resource, u_int64_t interest_mask)
1043 struct syscommon_resman_resource_attribute_value *attr_value;
1050 for (i = 0; i < resource->num_attrs; i++) {
1051 if (!(resource->attrs[i].id & interest_mask))
1054 ret = is_resource_attr_supported(resource, resource->attrs[i].id, &supported);
1057 } else if (!supported) {
1062 if (!is_resource_attr_visible(resource, &resource->attrs[i])) {
1067 attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
1073 if (resource->attrs[i].listener_ops.init) {
1074 ret = resource->attrs[i].listener_ops.init(resource->id, &resource->attrs[i]);
1080 * In resource monitor, each resource has a lot of attributes, but
1081 * only updated attributes are selected by clients on demand. So,
1082 * instead of allocating memory at the resource creation, allocate
1083 * at the set interest.
1085 if (!attr_value->data) {
1086 switch (attr_value->type) {
1087 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
1088 attr_value->data = calloc(1, sizeof(int32_t));
1090 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
1091 attr_value->data = calloc(1, sizeof(int64_t));
1093 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
1094 attr_value->data = calloc(1, sizeof(u_int32_t));
1096 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
1097 attr_value->data = calloc(1, sizeof(u_int64_t));
1099 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
1100 attr_value->data = calloc(1, sizeof(double));
1102 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
1103 attr_value->data = calloc(SYSCOMMON_RESMAN_BUFF_MAX, sizeof(char));
1105 case SYSCOMMON_RESMAN_DATA_TYPE_ARRAY:
1106 attr_value->data = calloc(1, sizeof(struct syscommon_resman_array_value));
1113 if (!attr_value->data) {
1120 resource->attr_interest |= interest_mask;
1125 for (; i >= 0; i--) {
1126 if (!(resource->attrs[i].id & interest_mask))
1129 if (resource->attrs[i].listener_ops.exit)
1130 resource->attrs[i].listener_ops.exit(resource->id, &resource->attrs[i]);
1132 attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
1136 if (attr_value->data) {
1137 free(attr_value->data);
1138 attr_value->data = NULL;
1146 syscommon_resman_set_resource_attr_interest(int resource_id, u_int64_t interest_mask)
1148 struct syscommon_resman_resource *resource = find_resource(resource_id);
1150 return set_resource_attr_interest(resource, interest_mask);
1154 unset_resource_attr_interest(struct syscommon_resman_resource *resource, u_int64_t interest_mask)
1156 struct syscommon_resman_resource_attribute_value *attr_value;
1162 if (!is_resource_attr_interested(resource, interest_mask))
1165 for (i = 0; i < resource->num_attrs; i++) {
1166 if (!(resource->attrs[i].id & interest_mask))
1169 if (resource->attrs[i].listener_ops.exit)
1170 resource->attrs[i].listener_ops.exit(resource->id, &resource->attrs[i]);
1172 attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
1176 if (attr_value->data) {
1177 switch (attr_value->type) {
1178 case SYSCOMMON_RESMAN_DATA_TYPE_ARRAY:
1180 struct syscommon_resman_array_value *array = attr_value->data;
1188 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
1189 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
1190 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
1191 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
1192 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
1193 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
1194 free(attr_value->data);
1195 attr_value->data = NULL;
1203 resource->attr_interest &= ~interest_mask;
1209 syscommon_resman_unset_resource_attr_interest(int resource_id, u_int64_t interest_mask)
1211 struct syscommon_resman_resource *resource = find_resource(resource_id);
1213 return unset_resource_attr_interest(resource, interest_mask);
1217 is_resource_attr_interested(struct syscommon_resman_resource *resource,
1218 u_int64_t interest_mask)
1223 if (resource->attr_interest != (resource->attr_interest | interest_mask))
1230 syscommon_resman_is_resource_attr_interested(int resource_id, u_int64_t interest_mask)
1232 struct syscommon_resman_resource *resource = find_resource(resource_id);
1234 return is_resource_attr_interested(resource, interest_mask);
1238 syscommon_resman_get_resource_attr_name(int resource_id, u_int64_t attr_id)
1240 const struct syscommon_resman_resource_attribute *attr;
1241 struct syscommon_resman_resource *resource = find_resource(resource_id);
1243 attr = get_resource_attr(resource, attr_id);
1251 *syscommon_resman_get_resource_name(int resource_id)
1253 struct syscommon_resman_resource *resource = find_resource(resource_id);
1255 return resource ? resource->name : NULL;
1259 syscommon_resman_get_resource_privdata(int resource_id)
1261 struct syscommon_resman_resource *resource = find_resource(resource_id);
1263 return resource ? resource->priv : NULL;
1267 syscommon_resman_get_resource_type(int resource_id)
1269 struct syscommon_resman_resource *resource = find_resource(resource_id);
1271 return resource ? resource->resource_type : -EINVAL;
1275 syscommon_resman_set_resource_privdata(int resource_id, void *priv)
1277 struct syscommon_resman_resource *resource = find_resource(resource_id);
1282 resource->priv = priv;
1287 static void init_resource_driver(gpointer data, gpointer udata)
1289 struct syscommon_resman_resource_driver *driver = (struct syscommon_resman_resource_driver *) data;
1292 if (driver && driver->ops.init) {
1293 ret = driver->ops.init();
1295 syscommon_resman_remove_resource_driver(driver);
1299 static void exit_resource_driver(gpointer data, gpointer udata)
1301 struct syscommon_resman_resource_driver *driver = (struct syscommon_resman_resource_driver *) data;
1303 if (driver && driver->ops.exit)
1307 void syscommon_resman_init_resource_drivers(void)
1309 g_list_foreach(g_resource_driver_head, init_resource_driver, NULL);
1312 void syscommon_resman_exit_resource_drivers(void)
1314 g_list_foreach(g_resource_driver_head, exit_resource_driver, NULL);