2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include "resource-manager.h"
24 #include "resource-type.h"
26 #define BIT64_INDEX(id) (63 - __builtin_clzll(id))
27 #define RESOURCE_ATTR_INDEX(id) BIT64_INDEX(id)
28 #define RESOURCE_CTRL_INDEX(id) BIT64_INDEX(id)
29 #define RESOURCE_FLAG_VISIBILITY_MASK (SYSCOMMON_RESMAN_RESOURCE_FLAG_PRIVATE \
30 | SYSCOMMON_RESMAN_RESOURCE_FLAG_PUBLIC)
31 #define RESOURCE_ATTR_FLAG_VISIBILITY_MASK (SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PRIVATE \
32 | SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC)
34 struct syscommon_resman_resource {
37 const struct syscommon_resman_resource_driver *driver;
41 const struct syscommon_resman_resource_attribute *attrs;
42 struct syscommon_resman_resource_attribute_value *attrs_value;
44 const struct syscommon_resman_resource_control *ctrls;
50 u_int64_t attr_interest;
51 u_int64_t attr_supported;
54 static int unset_resource_attr_interest(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
55 static bool is_resource_attr_interested(struct syscommon_resman_resource *resource, u_int64_t interest_mask);
57 static GList *g_resource_driver_head;
58 static GHashTable *g_resource_hash_table;
60 static int clear_sign_bit(unsigned int val)
62 return (int)((val << 1) >> 1);
65 static int init_resource_id(void)
70 gettimeofday(&tv, NULL);
71 val = tv.tv_sec * 1000 + tv.tv_usec / 1000;
72 return clear_sign_bit(val);
75 static int alloc_resource_id(void)
77 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
78 static int resource_id = -1;
81 pthread_mutex_lock(&lock);
84 resource_id = init_resource_id();
87 resource_id = clear_sign_bit(resource_id + 1);
89 pthread_mutex_unlock(&lock);
94 static void free_resource(struct syscommon_resman_resource *resource)
97 resource->name = NULL;
99 unset_resource_attr_interest(resource, resource->attr_interest);
100 free(resource->attrs_value);
101 resource->attrs_value = NULL;
103 resource->attrs = NULL;
104 resource->num_attrs = 0;
109 static void delete_resource(void *data)
111 struct syscommon_resman_resource *resource = (struct syscommon_resman_resource *) data;
116 if (resource->driver && resource->driver->ops.delete)
117 resource->driver->ops.delete(resource->id);
119 free_resource(resource);
122 static int add_resource(struct syscommon_resman_resource *resource)
127 if (!g_resource_hash_table) {
128 g_resource_hash_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, delete_resource);
129 if (!g_resource_hash_table)
133 g_hash_table_insert(g_resource_hash_table, GINT_TO_POINTER(resource->id), resource);
138 static struct syscommon_resman_resource * find_resource(int id)
140 if (!g_resource_hash_table)
143 return g_hash_table_lookup(g_resource_hash_table, GINT_TO_POINTER(id));
146 static gint __compare_resource_type(gconstpointer data, gconstpointer input)
148 struct syscommon_resman_resource_driver *driver;
149 int type = *(int *)input;
151 driver = (struct syscommon_resman_resource_driver *)data;
153 if (driver && driver->type == type)
158 const struct syscommon_resman_resource_driver *
159 syscommon_resman_find_resource_driver(int resource_type)
163 node = g_list_find_custom(g_resource_driver_head,
164 &resource_type, __compare_resource_type);
168 return (struct syscommon_resman_resource_driver *)node->data;
172 syscommon_resman_add_resource_driver(const struct syscommon_resman_resource_driver *driver)
177 g_resource_driver_head =
178 g_list_append(g_resource_driver_head, (gpointer)driver);
182 syscommon_resman_remove_resource_driver(const struct syscommon_resman_resource_driver *driver)
187 g_resource_driver_head =
188 g_list_remove(g_resource_driver_head, (gpointer)driver);
191 void syscommon_resman_delete_resource(int resource_id)
193 if (!g_resource_hash_table)
196 g_hash_table_remove(g_resource_hash_table, GINT_TO_POINTER(resource_id));
200 syscommon_resman_create_resource(int *resource_id, int resource_type)
202 const struct syscommon_resman_resource_driver *driver = NULL;
203 struct syscommon_resman_resource *resource = NULL;
209 driver = syscommon_resman_find_resource_driver(resource_type);
213 resource = calloc(1, sizeof(*resource));
217 resource->id = alloc_resource_id();
218 resource->type = resource_type;
219 resource->name = g_strdup(driver->name);
220 resource->driver = driver;
221 resource->num_attrs = driver->num_attrs;
222 resource->attrs = driver->attrs;
223 resource->attrs_value = calloc(resource->num_attrs,
224 sizeof(*resource->attrs_value));
225 if (!resource->attrs_value) {
226 free_resource(resource);
230 ret = add_resource(resource);
232 free_resource(resource);
236 for (i = 0; i < resource->num_attrs; i++)
237 resource->attrs_value[i].type = driver->attrs[i].type;
239 resource->ctrls = driver->ctrls;
240 resource->num_ctrls = driver->num_ctrls;
241 resource->flag = SYSCOMMON_RESMAN_RESOURCE_FLAG_PRIVATE;
243 if (driver->ops.create) {
244 ret = driver->ops.create(resource->id);
246 free_resource(resource);
251 *resource_id = resource->id;
257 syscommon_resman_set_resource_flag(int resource_id, u_int64_t flag_mask)
259 struct syscommon_resman_resource *resource = find_resource(resource_id);
264 resource->flag = flag_mask;
269 syscommon_resman_set_resource_control(int resource_id, u_int64_t ctrl_id, const void *data)
271 const struct syscommon_resman_resource_control *ctrl;
272 int ctrl_index = RESOURCE_CTRL_INDEX(ctrl_id);
274 struct syscommon_resman_resource *resource = find_resource(resource_id);
276 if (!resource || ctrl_index < 0 || ctrl_index >= resource->num_ctrls)
279 ctrl = &resource->ctrls[ctrl_index];
283 ret = ctrl->ops.set(resource_id, ctrl, data);
291 syscommon_resman_get_resource_control_name(int resource_id, u_int64_t ctrl_id)
293 const struct syscommon_resman_resource_control *ctrl;
294 int ctrl_index = RESOURCE_CTRL_INDEX(ctrl_id);
295 struct syscommon_resman_resource *resource = find_resource(resource_id);
297 if (!resource || ctrl_index < 0 || ctrl_index >= resource->num_ctrls)
300 ctrl = &resource->ctrls[ctrl_index];
306 update_resource_attr(struct syscommon_resman_resource *resource,
309 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
310 const struct syscommon_resman_resource_attribute *attr = NULL;
311 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
314 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs)
317 attr = &resource->attrs[attr_index];
322 attr_value = &resource->attrs_value[attr_index];
324 ret = attr->ops.get(resource->id, attr, attr_value->data);
332 syscommon_resman_update_resource_attrs(int resource_id)
335 struct syscommon_resman_resource *resource = find_resource(resource_id);
337 if (!resource || !resource->type)
340 if (resource->driver && resource->driver->ops.prepare_update) {
341 ret = resource->driver->ops.prepare_update(resource->id);
346 for (i = 0; i < resource->num_attrs; i++) {
347 if (!(resource->attrs[i].id & resource->attr_interest))
349 update_resource_attr(resource, resource->attrs[i].id);
355 static const struct syscommon_resman_resource_attribute *
356 get_resource_attr(struct syscommon_resman_resource *resource, u_int64_t attr_id)
358 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
360 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs)
363 return &resource->attrs[attr_index];
366 const struct syscommon_resman_resource_attribute *
367 syscommon_resman_get_resource_attr(int resource_id, u_int64_t attr_id)
369 struct syscommon_resman_resource *resource = find_resource(resource_id);
371 return get_resource_attr(resource, attr_id);
375 static struct syscommon_resman_resource_attribute_value *
376 get_resource_attr_value(struct syscommon_resman_resource *resource, u_int64_t attr_id)
378 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
380 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs)
383 return &resource->attrs_value[attr_index];
386 struct syscommon_resman_resource_attribute_value *
387 syscommon_resman_get_resource_attr_value(int resource_id, u_int64_t attr_id)
389 struct syscommon_resman_resource *resource = find_resource(resource_id);
391 return get_resource_attr_value(resource, attr_id);
394 static int is_resource_attr_supported(struct syscommon_resman_resource *resource, u_int64_t attr_id, bool *supported)
396 const struct syscommon_resman_resource_attribute *attr = NULL;
397 int attr_index = RESOURCE_ATTR_INDEX(attr_id);
399 bool is_supported = false;
401 if (!resource || attr_index < 0 || attr_index >= resource->num_attrs) {
406 attr = &resource->attrs[attr_index];
408 if (attr->id & resource->attr_supported) {
410 } else if (attr->ops.is_supported) {
411 is_supported = attr->ops.is_supported(resource->id, attr);
412 } else if (attr->ops.get) {
414 * Optionally, if .is_supported ops is not implemented,
415 * use .get ops in order to check whether the resource attribute
416 * is supported or not.
418 char data[SYSCOMMON_RESMAN_BUFF_MAX] = {0, };
420 ret = attr->ops.get(resource->id, attr, (void *)data);
421 is_supported = (ret < 0) ? false : true;
425 resource->attr_supported |= attr->id;
427 *supported = is_supported;
433 syscommon_resman_is_resource_attr_supported(int resource_id, u_int64_t attr_id, bool *supported)
435 struct syscommon_resman_resource *resource = find_resource(resource_id);
437 return is_resource_attr_supported(resource, attr_id, supported);
441 check_attr_validate(struct syscommon_resman_resource *resource,
442 u_int64_t attr_id, int type)
444 const struct syscommon_resman_resource_attribute *attr;
446 attr = get_resource_attr(resource, attr_id);
450 if (attr->type != type)
453 if (!(attr->id & resource->attr_interest))
460 _get_resource_attr_json(const struct syscommon_resman_resource_attribute *attr,
461 const struct syscommon_resman_resource_attribute_value *attr_value)
463 json_object *jobj_attr, *jobj_attr_name, *jobj_attr_type, *jobj_attr_value, *jobj_temp;
464 struct syscommon_resman_array_value *array;
467 switch (attr->type) {
468 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
469 jobj_attr_value = json_object_new_int(*((int32_t *)attr_value->data));
471 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
472 jobj_attr_value = json_object_new_int(*((u_int32_t *)attr_value->data));
474 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
475 jobj_attr_value = json_object_new_int64(*((int64_t *)attr_value->data));
477 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
478 jobj_attr_value = json_object_new_uint64(*((u_int64_t *)attr_value->data));
480 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
481 jobj_attr_value = json_object_new_double(*((double *)attr_value->data));
483 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
484 jobj_attr_value = json_object_new_string((char *)attr_value->data);
486 case SYSCOMMON_RESMAN_DATA_TYPE_ARRAY:
487 array = attr_value->data;
489 jobj_attr_value = json_object_new_array();
491 switch (array->type) {
492 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
493 for (i = 0; i < array->length; i++) {
494 int32_t *item = array->data;
496 jobj_temp = json_object_new_int(item[i]);
497 json_object_array_add(jobj_attr_value, jobj_temp);
500 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
501 for (i = 0; i < array->length; i++) {
502 u_int32_t *item = array->data;
504 jobj_temp = json_object_new_int(item[i]);
505 json_object_array_add(jobj_attr_value, jobj_temp);
508 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
509 for (i = 0; i < array->length; i++) {
510 int64_t *item = array->data;
512 jobj_temp = json_object_new_int64(item[i]);
513 json_object_array_add(jobj_attr_value, jobj_temp);
516 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
517 for (i = 0; i < array->length; i++) {
518 u_int64_t *item = array->data;
520 jobj_temp = json_object_new_uint64(item[i]);
521 json_object_array_add(jobj_attr_value, jobj_temp);
524 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
525 for (i = 0; i < array->length; i++) {
526 double *item = array->data;
528 jobj_temp = json_object_new_double(item[i]);
529 json_object_array_add(jobj_attr_value, jobj_temp);
532 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
533 for (i = 0; i < array->length; i++) {
534 char **item = array->data;
536 jobj_temp = json_object_new_string(item[i]);
537 json_object_array_add(jobj_attr_value, jobj_temp);
541 json_object_put(jobj_attr_value);
542 jobj_attr_value = json_object_new_null();
546 jobj_attr_value = json_object_new_null();
548 jobj_attr = json_object_new_object();
550 jobj_attr_name = json_object_new_string(attr->name);
552 * Since actually JSON format has no data type limitation itself, in many
553 * cases except converting JSON into json-c, type is not required. So,
554 * for the case of converting JSON generated here to json-c object again
555 * json_type is stored in each attributes.
557 jobj_attr_type = json_object_new_int(json_object_get_type(jobj_attr_value));
559 json_object_object_add(jobj_attr, "name", jobj_attr_name);
560 json_object_object_add(jobj_attr, "json_type", jobj_attr_type);
561 json_object_object_add(jobj_attr, "value", jobj_attr_value);
566 static void _put_resource_attr_json(json_object *jobj_attr)
568 json_object *jobj_attr_value;
570 json_object_object_del(jobj_attr, "name");
571 json_object_object_del(jobj_attr, "json_type");
573 if (json_object_object_get_ex(jobj_attr, "value", &jobj_attr_value) &&
574 json_object_is_type(jobj_attr_value, json_type_array))
575 json_object_array_del_idx(jobj_attr_value, 0,
576 json_object_array_length(jobj_attr_value));
578 json_object_object_del(jobj_attr, "value");
582 syscommon_resman_get_resource_attrs_json(int resource_id, char **json_string)
584 json_object *jobj_root, *jobj_res_name, *jobj_res_type, *jobj_res_attrs, *jobj_attr;
585 const struct syscommon_resman_resource_attribute *attr;
586 const struct syscommon_resman_resource_attribute_value *attr_value;
587 struct syscommon_resman_resource *resource = find_resource(resource_id);
590 if (!resource || !resource->type)
593 jobj_root = json_object_new_object();
595 jobj_res_name = json_object_new_string(resource->name);
596 jobj_res_type = json_object_new_int(resource->type);
597 jobj_res_attrs = json_object_new_array();
599 for (i = 0; i < resource->num_attrs; i++) {
600 if (!(resource->attrs[i].id & resource->attr_interest))
603 attr = &resource->attrs[i];
604 attr_value = &resource->attrs_value[i];
606 jobj_attr = _get_resource_attr_json(attr, attr_value);
608 json_object_array_add(jobj_res_attrs, jobj_attr);
611 json_object_object_add(jobj_root, "res_name", jobj_res_name);
612 json_object_object_add(jobj_root, "res_type", jobj_res_type);
613 json_object_object_add(jobj_root, "res_attrs", jobj_res_attrs);
615 *json_string = strdup(json_object_to_json_string(jobj_root));
617 for (i = 0; i < json_object_array_length(jobj_res_attrs); i++) {
618 jobj_attr = json_object_array_get_idx(jobj_res_attrs, i);
619 _put_resource_attr_json(jobj_attr);
621 json_object_array_del_idx(jobj_res_attrs, 0, json_object_array_length(jobj_res_attrs));
623 json_object_object_del(jobj_root, "res_attrs");
624 json_object_object_del(jobj_root, "res_type");
625 json_object_object_del(jobj_root, "res_name");
626 json_object_put(jobj_root);
632 syscommon_resman_get_resource_attr_json(int resource_id, u_int64_t attr_id, char **json_string)
634 const struct syscommon_resman_resource_attribute *attr;
635 const struct syscommon_resman_resource_attribute_value *attr_value;
636 json_object *jobj_attr;
637 struct syscommon_resman_resource *resource = find_resource(resource_id);
639 attr = get_resource_attr(resource, attr_id);
640 attr_value = get_resource_attr_value(resource, attr_id);
642 if (!attr || !attr_value)
645 jobj_attr = _get_resource_attr_json(attr, attr_value);
647 *json_string = strdup(json_object_to_json_string(jobj_attr));
649 _put_resource_attr_json(jobj_attr);
655 get_resource_driver_json(const struct syscommon_resman_resource_driver *driver)
657 json_object *jobj_drv, *jobj_drv_name, *jobj_drv_type;
658 json_object *jobj_drv_attrs_array, *jobj_drv_attr, *jobj_drv_ctrls_array, *jobj_drv_ctrl;
659 json_object *jobj_drv_attr_name, *jobj_drv_attr_type, *jobj_drv_attr_id;
660 json_object *jobj_drv_ctrl_name, *jobj_drv_ctrl_id;
661 const struct syscommon_resman_resource_attribute *attr;
662 const struct syscommon_resman_resource_control *ctrl;
665 jobj_drv = json_object_new_object();
667 jobj_drv_name = json_object_new_string(driver->name);
668 jobj_drv_type = json_object_new_int(driver->type);
670 jobj_drv_attrs_array = json_object_new_array();
672 for (i = 0; i < driver->num_attrs; i++) {
673 attr = &driver->attrs[i];
675 jobj_drv_attr = json_object_new_object();
677 jobj_drv_attr_name = json_object_new_string(attr->name);
678 jobj_drv_attr_type = json_object_new_int(attr->type);
679 jobj_drv_attr_id = json_object_new_uint64(attr->id);
681 json_object_object_add(jobj_drv_attr, "name", jobj_drv_attr_name);
682 json_object_object_add(jobj_drv_attr, "type", jobj_drv_attr_type);
683 json_object_object_add(jobj_drv_attr, "id", jobj_drv_attr_id);
685 json_object_array_add(jobj_drv_attrs_array, jobj_drv_attr);
688 jobj_drv_ctrls_array = json_object_new_array();
690 for (i = 0; i < driver->num_ctrls; i++) {
691 ctrl = &driver->ctrls[i];
693 jobj_drv_ctrl = json_object_new_object();
695 jobj_drv_ctrl_name = json_object_new_string(ctrl->name);
696 jobj_drv_ctrl_id = json_object_new_uint64(ctrl->id);
698 json_object_object_add(jobj_drv_ctrl, "name", jobj_drv_ctrl_name);
699 json_object_object_add(jobj_drv_ctrl, "id", jobj_drv_ctrl_id);
701 json_object_array_add(jobj_drv_ctrls_array, jobj_drv_ctrl);
704 json_object_object_add(jobj_drv, "name", jobj_drv_name);
705 json_object_object_add(jobj_drv, "type", jobj_drv_type);
706 json_object_object_add(jobj_drv, "attrs", jobj_drv_attrs_array);
707 json_object_object_add(jobj_drv, "ctrls", jobj_drv_ctrls_array);
712 static void put_resource_driver_json(json_object *jobj_drv)
714 json_object *jobj_array, *jobj_obj;
717 if (json_object_object_get_ex(jobj_drv, "ctrls", &jobj_array)) {
718 for (i = 0; i < json_object_array_length(jobj_array); i++) {
719 jobj_obj = json_object_array_get_idx(jobj_array, i);
721 json_object_object_del(jobj_obj, "id");
722 json_object_object_del(jobj_obj, "name");
724 json_object_array_del_idx(jobj_array, 0, json_object_array_length(jobj_array));
727 if (json_object_object_get_ex(jobj_drv, "attrs", &jobj_array)) {
728 for (i = 0; i < json_object_array_length(jobj_array); i++) {
729 jobj_obj = json_object_array_get_idx(jobj_array, i);
731 json_object_object_del(jobj_obj, "id");
732 json_object_object_del(jobj_obj, "type");
733 json_object_object_del(jobj_obj, "name");
735 json_object_array_del_idx(jobj_array, 0, json_object_array_length(jobj_array));
738 json_object_object_del(jobj_drv, "ctrls");
739 json_object_object_del(jobj_drv, "attrs");
740 json_object_object_del(jobj_drv, "type");
741 json_object_object_del(jobj_drv, "name");
744 int syscommon_resman_get_resource_list_json(char **json_string)
746 const struct syscommon_resman_resource_driver *driver;
747 json_object *jobj_root, *jobj_drvs_array, *jobj_drv;
750 jobj_root = json_object_new_object();
751 jobj_drvs_array = json_object_new_array();
753 for (i = 0; i < g_list_length(g_resource_driver_head); i++) {
754 driver = g_list_nth(g_list_first(g_resource_driver_head), i)->data;
756 jobj_drv = get_resource_driver_json(driver);
757 json_object_array_add(jobj_drvs_array, jobj_drv);
760 json_object_object_add(jobj_root, "resources", jobj_drvs_array);
762 *json_string = strdup(json_object_to_json_string(jobj_root));
764 for (i = 0; i < json_object_array_length(jobj_drvs_array); i++) {
765 jobj_drv = json_object_array_get_idx(jobj_drvs_array, i);
767 put_resource_driver_json(jobj_drv);
769 json_object_array_del_idx(jobj_drvs_array, 0, json_object_array_length(jobj_drvs_array));
771 json_object_object_del(jobj_root, "resources");
772 json_object_put(jobj_root);
778 syscommon_resman_get_resource_attr_int(int resource_id, u_int64_t attr_id, int32_t *data)
780 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
781 struct syscommon_resman_resource *resource = find_resource(resource_id);
783 if (!check_attr_validate(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_INT))
786 attr_value = get_resource_attr_value(resource, attr_id);
790 *data = *((int32_t *)attr_value->data);
796 syscommon_resman_get_resource_attr_int_sync(int resource_id, u_int64_t attr_id, int32_t *data)
800 ret = update_resource_attr(find_resource(resource_id), attr_id);
804 return syscommon_resman_get_resource_attr_int(resource_id, attr_id, data);
808 syscommon_resman_get_resource_attr_int64(int resource_id, u_int64_t attr_id, int64_t *data)
810 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
811 struct syscommon_resman_resource *resource = find_resource(resource_id);
813 if (!check_attr_validate(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_INT64))
816 attr_value = get_resource_attr_value(resource, attr_id);
820 *data = *((int64_t *)attr_value->data);
826 syscommon_resman_get_resource_attr_int64_sync(int resource_id, u_int64_t attr_id, int64_t *data)
830 ret = update_resource_attr(find_resource(resource_id), attr_id);
834 return syscommon_resman_get_resource_attr_int64(resource_id, attr_id, data);
838 syscommon_resman_get_resource_attr_uint(int resource_id, u_int64_t attr_id, u_int32_t *data)
840 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
841 struct syscommon_resman_resource *resource = find_resource(resource_id);
843 if (!check_attr_validate(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_UINT))
846 attr_value = get_resource_attr_value(resource, attr_id);
850 *data = *((u_int32_t *)attr_value->data);
856 syscommon_resman_get_resource_attr_uint_sync(int resource_id, u_int64_t attr_id, u_int32_t *data)
860 ret = update_resource_attr(find_resource(resource_id), attr_id);
864 return syscommon_resman_get_resource_attr_uint(resource_id, attr_id, data);
868 syscommon_resman_get_resource_attr_uint64(int resource_id, u_int64_t attr_id, u_int64_t *data)
870 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
871 struct syscommon_resman_resource *resource = find_resource(resource_id);
873 if (!check_attr_validate(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_UINT64))
876 attr_value = get_resource_attr_value(resource, attr_id);
880 *data = *((u_int64_t *)attr_value->data);
886 syscommon_resman_get_resource_attr_uint64_sync(int resource_id, u_int64_t attr_id, u_int64_t *data)
890 ret = update_resource_attr(find_resource(resource_id), attr_id);
894 return syscommon_resman_get_resource_attr_uint64(resource_id, attr_id, data);
898 syscommon_resman_get_resource_attr_double(int resource_id, u_int64_t attr_id, double *data)
900 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
901 struct syscommon_resman_resource *resource = find_resource(resource_id);
903 if (!check_attr_validate(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE))
906 attr_value = get_resource_attr_value(resource, attr_id);
910 *data = *((double *)attr_value->data);
916 syscommon_resman_get_resource_attr_double_sync(int resource_id, u_int64_t attr_id, double *data)
920 ret = update_resource_attr(find_resource(resource_id), attr_id);
924 return syscommon_resman_get_resource_attr_double(resource_id, attr_id, data);
928 syscommon_resman_get_resource_attr_string(int resource_id, u_int64_t attr_id, char *data)
930 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
931 struct syscommon_resman_resource *resource = find_resource(resource_id);
933 if (!check_attr_validate(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_STRING))
936 attr_value = get_resource_attr_value(resource, attr_id);
940 strncpy(data, (char *)attr_value->data, SYSCOMMON_RESMAN_BUFF_MAX);
946 syscommon_resman_get_resource_attr_string_sync(int resource_id, u_int64_t attr_id, char *data)
950 ret = update_resource_attr(find_resource(resource_id), attr_id);
954 return syscommon_resman_get_resource_attr_string(resource_id, attr_id, data);
958 syscommon_resman_get_resource_attr_array(int resource_id, u_int64_t attr_id, struct syscommon_resman_array_value **data)
960 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
961 struct syscommon_resman_resource *resource = find_resource(resource_id);
963 if (!check_attr_validate(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_ARRAY))
966 attr_value = get_resource_attr_value(resource, attr_id);
970 *data = (struct syscommon_resman_array_value *)attr_value->data;
976 syscommon_resman_get_resource_attr_array_sync(int resource_id, u_int64_t attr_id, struct syscommon_resman_array_value **data)
980 ret = update_resource_attr(find_resource(resource_id), attr_id);
984 return syscommon_resman_get_resource_attr_array(resource_id, attr_id, data);
988 syscommon_resman_get_resource_attr_ptr(int resource_id, u_int64_t attr_id, void **data)
990 struct syscommon_resman_resource_attribute_value *attr_value = NULL;
991 struct syscommon_resman_resource *resource = find_resource(resource_id);
993 if (!check_attr_validate(resource, attr_id, SYSCOMMON_RESMAN_DATA_TYPE_PTR))
996 attr_value = get_resource_attr_value(resource, attr_id);
1000 *data = attr_value->data;
1006 syscommon_resman_get_resource_attr_ptr_sync(int resource_id, u_int64_t attr_id, void **data)
1010 ret = update_resource_attr(find_resource(resource_id), attr_id);
1014 return syscommon_resman_get_resource_attr_ptr(resource_id, attr_id, data);
1018 is_resource_attr_visible(struct syscommon_resman_resource *resource,
1019 const struct syscommon_resman_resource_attribute *attr)
1021 u_int64_t res_visibility, attr_visibility;
1023 res_visibility = resource->flag & RESOURCE_FLAG_VISIBILITY_MASK;
1024 attr_visibility = attr->flag & RESOURCE_ATTR_FLAG_VISIBILITY_MASK;
1026 /* bigger visibility means smaller privilege */
1027 if (res_visibility > attr_visibility)
1034 syscommon_resman_set_resource_attr_interest(int resource_id, u_int64_t interest_mask)
1036 struct syscommon_resman_resource_attribute_value *attr_value;
1039 struct syscommon_resman_resource *resource = find_resource(resource_id);
1044 for (i = 0; i < resource->num_attrs; i++) {
1045 if (!(resource->attrs[i].id & interest_mask))
1048 ret = is_resource_attr_supported(resource,
1049 resource->attrs[i].id,
1053 } else if (!supported) {
1058 if (!is_resource_attr_visible(resource, &resource->attrs[i])) {
1063 attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
1070 * In resource monitor, each resource has a lot of attributes, but
1071 * only updated attributes are selected by clients on demand. So,
1072 * instead of allocating memory at the resource creation, allocate
1073 * at the set interest.
1075 if (!attr_value->data) {
1076 switch (attr_value->type) {
1077 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
1078 attr_value->data = calloc(1, sizeof(int32_t));
1080 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
1081 attr_value->data = calloc(1, sizeof(int64_t));
1083 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
1084 attr_value->data = calloc(1, sizeof(u_int32_t));
1086 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
1087 attr_value->data = calloc(1, sizeof(u_int64_t));
1089 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
1090 attr_value->data = calloc(1, sizeof(double));
1092 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
1093 attr_value->data = calloc(SYSCOMMON_RESMAN_BUFF_MAX, sizeof(char));
1095 case SYSCOMMON_RESMAN_DATA_TYPE_ARRAY:
1096 attr_value->data = calloc(1, sizeof(struct syscommon_resman_array_value));
1103 if (!attr_value->data) {
1110 resource->attr_interest |= interest_mask;
1115 for (; i >= 0; i--) {
1116 if (!(resource->attrs[i].id & interest_mask))
1119 attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
1123 if (attr_value->data) {
1124 free(attr_value->data);
1125 attr_value->data = NULL;
1133 unset_resource_attr_interest(struct syscommon_resman_resource *resource, u_int64_t interest_mask)
1135 struct syscommon_resman_resource_attribute_value *attr_value;
1141 if (!is_resource_attr_interested(resource, interest_mask))
1144 for (i = 0; i < resource->num_attrs; i++) {
1145 if (!(resource->attrs[i].id & interest_mask))
1148 attr_value = get_resource_attr_value(resource, resource->attrs[i].id);
1152 if (attr_value->data) {
1153 switch (attr_value->type) {
1154 case SYSCOMMON_RESMAN_DATA_TYPE_ARRAY:
1156 struct syscommon_resman_array_value *array = attr_value->data;
1164 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
1165 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
1166 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
1167 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
1168 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
1169 case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
1170 free(attr_value->data);
1171 attr_value->data = NULL;
1179 resource->attr_interest &= ~interest_mask;
1185 syscommon_resman_unset_resource_attr_interest(int resource_id, u_int64_t interest_mask)
1187 struct syscommon_resman_resource *resource = find_resource(resource_id);
1189 return unset_resource_attr_interest(resource, interest_mask);
1193 is_resource_attr_interested(struct syscommon_resman_resource *resource,
1194 u_int64_t interest_mask)
1199 if (resource->attr_interest != (resource->attr_interest | interest_mask))
1206 syscommon_resman_is_resource_attr_interested(int resource_id, u_int64_t interest_mask)
1208 struct syscommon_resman_resource *resource = find_resource(resource_id);
1210 return is_resource_attr_interested(resource, interest_mask);
1214 syscommon_resman_get_resource_attr_name(int resource_id, u_int64_t attr_id)
1216 const struct syscommon_resman_resource_attribute *attr;
1217 struct syscommon_resman_resource *resource = find_resource(resource_id);
1219 attr = get_resource_attr(resource, attr_id);
1227 *syscommon_resman_get_resource_name(int resource_id)
1229 struct syscommon_resman_resource *resource = find_resource(resource_id);
1231 return resource ? resource->name : NULL;
1235 syscommon_resman_get_resource_privdata(int resource_id)
1237 struct syscommon_resman_resource *resource = find_resource(resource_id);
1239 return resource ? resource->priv : NULL;
1243 syscommon_resman_get_resource_type(int resource_id)
1245 struct syscommon_resman_resource *resource = find_resource(resource_id);
1247 return resource ? resource->type : -EINVAL;
1251 syscommon_resman_set_resource_privdata(int resource_id, void *priv)
1253 struct syscommon_resman_resource *resource = find_resource(resource_id);
1258 resource->priv = priv;
1263 static void init_resource_driver(gpointer data, gpointer udata)
1265 struct syscommon_resman_resource_driver *driver = (struct syscommon_resman_resource_driver *) data;
1268 if (driver && driver->ops.init) {
1269 ret = driver->ops.init();
1271 syscommon_resman_remove_resource_driver(driver);
1275 static void exit_resource_driver(gpointer data, gpointer udata)
1277 struct syscommon_resman_resource_driver *driver = (struct syscommon_resman_resource_driver *) data;
1279 if (driver && driver->ops.exit)
1283 void syscommon_resman_init_resource_drivers(void)
1285 g_list_foreach(g_resource_driver_head, init_resource_driver, NULL);
1288 void syscommon_resman_exit_resource_drivers(void)
1290 g_list_foreach(g_resource_driver_head, exit_resource_driver, NULL);