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
29 #include "resource-manager.h"
30 #include "resource-type.h"
32 #define BIT64_INDEX(id) (63 - __builtin_clzll(id))
33 #define RESOURCE_ATTR_INDEX(id) BIT64_INDEX(id)
34 #define RESOURCE_CTRL_INDEX(id) BIT64_INDEX(id)
35 #define RESOURCE_FLAG_VISIBILITY_MASK (SYSCOMMON_RESMAN_RESOURCE_FLAG_PRIVATE \
36 | SYSCOMMON_RESMAN_RESOURCE_FLAG_PUBLIC)
37 #define RESOURCE_ATTR_FLAG_VISIBILITY_MASK (SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PRIVATE \
38 | SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC)
40 struct syscommon_resman_resource {
43 const struct syscommon_resman_resource_driver *driver;
47 const struct syscommon_resman_resource_attribute *attrs;
48 struct syscommon_resman_resource_attribute_value *attrs_value;
50 const struct syscommon_resman_resource_control *ctrls;
56 u_int64_t attr_interest;
57 u_int64_t attr_supported;
60 static int unset_resource_attr_interest(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
61 static bool is_resource_attr_interested(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
63 static GList *g_resource_driver_head;
64 static GHashTable *g_resource_hash_table;
66 static int clear_sign_bit(unsigned int val)
68 return (int)((val << 1) >> 1);
71 static int init_resource_id(void)
76 gettimeofday(&tv, NULL);
77 val = tv.tv_sec * 1000 + tv.tv_usec / 1000;
78 return clear_sign_bit(val);
81 static int alloc_resource_id(void)
83 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
84 static int resource_id = -1;
87 pthread_mutex_lock(&lock);
90 resource_id = init_resource_id();
93 resource_id = clear_sign_bit(resource_id + 1);
95 pthread_mutex_unlock(&lock);
100 static void free_resource(struct syscommon_resman_resource *resource)
102 free(resource->name);
103 resource->name = NULL;
105 unset_resource_attr_interest(resource, resource->attr_interest);
106 free(resource->attrs_value);
107 resource->attrs_value = NULL;
109 resource->attrs = NULL;
110 resource->num_attrs = 0;
115 static void delete_resource(void *data)
117 struct syscommon_resman_resource *resource = (struct syscommon_resman_resource *) data;
122 if (resource->driver && resource->driver->ops.delete)
123 resource->driver->ops.delete(resource->id);
125 free_resource(resource);
128 static int add_resource(struct syscommon_resman_resource *resource)
133 if (!g_resource_hash_table) {
134 g_resource_hash_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, delete_resource);
135 if (!g_resource_hash_table)
139 g_hash_table_insert(g_resource_hash_table, GINT_TO_POINTER(resource->id), resource);
144 static struct syscommon_resman_resource * find_resource(int id)
146 if (!g_resource_hash_table)
149 return g_hash_table_lookup(g_resource_hash_table, GINT_TO_POINTER(id));
152 static gint __compare_resource_type(gconstpointer data, gconstpointer input)
154 struct syscommon_resman_resource_driver *driver;
155 int type = *(int *)input;
157 driver = (struct syscommon_resman_resource_driver *)data;
159 if (driver && driver->type == type)
164 const struct syscommon_resman_resource_driver *
165 syscommon_resman_find_resource_driver(int resource_type)
169 node = g_list_find_custom(g_resource_driver_head,
170 &resource_type, __compare_resource_type);
174 return (struct syscommon_resman_resource_driver *)node->data;
178 syscommon_resman_add_resource_driver(const struct syscommon_resman_resource_driver *driver)
183 g_resource_driver_head =
184 g_list_append(g_resource_driver_head, (gpointer)driver);
188 syscommon_resman_remove_resource_driver(const struct syscommon_resman_resource_driver *driver)
193 g_resource_driver_head =
194 g_list_remove(g_resource_driver_head, (gpointer)driver);
197 void syscommon_resman_delete_resource(int resource_id)
199 if (!g_resource_hash_table)
202 g_hash_table_remove(g_resource_hash_table, GINT_TO_POINTER(resource_id));
206 syscommon_resman_create_resource(int *resource_id, int resource_type)
208 const struct syscommon_resman_resource_driver *driver = NULL;
209 struct syscommon_resman_resource *resource = NULL;
215 driver = syscommon_resman_find_resource_driver(resource_type);
219 resource = calloc(1, sizeof(*resource));
223 resource->id = alloc_resource_id();
224 resource->type = resource_type;
225 resource->name = g_strdup(driver->name);
226 resource->driver = driver;
227 resource->num_attrs = driver->num_attrs;
228 resource->attrs = driver->attrs;
229 resource->attrs_value = calloc(resource->num_attrs,
230 sizeof(*resource->attrs_value));
231 if (!resource->attrs_value) {
232 free_resource(resource);
236 ret = add_resource(resource);
238 free_resource(resource);
242 for (i = 0; i < resource->num_attrs; i++)
243 resource->attrs_value[i].type = driver->attrs[i].type;
245 resource->ctrls = driver->ctrls;
246 resource->num_ctrls = driver->num_ctrls;
247 resource->flag = SYSCOMMON_RESMAN_RESOURCE_FLAG_PRIVATE;
249 if (driver->ops.create) {
250 ret = driver->ops.create(resource->id);
252 free_resource(resource);
257 *resource_id = resource->id;
263 syscommon_resman_set_resource_flag(int resource_id, u_int64_t flag_mask)
265 struct syscommon_resman_resource *resource = find_resource(resource_id);
270 resource->flag = flag_mask;
275 syscommon_resman_set_resource_control(int resource_id, u_int64_t ctrl_id, const void *data)
277 const struct syscommon_resman_resource_control *ctrl;
278 int ctrl_index = RESOURCE_CTRL_INDEX(ctrl_id);
280 struct syscommon_resman_resource *resource = find_resource(resource_id);
282 if (!resource || ctrl_index < 0 || ctrl_index >= resource->num_ctrls)
285 ctrl = &resource->ctrls[ctrl_index];
289 ret = ctrl->ops.set(resource_id, ctrl, data);
297 syscommon_resman_get_resource_control_name(int resource_id, u_int64_t ctrl_id)
299 const struct syscommon_resman_resource_control *ctrl;
300 int ctrl_index = RESOURCE_CTRL_INDEX(ctrl_id);
301 struct syscommon_resman_resource *resource = find_resource(resource_id);
303 if (!resource || ctrl_index < 0 || ctrl_index >= resource->num_ctrls)
306 ctrl = &resource->ctrls[ctrl_index];
312 monitor_update_resource_attr(struct syscommon_resman_resource *resource,
315 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
316 const struct syscommon_resman_resource_attribute *attr = NULL;
317 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
320 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs)
323 attr = &resource->attrs[attr_index];
325 if (!attr->monitor_ops.get)
328 attr_value = &resource->attrs_value[attr_index];
330 ret = attr->monitor_ops.get(resource->id, attr, attr_value->data);
338 syscommon_resman_monitor_update_resource_attrs(int resource_id)
341 struct syscommon_resman_resource *resource = find_resource(resource_id);
343 if (!resource || !resource->type)
346 if (resource->driver && resource->driver->ops.prepare_update) {
347 ret = resource->driver->ops.prepare_update(resource->id);
352 for (i = 0; i < resource->num_attrs; i++) {
353 if (!(resource->attrs[i].id & resource->attr_interest))
355 monitor_update_resource_attr(resource, resource->attrs[i].id);
361 static const struct syscommon_resman_resource_attribute *
362 get_resource_attr(struct syscommon_resman_resource *resource, u_int64_t attr_id)
364 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
366 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs)
369 return &resource->attrs[attr_index];
372 const struct syscommon_resman_resource_attribute *
373 syscommon_resman_get_resource_attr(int resource_id, u_int64_t attr_id)
375 struct syscommon_resman_resource *resource = find_resource(resource_id);
377 return get_resource_attr(resource, attr_id);
381 static struct syscommon_resman_resource_attribute_value *
382 get_resource_attr_value(struct syscommon_resman_resource *resource, u_int64_t attr_id)
384 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
386 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs)
389 return &resource->attrs_value[attr_index];
392 struct syscommon_resman_resource_attribute_value *
393 syscommon_resman_get_resource_attr_value(int resource_id, u_int64_t attr_id)
395 struct syscommon_resman_resource *resource = find_resource(resource_id);
397 return get_resource_attr_value(resource, attr_id);
400 static int monitor_is_resource_attr_supported(struct syscommon_resman_resource *resource, u_int64_t attr_id, bool *supported)
402 const struct syscommon_resman_resource_attribute *attr = NULL;
403 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
405 bool is_supported = false;
407 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs) {
412 attr = &resource->attrs[attr_index];
414 if (attr->id & resource->attr_supported) {
416 } else if (attr->monitor_ops.is_supported) {
417 is_supported = attr->monitor_ops.is_supported(resource->id, attr);
418 } else if (attr->monitor_ops.get) {
420 * Optionally, if .is_supported ops is not implemented,
421 * use .get ops in order to check whether the resource attribute
422 * is supported or not.
424 char data[SYSCOMMON_RESMAN_BUFF_MAX] = {0, };
426 ret = attr->monitor_ops.get(resource->id, attr, (void *)data);
427 is_supported = (ret < 0) ? false : true;
431 resource->attr_supported |= attr->id;
433 *supported = is_supported;
439 syscommon_resman_monitor_is_resource_attr_supported(int resource_id, u_int64_t attr_id, bool *supported)
441 struct syscommon_resman_resource *resource = find_resource(resource_id);
443 return monitor_is_resource_attr_supported(resource, attr_id, supported);
447 check_attr_validate(struct syscommon_resman_resource *resource,
448 u_int64_t attr_id, int type)
450 const struct syscommon_resman_resource_attribute *attr;
452 attr = get_resource_attr(resource, attr_id);
456 if (attr->type != type)
459 if (!(attr->id & resource->attr_interest))
466 _get_resource_attr_json(const struct syscommon_resman_resource_attribute *attr,
467 const struct syscommon_resman_resource_attribute_value *attr_value)
469 json_object *jobj_attr, *jobj_attr_name, *jobj_attr_type, *jobj_attr_value, *jobj_temp;
470 struct syscommon_resman_array_value *array;
473 switch (attr->type) {
474 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
475 jobj_attr_value = json_object_new_int(*((int32_t *)attr_value->data));
477 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
478 jobj_attr_value = json_object_new_int(*((u_int32_t *)attr_value->data));
480 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
481 jobj_attr_value = json_object_new_int64(*((int64_t *)attr_value->data));
483 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
484 jobj_attr_value = json_object_new_uint64(*((u_int64_t *)attr_value->data));
486 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
487 jobj_attr_value = json_object_new_double(*((double *)attr_value->data));
489 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
490 jobj_attr_value = json_object_new_string((char *)attr_value->data);
492 case SYSCOMMON_RESMAN_DATA_TYPE_ARRAY:
493 array = attr_value->data;
495 jobj_attr_value = json_object_new_array();
497 switch (array->type) {
498 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
499 for (i = 0; i < array->length; i++) {
500 int32_t *item = array->data;
502 jobj_temp = json_object_new_int(item[i]);
503 json_object_array_add(jobj_attr_value, jobj_temp);
506 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
507 for (i = 0; i < array->length; i++) {
508 u_int32_t *item = array->data;
510 jobj_temp = json_object_new_int(item[i]);
511 json_object_array_add(jobj_attr_value, jobj_temp);
514 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
515 for (i = 0; i < array->length; i++) {
516 int64_t *item = array->data;
518 jobj_temp = json_object_new_int64(item[i]);
519 json_object_array_add(jobj_attr_value, jobj_temp);
522 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
523 for (i = 0; i < array->length; i++) {
524 u_int64_t *item = array->data;
526 jobj_temp = json_object_new_uint64(item[i]);
527 json_object_array_add(jobj_attr_value, jobj_temp);
530 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
531 for (i = 0; i < array->length; i++) {
532 double *item = array->data;
534 jobj_temp = json_object_new_double(item[i]);
535 json_object_array_add(jobj_attr_value, jobj_temp);
538 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
539 for (i = 0; i < array->length; i++) {
540 char **item = array->data;
542 jobj_temp = json_object_new_string(item[i]);
543 json_object_array_add(jobj_attr_value, jobj_temp);
547 json_object_put(jobj_attr_value);
548 jobj_attr_value = json_object_new_null();
552 jobj_attr_value = json_object_new_null();
554 jobj_attr = json_object_new_object();
556 jobj_attr_name = json_object_new_string(attr->name);
558 * Since actually JSON format has no data type limitation itself, in many
559 * cases except converting JSON into json-c, type is not required. So,
560 * for the case of converting JSON generated here to json-c object again
561 * json_type is stored in each attributes.
563 jobj_attr_type = json_object_new_int(json_object_get_type(jobj_attr_value));
565 json_object_object_add(jobj_attr, "name", jobj_attr_name);
566 json_object_object_add(jobj_attr, "json_type", jobj_attr_type);
567 json_object_object_add(jobj_attr, "value", jobj_attr_value);
572 static void _put_resource_attr_json(json_object *jobj_attr)
574 json_object *jobj_attr_value;
576 json_object_object_del(jobj_attr, "name");
577 json_object_object_del(jobj_attr, "json_type");
579 if (json_object_object_get_ex(jobj_attr, "value", &jobj_attr_value) &&
580 json_object_is_type(jobj_attr_value, json_type_array))
581 json_object_array_del_idx(jobj_attr_value, 0,
582 json_object_array_length(jobj_attr_value));
584 json_object_object_del(jobj_attr, "value");
588 syscommon_resman_monitor_get_resource_attrs_json(int resource_id, char **json_string)
590 json_object *jobj_root, *jobj_res_name, *jobj_res_type, *jobj_res_attrs, *jobj_attr;
591 const struct syscommon_resman_resource_attribute *attr;
592 const struct syscommon_resman_resource_attribute_value *attr_value;
593 struct syscommon_resman_resource *resource = find_resource(resource_id);
596 if (!resource || !resource->type)
599 jobj_root = json_object_new_object();
601 jobj_res_name = json_object_new_string(resource->name);
602 jobj_res_type = json_object_new_int(resource->type);
603 jobj_res_attrs = json_object_new_array();
605 for (i = 0; i < resource->num_attrs; i++) {
606 if (!(resource->attrs[i].id & resource->attr_interest))
609 attr = &resource->attrs[i];
610 attr_value = &resource->attrs_value[i];
612 jobj_attr = _get_resource_attr_json(attr, attr_value);
614 json_object_array_add(jobj_res_attrs, jobj_attr);
617 json_object_object_add(jobj_root, "res_name", jobj_res_name);
618 json_object_object_add(jobj_root, "res_type", jobj_res_type);
619 json_object_object_add(jobj_root, "res_attrs", jobj_res_attrs);
621 *json_string = strdup(json_object_to_json_string(jobj_root));
623 for (i = 0; i < json_object_array_length(jobj_res_attrs); i++) {
624 jobj_attr = json_object_array_get_idx(jobj_res_attrs, i);
625 _put_resource_attr_json(jobj_attr);
627 json_object_array_del_idx(jobj_res_attrs, 0, json_object_array_length(jobj_res_attrs));
629 json_object_object_del(jobj_root, "res_attrs");
630 json_object_object_del(jobj_root, "res_type");
631 json_object_object_del(jobj_root, "res_name");
632 json_object_put(jobj_root);
638 syscommon_resman_monitor_get_resource_attr_json(int resource_id, u_int64_t attr_id, char **json_string)
640 const struct syscommon_resman_resource_attribute *attr;
641 const struct syscommon_resman_resource_attribute_value *attr_value;
642 json_object *jobj_attr;
643 struct syscommon_resman_resource *resource = find_resource(resource_id);
645 attr = get_resource_attr(resource, attr_id);
646 attr_value = get_resource_attr_value(resource, attr_id);
648 if (!attr || !attr_value)
651 jobj_attr = _get_resource_attr_json(attr, attr_value);
653 *json_string = strdup(json_object_to_json_string(jobj_attr));
655 _put_resource_attr_json(jobj_attr);
661 get_resource_driver_json(const struct syscommon_resman_resource_driver *driver)
663 json_object *jobj_drv, *jobj_drv_name, *jobj_drv_type;
664 json_object *jobj_drv_attrs_array, *jobj_drv_attr, *jobj_drv_ctrls_array, *jobj_drv_ctrl;
665 json_object *jobj_drv_attr_name, *jobj_drv_attr_type, *jobj_drv_attr_id;
666 json_object *jobj_drv_ctrl_name, *jobj_drv_ctrl_id;
667 const struct syscommon_resman_resource_attribute *attr;
668 const struct syscommon_resman_resource_control *ctrl;
671 jobj_drv = json_object_new_object();
673 jobj_drv_name = json_object_new_string(driver->name);
674 jobj_drv_type = json_object_new_int(driver->type);
676 jobj_drv_attrs_array = json_object_new_array();
678 for (i = 0; i < driver->num_attrs; i++) {
679 attr = &driver->attrs[i];
681 jobj_drv_attr = json_object_new_object();
683 jobj_drv_attr_name = json_object_new_string(attr->name);
684 jobj_drv_attr_type = json_object_new_int(attr->type);
685 jobj_drv_attr_id = json_object_new_uint64(attr->id);
687 json_object_object_add(jobj_drv_attr, "name", jobj_drv_attr_name);
688 json_object_object_add(jobj_drv_attr, "type", jobj_drv_attr_type);
689 json_object_object_add(jobj_drv_attr, "id", jobj_drv_attr_id);
691 json_object_array_add(jobj_drv_attrs_array, jobj_drv_attr);
694 jobj_drv_ctrls_array = json_object_new_array();
696 for (i = 0; i < driver->num_ctrls; i++) {
697 ctrl = &driver->ctrls[i];
699 jobj_drv_ctrl = json_object_new_object();
701 jobj_drv_ctrl_name = json_object_new_string(ctrl->name);
702 jobj_drv_ctrl_id = json_object_new_uint64(ctrl->id);
704 json_object_object_add(jobj_drv_ctrl, "name", jobj_drv_ctrl_name);
705 json_object_object_add(jobj_drv_ctrl, "id", jobj_drv_ctrl_id);
707 json_object_array_add(jobj_drv_ctrls_array, jobj_drv_ctrl);
710 json_object_object_add(jobj_drv, "name", jobj_drv_name);
711 json_object_object_add(jobj_drv, "type", jobj_drv_type);
712 json_object_object_add(jobj_drv, "attrs", jobj_drv_attrs_array);
713 json_object_object_add(jobj_drv, "ctrls", jobj_drv_ctrls_array);
718 static void put_resource_driver_json(json_object *jobj_drv)
720 json_object *jobj_array, *jobj_obj;
723 if (json_object_object_get_ex(jobj_drv, "ctrls", &jobj_array)) {
724 for (i = 0; i < json_object_array_length(jobj_array); i++) {
725 jobj_obj = json_object_array_get_idx(jobj_array, i);
727 json_object_object_del(jobj_obj, "id");
728 json_object_object_del(jobj_obj, "name");
730 json_object_array_del_idx(jobj_array, 0, json_object_array_length(jobj_array));
733 if (json_object_object_get_ex(jobj_drv, "attrs", &jobj_array)) {
734 for (i = 0; i < json_object_array_length(jobj_array); i++) {
735 jobj_obj = json_object_array_get_idx(jobj_array, i);
737 json_object_object_del(jobj_obj, "id");
738 json_object_object_del(jobj_obj, "type");
739 json_object_object_del(jobj_obj, "name");
741 json_object_array_del_idx(jobj_array, 0, json_object_array_length(jobj_array));
744 json_object_object_del(jobj_drv, "ctrls");
745 json_object_object_del(jobj_drv, "attrs");
746 json_object_object_del(jobj_drv, "type");
747 json_object_object_del(jobj_drv, "name");
750 int syscommon_resman_get_resource_list_json(char **json_string)
752 const struct syscommon_resman_resource_driver *driver;
753 json_object *jobj_root, *jobj_drvs_array, *jobj_drv;
756 jobj_root = json_object_new_object();
757 jobj_drvs_array = json_object_new_array();
759 for (i = 0; i < g_list_length(g_resource_driver_head); i++) {
760 driver = g_list_nth(g_list_first(g_resource_driver_head), i)->data;
762 jobj_drv = get_resource_driver_json(driver);
763 json_object_array_add(jobj_drvs_array, jobj_drv);
766 json_object_object_add(jobj_root, "resources", jobj_drvs_array);
768 *json_string = strdup(json_object_to_json_string(jobj_root));
770 for (i = 0; i < json_object_array_length(jobj_drvs_array); i++) {
771 jobj_drv = json_object_array_get_idx(jobj_drvs_array, i);
773 put_resource_driver_json(jobj_drv);
775 json_object_array_del_idx(jobj_drvs_array, 0, json_object_array_length(jobj_drvs_array));
777 json_object_object_del(jobj_root, "resources");
778 json_object_put(jobj_root);
784 get_resource_attr_value_data(int resource_id, u_int64_t attr_id, enum syscommon_resman_data_type type, void *data)
786 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
787 struct syscommon_resman_resource *resource = find_resource(resource_id);
789 if (!check_attr_validate(resource, attr_id, type))
792 attr_value = get_resource_attr_value(resource, attr_id);
797 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
798 *(int *) data = *((int32_t *) attr_value->data);
800 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
801 *(int64_t *) data = *((int64_t *) attr_value->data);
803 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
804 *(u_int32_t *) data = *((u_int32_t *)attr_value->data);
806 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
807 *(u_int64_t *) data = *((u_int64_t *)attr_value->data);
809 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
810 *(double *) data = *((double *)attr_value->data);
812 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
813 strncpy(data, (char *)attr_value->data, SYSCOMMON_RESMAN_BUFF_MAX);
815 case SYSCOMMON_RESMAN_DATA_TYPE_ARRAY:
816 *(struct syscommon_resman_array_value **) data = (struct syscommon_resman_array_value *)attr_value->data;
818 case SYSCOMMON_RESMAN_DATA_TYPE_PTR:
819 *(void **) data = attr_value->data;
821 case SYSCOMMON_RESMAN_DATA_TYPE_BOOLEAN:
822 case SYSCOMMON_RESMAN_DATA_TYPE_NUM:
831 syscommon_resman_monitor_get_resource_attr_int(int resource_id, u_int64_t attr_id, int32_t *data)
833 return get_resource_attr_value_data(resource_id, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_INT, data);
837 syscommon_resman_monitor_get_resource_attr_int64(int resource_id, u_int64_t attr_id, int64_t *data)
839 return get_resource_attr_value_data(resource_id, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_INT64, data);
843 syscommon_resman_monitor_get_resource_attr_uint(int resource_id, u_int64_t attr_id, u_int32_t *data)
845 return get_resource_attr_value_data(resource_id, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_UINT, data);
849 syscommon_resman_monitor_get_resource_attr_uint64(int resource_id, u_int64_t attr_id, u_int64_t *data)
851 return get_resource_attr_value_data(resource_id, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_UINT64, data);
855 syscommon_resman_monitor_get_resource_attr_double(int resource_id, u_int64_t attr_id, double *data)
857 return get_resource_attr_value_data(resource_id, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE, data);
861 syscommon_resman_monitor_get_resource_attr_string(int resource_id, u_int64_t attr_id, char *data)
863 return get_resource_attr_value_data(resource_id, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_STRING, data);
867 syscommon_resman_monitor_get_resource_attr_array(int resource_id, u_int64_t attr_id, struct syscommon_resman_array_value **data)
869 return get_resource_attr_value_data(resource_id, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_ARRAY, data);
873 syscommon_resman_monitor_get_resource_attr_ptr(int resource_id, u_int64_t attr_id, void **data)
875 return get_resource_attr_value_data(resource_id, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_PTR, data);
879 is_resource_attr_visible(struct syscommon_resman_resource *resource,
880 const struct syscommon_resman_resource_attribute *attr)
882 u_int64_t res_visibility, attr_visibility;
884 res_visibility = resource->flag & RESOURCE_FLAG_VISIBILITY_MASK;
885 attr_visibility = attr->flag & RESOURCE_ATTR_FLAG_VISIBILITY_MASK;
887 /* bigger visibility means smaller privilege */
888 if (res_visibility > attr_visibility)
895 syscommon_resman_set_resource_attr_interest(int resource_id, u_int64_t interest_mask)
897 struct syscommon_resman_resource_attribute_value *attr_value;
900 struct syscommon_resman_resource *resource = find_resource(resource_id);
905 for (i = 0; i < resource->num_attrs; i++) {
906 if (!(resource->attrs[i].id & interest_mask))
909 ret = monitor_is_resource_attr_supported(resource,
910 resource->attrs[i].id,
914 } else if (!supported) {
919 if (!is_resource_attr_visible(resource, &resource->attrs[i])) {
924 attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
930 if (resource->attrs[i].listener_ops.init) {
931 ret = resource->attrs[i].listener_ops.init(resource_id, &resource->attrs[i]);
937 * In resource monitor, each resource has a lot of attributes, but
938 * only updated attributes are selected by clients on demand. So,
939 * instead of allocating memory at the resource creation, allocate
940 * at the set interest.
942 if (!attr_value->data) {
943 switch (attr_value->type) {
944 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
945 attr_value->data = calloc(1, sizeof(int32_t));
947 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
948 attr_value->data = calloc(1, sizeof(int64_t));
950 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
951 attr_value->data = calloc(1, sizeof(u_int32_t));
953 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
954 attr_value->data = calloc(1, sizeof(u_int64_t));
956 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
957 attr_value->data = calloc(1, sizeof(double));
959 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
960 attr_value->data = calloc(SYSCOMMON_RESMAN_BUFF_MAX, sizeof(char));
962 case SYSCOMMON_RESMAN_DATA_TYPE_ARRAY:
963 attr_value->data = calloc(1, sizeof(struct syscommon_resman_array_value));
970 if (!attr_value->data) {
977 resource->attr_interest |= interest_mask;
982 for (; i >= 0; i--) {
983 if (!(resource->attrs[i].id & interest_mask))
986 if (resource->attrs[i].listener_ops.exit)
987 resource->attrs[i].listener_ops.exit(resource_id, &resource->attrs[i]);
989 attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
993 if (attr_value->data) {
994 free(attr_value->data);
995 attr_value->data = NULL;
1003 unset_resource_attr_interest(struct syscommon_resman_resource *resource, u_int64_t interest_mask)
1005 struct syscommon_resman_resource_attribute_value *attr_value;
1011 if (!is_resource_attr_interested(resource, interest_mask))
1014 for (i = 0; i < resource->num_attrs; i++) {
1015 if (!(resource->attrs[i].id & interest_mask))
1018 if (resource->attrs[i].listener_ops.exit)
1019 resource->attrs[i].listener_ops.exit(resource->id, &resource->attrs[i]);
1021 attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
1025 if (attr_value->data) {
1026 switch (attr_value->type) {
1027 case SYSCOMMON_RESMAN_DATA_TYPE_ARRAY:
1029 struct syscommon_resman_array_value *array = attr_value->data;
1037 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
1038 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
1039 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
1040 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
1041 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
1042 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
1043 free(attr_value->data);
1044 attr_value->data = NULL;
1052 resource->attr_interest &= ~interest_mask;
1058 syscommon_resman_unset_resource_attr_interest(int resource_id, u_int64_t interest_mask)
1060 struct syscommon_resman_resource *resource = find_resource(resource_id);
1062 return unset_resource_attr_interest(resource, interest_mask);
1066 is_resource_attr_interested(struct syscommon_resman_resource *resource,
1067 u_int64_t interest_mask)
1072 if (resource->attr_interest != (resource->attr_interest | interest_mask))
1079 syscommon_resman_is_resource_attr_interested(int resource_id, u_int64_t interest_mask)
1081 struct syscommon_resman_resource *resource = find_resource(resource_id);
1083 return is_resource_attr_interested(resource, interest_mask);
1087 syscommon_resman_get_resource_attr_name(int resource_id, u_int64_t attr_id)
1089 const struct syscommon_resman_resource_attribute *attr;
1090 struct syscommon_resman_resource *resource = find_resource(resource_id);
1092 attr = get_resource_attr(resource, attr_id);
1100 *syscommon_resman_get_resource_name(int resource_id)
1102 struct syscommon_resman_resource *resource = find_resource(resource_id);
1104 return resource ? resource->name : NULL;
1108 syscommon_resman_get_resource_privdata(int resource_id)
1110 struct syscommon_resman_resource *resource = find_resource(resource_id);
1112 return resource ? resource->priv : NULL;
1116 syscommon_resman_get_resource_type(int resource_id)
1118 struct syscommon_resman_resource *resource = find_resource(resource_id);
1120 return resource ? resource->type : -EINVAL;
1124 syscommon_resman_set_resource_privdata(int resource_id, void *priv)
1126 struct syscommon_resman_resource *resource = find_resource(resource_id);
1131 resource->priv = priv;
1136 static void init_resource_driver(gpointer data, gpointer udata)
1138 struct syscommon_resman_resource_driver *driver = (struct syscommon_resman_resource_driver *) data;
1141 if (driver && driver->ops.init) {
1142 ret = driver->ops.init();
1144 syscommon_resman_remove_resource_driver(driver);
1148 static void exit_resource_driver(gpointer data, gpointer udata)
1150 struct syscommon_resman_resource_driver *driver = (struct syscommon_resman_resource_driver *) data;
1152 if (driver && driver->ops.exit)
1156 void syscommon_resman_init_resource_drivers(void)
1158 g_list_foreach(g_resource_driver_head, init_resource_driver, NULL);
1161 void syscommon_resman_exit_resource_drivers(void)
1163 g_list_foreach(g_resource_driver_head, exit_resource_driver, NULL);