From 046f40d3d2caf77e8b02675855ad145ae1280dc7 Mon Sep 17 00:00:00 2001 From: YoungHun Kim Date: Tue, 3 Dec 2019 09:30:26 +0900 Subject: [PATCH] Add new api of stream and instance for multi-instance Change-Id: I5d940ac9704fec6f354d68f4a82d41c3c3f7956f --- packaging/mm-resource-manager.spec | 2 +- packaging/org.tizen.MMResourceManager.xml | 1 + src/common/mm_resource_manager_utils.c | 13 +- src/common/mm_resource_manager_utils.h | 6 +- src/daemon/backend/mm_resource_manager_backend.c | 19 +- .../backend/murphy/mm_resource_manager_backend.c | 9 +- .../backend/murphy/mm_resource_manager_rset.c | 11 +- src/daemon/mm_resource_manager_daemon.c | 15 +- src/daemon/mm_resource_manager_daemon_conf.c | 79 ++-- src/daemon/mm_resource_manager_daemon_conf.h | 6 +- src/daemon/mm_resource_manager_daemon_dbus.c | 45 +- src/daemon/mm_resource_manager_daemon_dbus.h | 2 +- src/daemon/mm_resource_manager_daemon_priv.c | 512 +++++++++++---------- src/daemon/mm_resource_manager_daemon_priv.h | 1 + src/lib/mm_resource_manager.c | 11 + src/lib/mm_resource_manager.h | 32 +- src/lib/mm_resource_manager_priv.c | 116 +++-- src/lib/mm_resource_manager_priv.h | 2 + test/mm_res_manager_test.c | 60 +-- 19 files changed, 514 insertions(+), 428 deletions(-) diff --git a/packaging/mm-resource-manager.spec b/packaging/mm-resource-manager.spec index 8231ee9..02ab0e9 100644 --- a/packaging/mm-resource-manager.spec +++ b/packaging/mm-resource-manager.spec @@ -1,6 +1,6 @@ Name: mm-resource-manager Summary: A Multimedia Resource Manager API -Version: 0.2.19 +Version: 0.2.20 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/packaging/org.tizen.MMResourceManager.xml b/packaging/org.tizen.MMResourceManager.xml index 242bebf..1e583a2 100644 --- a/packaging/org.tizen.MMResourceManager.xml +++ b/packaging/org.tizen.MMResourceManager.xml @@ -4,6 +4,7 @@ + diff --git a/src/common/mm_resource_manager_utils.c b/src/common/mm_resource_manager_utils.c index 93ef5d2..57c533b 100644 --- a/src/common/mm_resource_manager_utils.c +++ b/src/common/mm_resource_manager_utils.c @@ -20,7 +20,7 @@ -static const char* mm_resource_manager_res_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX] = { +static const char *mm_resource_manager_res_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX] = { "video_decoder", "video_overlay", "camera", @@ -29,34 +29,33 @@ static const char* mm_resource_manager_res_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX] "audio_offload" }; -static const char* mm_resource_manager_app_class_str[MM_RESOURCE_MANAGER_APP_CLASS_MAX] = { +static const char *mm_resource_manager_app_class_str[MM_RESOURCE_MANAGER_APP_CLASS_MAX] = { "media", "interrupt" }; -static const char* mm_resource_manager_condition_str[MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX] = { +static const char *mm_resource_manager_condition_str[MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX] = { "SD", "HD", "FHD", "UHD" }; - -const char* _mm_resource_manager_get_res_str(mm_resource_manager_res_type_e type) +const char *_mm_resource_manager_get_res_str(mm_resource_manager_res_type_e type) { MM_RM_RETVM_IF(type < 0 || type >= MM_RESOURCE_MANAGER_RES_TYPE_MAX, "", "Type is out of range"); return mm_resource_manager_res_str[type]; } -const char* _mm_resource_manager_get_app_class_str(mm_resource_manager_app_class_e cls) +const char *_mm_resource_manager_get_app_class_str(mm_resource_manager_app_class_e cls) { MM_RM_RETVM_IF(cls < 0 || cls >= MM_RESOURCE_MANAGER_APP_CLASS_MAX, "", "App class is out of range"); return mm_resource_manager_app_class_str[cls]; } -const char* _mm_resource_manager_get_condition_str(mm_resource_manager_res_type_cond_e cond) +const char *_mm_resource_manager_get_condition_str(mm_resource_manager_res_type_cond_e cond) { MM_RM_RETVM_IF(cond < 0 || cond >= MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX, "", "Resource type condition is out of range"); diff --git a/src/common/mm_resource_manager_utils.h b/src/common/mm_resource_manager_utils.h index d1277df..8d7ca1c 100644 --- a/src/common/mm_resource_manager_utils.h +++ b/src/common/mm_resource_manager_utils.h @@ -115,9 +115,9 @@ var = var ^ (var >> 31); \ } while (0) -#define MM_RESOURCE_MANAGER_NO_RES -2 -#define MM_RESOURCE_MANAGER_NO_APP_CLASS -1 -#define RELEASE_CB_SYNC_PATH "/tmp/.mm-res-mgr.fifo" +#define MM_RESOURCE_MANAGER_NO_RES (-2) +#define MM_RESOURCE_MANAGER_NO_APP_CLASS (-1) +#define RELEASE_CB_SYNC_PATH "/tmp/.mm-res-mgr.fifo" typedef uint64_t mm_resource_manager_id; diff --git a/src/daemon/backend/mm_resource_manager_backend.c b/src/daemon/backend/mm_resource_manager_backend.c index a607d83..ac35b6d 100644 --- a/src/daemon/backend/mm_resource_manager_backend.c +++ b/src/daemon/backend/mm_resource_manager_backend.c @@ -15,6 +15,7 @@ */ #include "daemon/backend/mm_resource_manager_backend.h" +#include "daemon/mm_resource_manager_daemon_conf.h" #include "common/mm_resource_manager_utils.h" @@ -33,8 +34,6 @@ int _mm_resource_manager_backend_deinit(void); int _mm_resource_manager_backend_acquire(mm_resource_manager_res_type_e type); int _mm_resource_manager_backend_release(mm_resource_manager_res_type_e type); - - static mm_resource_manager_backend_res_s resources[MM_RESOURCE_MANAGER_RES_TYPE_MAX]; @@ -70,6 +69,10 @@ int mm_resource_manager_backend_deinit(void) int mm_resource_manager_backend_acquire(mm_resource_manager_res_type_e type) { + MM_RM_RETVM_IF(type < MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER || + type >= MM_RESOURCE_MANAGER_RES_TYPE_MAX, + MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "wrong type %d", type); + resources[type].ref_counter++; return MM_RESOURCE_MANAGER_ERROR_NONE; @@ -77,12 +80,16 @@ int mm_resource_manager_backend_acquire(mm_resource_manager_res_type_e type) int mm_resource_manager_backend_release(mm_resource_manager_res_type_e type) { + MM_RM_RETVM_IF(type < MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER || + type >= MM_RESOURCE_MANAGER_RES_TYPE_MAX, + MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "wrong type %d", type); + if (resources[type].ref_counter > 0) { resources[type].ref_counter--; return MM_RESOURCE_MANAGER_ERROR_NONE; } else { - MM_RM_ERROR("Reference counter is 0 already"); + MM_RM_ERROR("Reference counter is already 0"); return MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION; } } @@ -119,16 +126,14 @@ int mm_resource_manager_backend_commit(mm_resource_manager_res_type_e type) return ret; } -gboolean mm_resource_manager_backend_commit_all() +gboolean mm_resource_manager_backend_commit_all(void) { int i; gboolean error = FALSE; for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) { - if (mm_resource_manager_backend_commit(i) != - MM_RESOURCE_MANAGER_ERROR_NONE) { + if (mm_resource_manager_backend_commit(i) != MM_RESOURCE_MANAGER_ERROR_NONE) error = TRUE; - } } return !error; diff --git a/src/daemon/backend/murphy/mm_resource_manager_backend.c b/src/daemon/backend/murphy/mm_resource_manager_backend.c index d8fde6d..71d0f2b 100644 --- a/src/daemon/backend/murphy/mm_resource_manager_backend.c +++ b/src/daemon/backend/murphy/mm_resource_manager_backend.c @@ -56,7 +56,7 @@ int _mm_resource_manager_backend_init(void) return MM_RESOURCE_MANAGER_ERROR_NONE; } -int _mm_resource_manager_backend_deinit() +int _mm_resource_manager_backend_deinit(void) { int ret; @@ -83,6 +83,7 @@ int _mm_resource_manager_backend_acquire(mm_resource_manager_res_type_e type) MM_RM_ERROR("Failed to get is_run property from mloop"); return ret; } + if (!is_run) { MM_RM_ERROR("mloop is not ran"); return MM_RESOURCE_MANAGER_ERROR_INVALID_STATE; @@ -140,8 +141,6 @@ int _mm_resource_manager_backend_release(mm_resource_manager_res_type_e type) return MM_RESOURCE_MANAGER_ERROR_NONE; } - - static void __mm_resource_manager_mloop_error_cb(mm_resource_manager_mloop_s *mrp, mm_resource_manager_mloop_error_e err, void *user_data) { @@ -166,13 +165,13 @@ static int __mm_resource_manager_add_resource( ret = _mm_resource_manager_rset_set_release_cb(rset[type], __mm_resource_manager_release_cb, NULL); if (MM_RESOURCE_MANAGER_ERROR_NONE != ret) { - MM_RM_ERROR("Failed to set release callback to resource set %p", rset[type]); + MM_RM_ERROR("Failed to set release callback to resource set %p 0x%x", rset[type], ret); return ret; } ret = _mm_resource_manager_rset_add_resource(rset[type], type); if (MM_RESOURCE_MANAGER_ERROR_NONE != ret) { - MM_RM_ERROR("Failed to add resource to resource set"); + MM_RM_ERROR("Failed to add resource to resource set 0x%x", ret); return ret; } diff --git a/src/daemon/backend/murphy/mm_resource_manager_rset.c b/src/daemon/backend/murphy/mm_resource_manager_rset.c index 0e2d511..88278ed 100644 --- a/src/daemon/backend/murphy/mm_resource_manager_rset.c +++ b/src/daemon/backend/murphy/mm_resource_manager_rset.c @@ -213,7 +213,7 @@ int _mm_resource_manager_rset_destroy(mm_resource_manager_rset_s *rset) MM_RM_ERROR("Timeout elapsed"); ret = MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION; } else { - MM_RM_INFO("Released rset %p", rset); + MM_RM_INFO("Released rset %p [%s]", rset, _mm_resource_manager_get_res_str(rset->type)); ret = MM_RESOURCE_MANAGER_ERROR_NONE; } } @@ -238,12 +238,9 @@ static void _mm_resource_manager_rset_release_cb(mrp_res_context_t *cx, { mm_resource_manager_rset_s *rset = NULL; - if (!user_data) { - MM_RM_ERROR("user data must be not NULL"); - return; - } + MM_RM_RETM_IF(NULL == user_data, "user data must be not NULL"); - rset = (mm_resource_manager_rset_s *) user_data; + rset = (mm_resource_manager_rset_s *) user_data; MM_RM_INFO("Release callback was triggered for rset %p", rset); g_mutex_lock(&rset->lock); @@ -268,7 +265,7 @@ static void _mm_resource_manager_rset_state_callback(mrp_res_context_t *cx, cons return; } - MM_RM_INFO(" - resource set state (%p) is changed to [%s]", rs, state_str[rs->state]); + MM_RM_INFO(" -- resource set state (%p) is changed to [%s]", rs, state_str[rs->state]); for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) { res = mrp_res_get_resource_by_name(rs, _mm_resource_manager_get_res_str(i)); if (res == NULL) diff --git a/src/daemon/mm_resource_manager_daemon.c b/src/daemon/mm_resource_manager_daemon.c index ccedc8a..8153e07 100644 --- a/src/daemon/mm_resource_manager_daemon.c +++ b/src/daemon/mm_resource_manager_daemon.c @@ -43,14 +43,14 @@ int notify_fd[2]; static gboolean fork_wait(void); static daemonize_result_e daemonize(const char *path); static gboolean init_event(gpointer user_data); -static void daemon_loop(); +static void daemon_loop(void); static gboolean remove_pid_file(void); static gboolean remove_ready_file(void); static gboolean remove_daemon_setup_file(void); -static int set_signal_handlers(); +static int set_signal_handlers(void); static void terminate_handler(int signum); static void reload_conf_handler(int signum); -static void quit_main_loop(); +static void quit_main_loop(void); @@ -121,15 +121,14 @@ static gboolean init_event(gpointer user_data) return G_SOURCE_REMOVE; } -static void daemon_loop() +static void daemon_loop(void) { guint id = 0; do { restart = FALSE; - MM_RM_RETM_IF(!mm_resource_manager_reload_conf(), - "Daemon cannot reload conf"); + MM_RM_RETM_IF(!mm_resource_manager_reload_conf(), "Daemon cannot reload conf"); main_loop = g_main_loop_new(NULL, FALSE); MM_RM_RETM_IF(main_loop == NULL, "Daemon cannot create main loop"); @@ -178,7 +177,7 @@ static gboolean remove_daemon_setup_file(void) return remove_pid_file() && remove_ready_file(); } -static int set_signal_handlers() +static int set_signal_handlers(void) { struct sigaction sa_term; struct sigaction sa_reload_conf; @@ -215,7 +214,7 @@ static void reload_conf_handler(int signum) quit_main_loop(); } -static void quit_main_loop() +static void quit_main_loop(void) { if (main_loop) { _mmrm_dmn_status_callback(MM_RESOURCE_MANAGER_STATUS_DISCONNECTED); diff --git a/src/daemon/mm_resource_manager_daemon_conf.c b/src/daemon/mm_resource_manager_daemon_conf.c index 7f7efc1..c650c83 100644 --- a/src/daemon/mm_resource_manager_daemon_conf.c +++ b/src/daemon/mm_resource_manager_daemon_conf.c @@ -25,6 +25,7 @@ #define MM_RESOURCE_MANAGER_INI_FILE "/etc/multimedia/mmfw_resource_manager.ini" #define MM_RESOURCE_MANAGER_INI_MAX_VOLUME "max volume:" #define MM_RESOURCE_MANAGER_INI_PRIORITY "priority:" +#define MM_RESOURCE_MANAGER_INI_MAX_INSTANCE "max instance:" @@ -35,59 +36,67 @@ static mm_resource_manager_conf_s mm_resource_manager_conf = { MM_RESOURCE_MANAGER_NO_APP_CLASS}, {[0 ... MM_RESOURCE_MANAGER_RES_TYPE_MAX - 1] [0 ... MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX - 1] = + MM_RESOURCE_MANAGER_NO_RES}, + {[0 ... MM_RESOURCE_MANAGER_RES_TYPE_MAX - 1] = MM_RESOURCE_MANAGER_NO_RES} }; -gboolean mm_resource_manager_reload_conf() +gboolean mm_resource_manager_reload_conf(void) { dictionary *ini; GString *param_name; int i, j; ini = iniparser_load(MM_RESOURCE_MANAGER_INI_FILE); - if (ini) { - param_name = g_string_sized_new(64); - - for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) { - mm_resource_manager_conf.max_volume[i] = iniparser_getint(ini, - g_string_append(g_string_assign(param_name, - MM_RESOURCE_MANAGER_INI_MAX_VOLUME), - _mm_resource_manager_get_res_str(i))->str, - MM_RESOURCE_MANAGER_NO_RES); - if (mm_resource_manager_conf.max_volume[i] >= 1) { - for (j = 0; j < MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX; j++) { - g_string_printf(param_name, "%s:%s", - _mm_resource_manager_get_res_str(i), - _mm_resource_manager_get_condition_str(j)); - mm_resource_manager_conf.condition_volume[i][j] = - iniparser_getint(ini, param_name->str, - MM_RESOURCE_MANAGER_NO_RES); - } + MM_RM_RETVM_IF(ini == NULL, FALSE, + "Daemon cannot load conf file '%s'", MM_RESOURCE_MANAGER_INI_FILE); + + param_name = g_string_sized_new(64); + + for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) { + mm_resource_manager_conf.max_volume[i] = iniparser_getint(ini, + g_string_append(g_string_assign(param_name, + MM_RESOURCE_MANAGER_INI_MAX_VOLUME), + _mm_resource_manager_get_res_str(i))->str, + MM_RESOURCE_MANAGER_NO_RES); + if (mm_resource_manager_conf.max_volume[i] >= 1) { + mm_resource_manager_conf.volume_would_be_checked[i] = TRUE; + for (j = 0; j < MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX; j++) { + g_string_printf(param_name, "%s:%s", + _mm_resource_manager_get_res_str(i), + _mm_resource_manager_get_condition_str(j)); + mm_resource_manager_conf.condition_volume[i][j] = + iniparser_getint(ini, param_name->str, + MM_RESOURCE_MANAGER_NO_RES); } } + } - for (i = 0; i < MM_RESOURCE_MANAGER_APP_CLASS_MAX; i++) { - mm_resource_manager_conf.priority[i] = iniparser_getint(ini, - g_string_append(g_string_assign(param_name, - MM_RESOURCE_MANAGER_INI_PRIORITY), - _mm_resource_manager_get_app_class_str(i))->str, - MM_RESOURCE_MANAGER_NO_APP_CLASS); - } - - g_string_free(param_name, TRUE); - iniparser_freedict(ini); + for (i = 0; i < MM_RESOURCE_MANAGER_APP_CLASS_MAX; i++) { + mm_resource_manager_conf.priority[i] = iniparser_getint(ini, + g_string_append(g_string_assign(param_name, + MM_RESOURCE_MANAGER_INI_PRIORITY), + _mm_resource_manager_get_app_class_str(i))->str, + MM_RESOURCE_MANAGER_NO_APP_CLASS); + } - return TRUE; - } else { - MM_RM_ERROR("Daemon cannot load conf file '%s'", - MM_RESOURCE_MANAGER_INI_FILE); - return FALSE; + for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) { + mm_resource_manager_conf.max_instance[i] = iniparser_getint(ini, + g_string_append(g_string_assign(param_name, + MM_RESOURCE_MANAGER_INI_MAX_INSTANCE), + _mm_resource_manager_get_res_str(i))->str, + MM_RESOURCE_MANAGER_NO_RES); } + + g_string_free(param_name, TRUE); + iniparser_freedict(ini); + + return TRUE; } -mm_resource_manager_conf_s* mm_resource_manager_get_conf() +mm_resource_manager_conf_s* mm_resource_manager_get_conf(void) { return &mm_resource_manager_conf; } diff --git a/src/daemon/mm_resource_manager_daemon_conf.h b/src/daemon/mm_resource_manager_daemon_conf.h index b5a31d4..d926cb0 100644 --- a/src/daemon/mm_resource_manager_daemon_conf.h +++ b/src/daemon/mm_resource_manager_daemon_conf.h @@ -30,9 +30,11 @@ typedef struct { mm_resource_manager_res_volume max_volume[MM_RESOURCE_MANAGER_RES_TYPE_MAX]; mm_resource_manager_priority priority[MM_RESOURCE_MANAGER_APP_CLASS_MAX]; mm_resource_manager_condition_volume_a condition_volume; + int max_instance[MM_RESOURCE_MANAGER_RES_TYPE_MAX]; + gboolean volume_would_be_checked[MM_RESOURCE_MANAGER_RES_TYPE_MAX]; } mm_resource_manager_conf_s; -gboolean mm_resource_manager_reload_conf(); -mm_resource_manager_conf_s* mm_resource_manager_get_conf(); +gboolean mm_resource_manager_reload_conf(void); +mm_resource_manager_conf_s* mm_resource_manager_get_conf(void); #endif /* __MM_RESOURCE_MANAGER_DAEMON_CONF__ */ diff --git a/src/daemon/mm_resource_manager_daemon_dbus.c b/src/daemon/mm_resource_manager_daemon_dbus.c index 232465a..cd238a9 100755 --- a/src/daemon/mm_resource_manager_daemon_dbus.c +++ b/src/daemon/mm_resource_manager_daemon_dbus.c @@ -108,7 +108,7 @@ static gboolean _create_daemon_setup_file(void) return _create_pid_file() && _create_ready_file(); } -int _mmrm_dmn_dbus_init() +int _mmrm_dmn_dbus_init(void) { interface = mmresource_manager_skeleton_new(); MM_RM_RETVM_IF(interface == NULL, @@ -120,7 +120,7 @@ int _mmrm_dmn_dbus_init() return MM_RESOURCE_MANAGER_ERROR_NONE; } -int _mmrm_dmn_dbus_deinit() +int _mmrm_dmn_dbus_deinit(void) { MM_RM_RETVM_IF(interface == NULL, MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION, "Interface is NULL"); @@ -130,7 +130,7 @@ int _mmrm_dmn_dbus_deinit() } int _mmrm_dmn_dbus_get_conf(mm_resource_manager_res_volume **max_volume, - mm_resource_manager_condition_volume_a **cond_volume) + mm_resource_manager_condition_volume_a **cond_volume, int **max_instance) { mm_resource_manager_conf_s *conf; @@ -142,6 +142,7 @@ int _mmrm_dmn_dbus_get_conf(mm_resource_manager_res_volume **max_volume, *max_volume = conf->max_volume; *cond_volume = &conf->condition_volume; + *max_instance = conf->max_instance; return MM_RESOURCE_MANAGER_ERROR_NONE; } @@ -158,28 +159,29 @@ int _mmrm_dmn_dbus_destroy(mm_resource_manager_id id) } int _mmrm_dmn_dbus_commit(mm_resource_manager_id id, GVariantIter *release, - GVariantIter *acquire, gboolean **priority_error) + GVariantIter *acquire, gboolean **is_acquired) { int i; int ret; mm_resource_manager_dmn_res_request_s *release_requests = NULL, *acquire_requests = NULL; - MM_RM_DEBUG("Commit release request of %"G_GSIZE_FORMAT" items", - g_variant_iter_n_children(release)); __gv2c_array(release, &release_requests); + if (release_requests->type != MM_RESOURCE_MANAGER_NO_RES) + MM_RM_DEBUG("Commit release request of %"G_GSIZE_FORMAT" items [type %d]", + g_variant_iter_n_children(release), release_requests->type); - MM_RM_DEBUG("Commit acquire request of %"G_GSIZE_FORMAT" items", - g_variant_iter_n_children(acquire)); __gv2c_array(acquire, &acquire_requests); + if (acquire_requests->type != MM_RESOURCE_MANAGER_NO_RES) + MM_RM_DEBUG("Commit acquire request of %"G_GSIZE_FORMAT" items [type %d]", + g_variant_iter_n_children(acquire), acquire_requests->type); - *priority_error = (gboolean *) g_malloc0_n( - g_variant_iter_n_children(acquire), sizeof(**priority_error)); + *is_acquired = (gboolean *) g_malloc0_n(g_variant_iter_n_children(acquire), sizeof(**is_acquired)); ret = _mmrm_dmn_commit(id, release_requests, acquire_requests); for (i = 0; acquire_requests[i].type != MM_RESOURCE_MANAGER_NO_RES; i++) - (*priority_error)[i] = acquire_requests[i].priority_error; + (*is_acquired)[i] = acquire_requests[i].priority_error; g_free(release_requests); g_free(acquire_requests); @@ -220,8 +222,10 @@ static void __gv2c_array(GVariantIter *gv, mm_resource_manager_dmn_res_request_s rs = (mm_resource_manager_dmn_res_request_s *) g_malloc0_n(g_variant_iter_n_children(gv), sizeof(*rs)); - for (i = 0; g_variant_iter_next(gv, "(ii)", &rs[i].type, &rs[i].volume); i++) - MM_RM_DEBUG("(type,vol) = (%d,%d)", rs[i].type, rs[i].volume); + for (i = 0; g_variant_iter_next(gv, "(ii)", &rs[i].type, &rs[i].volume); i++) { + if (rs[i].type != MM_RESOURCE_MANAGER_NO_RES) + MM_RM_DEBUG("(type, vol) = (%d, %d)", rs[i].type, rs[i].volume); + } *c = rs; } @@ -233,12 +237,15 @@ static gboolean on_get_conf(MMResourceManager *interface, gint error = 0; mm_resource_manager_res_volume *max_volume = NULL; mm_resource_manager_condition_volume_a *cond_volume = NULL; + int *max_instance = NULL; GVariantBuilder *res_type_builder; GVariantBuilder *res_cond_builder; + GVariantBuilder *res_instance_builder; GVariant *res_type_conf; GVariant *res_cond_conf; + GVariant *res_instance_conf; - error = _mmrm_dmn_dbus_get_conf(&max_volume, &cond_volume); + error = _mmrm_dmn_dbus_get_conf(&max_volume, &cond_volume, &max_instance); res_type_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY); for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) @@ -259,7 +266,13 @@ static gboolean on_get_conf(MMResourceManager *interface, res_cond_conf = g_variant_builder_end(res_type_builder); g_variant_builder_unref(res_type_builder); - mmresource_manager_complete_conf(interface, invocation, error, res_type_conf, res_cond_conf); + res_instance_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY); + for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) + g_variant_builder_add_value(res_instance_builder, g_variant_new("i", max_instance[i])); + res_instance_conf = g_variant_builder_end(res_instance_builder); + g_variant_builder_unref(res_instance_builder); + + mmresource_manager_complete_conf(interface, invocation, error, res_type_conf, res_cond_conf, res_instance_conf); return TRUE; } @@ -330,7 +343,7 @@ static gboolean on_commit_handle(MMResourceManager *interface, static void on_bus_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data) { - GError* error = NULL; + GError *error = NULL; MM_RM_DEBUG("name of bus = %s, userID = %d", name, getuid()); g_signal_connect(interface, "handle-conf", G_CALLBACK(on_get_conf), NULL); diff --git a/src/daemon/mm_resource_manager_daemon_dbus.h b/src/daemon/mm_resource_manager_daemon_dbus.h index aceaf82..e890be1 100644 --- a/src/daemon/mm_resource_manager_daemon_dbus.h +++ b/src/daemon/mm_resource_manager_daemon_dbus.h @@ -27,7 +27,7 @@ int _mmrm_dmn_dbus_init(void); int _mmrm_dmn_dbus_deinit(void); void _mmrm_dmn_notify_fork_done(void); int _mmrm_dmn_dbus_get_conf(mm_resource_manager_res_volume **max_volume, - mm_resource_manager_condition_volume_a **cond_volume); + mm_resource_manager_condition_volume_a **cond_volume, int **max_instance); int _mmrm_dmn_dbus_create(mm_resource_manager_app_class_e app_class, mm_resource_manager_id *id); int _mmrm_dmn_dbus_destroy(mm_resource_manager_id id); diff --git a/src/daemon/mm_resource_manager_daemon_priv.c b/src/daemon/mm_resource_manager_daemon_priv.c index a0bb41b..c866dc2 100644 --- a/src/daemon/mm_resource_manager_daemon_priv.c +++ b/src/daemon/mm_resource_manager_daemon_priv.c @@ -48,7 +48,9 @@ typedef mm_resource_manager_dmn_res_s *mm_resource_manager_dmn_res_p; typedef struct { mm_resource_manager_id id; mm_resource_manager_app_class_e app_class; - + mm_resource_manager_res_type_e type; + int volume; + gboolean is_released; /* if an element is NULL, there is no such a resource for the current platform. */ mm_resource_manager_dmn_res_p resources[MM_RESOURCE_MANAGER_RES_TYPE_MAX]; @@ -63,8 +65,8 @@ typedef struct { -static GPtrArray *managers = NULL; - +static GPtrArray *managers; +static int res_count[MM_RESOURCE_MANAGER_RES_TYPE_MAX]; static void __destroy_resource(mm_resource_manager_dmn_res_p res); @@ -74,7 +76,7 @@ static inline mm_resource_manager_dmn_p __search_manager(mm_resource_manager_id static mm_resource_manager_error_e __check_release_requests( mm_resource_manager_dmn_p manager, mm_resource_manager_dmn_res_request_s *requests); -static mm_resource_manager_dmn_res_request_s* __create_increase_requests( +static mm_resource_manager_dmn_res_request_s *__create_increase_requests( mm_resource_manager_dmn_res_request_s *releases, mm_resource_manager_dmn_res_request_s *acquires); static mm_resource_manager_error_e __check_increase_requests( @@ -88,10 +90,8 @@ static void __handle_release_requests(mm_resource_manager_dmn_p manager, static GArray* __handle_acquire_requests(mm_resource_manager_dmn_p manager, mm_resource_manager_dmn_res_request_s *requests); static void __handle_release_callbacks(GArray *requests); -static inline void __add_cb_request(GArray *cb_requests, - mm_resource_manager_dmn_p man, - mm_resource_manager_res_type_e type, - mm_resource_manager_res_volume volume); +static inline void __add_cb_request(GArray *cb_requests, mm_resource_manager_dmn_p man, + mm_resource_manager_res_type_e type, mm_resource_manager_res_volume volume); static void __release_all_resources(mm_resource_manager_dmn_s *manager); static gboolean __wait_for_release_cb_sync(mm_resource_manager_id id); @@ -134,7 +134,7 @@ gboolean _mmrm_dmn_deinit() if (managers) { for (i = 0; i < managers->len; i++) - __release_all_resources((mm_resource_manager_dmn_s*)managers->pdata[i]); + __release_all_resources((mm_resource_manager_dmn_p)managers->pdata[i]); mm_resource_manager_backend_commit_all(); g_ptr_array_free(managers, TRUE); @@ -174,6 +174,8 @@ mm_resource_manager_error_e _mmrm_dmn_create( g_ptr_array_add(managers, man); + MM_RM_INFO("managers length %d", managers->len); + *id = man->id; return MM_RESOURCE_MANAGER_ERROR_NONE; @@ -181,16 +183,25 @@ mm_resource_manager_error_e _mmrm_dmn_create( mm_resource_manager_error_e _mmrm_dmn_destroy(mm_resource_manager_id id) { - int i_man = __search_manager_index(id); + int idx = __search_manager_index(id); + mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf(); + mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX; + mm_resource_manager_dmn_p i_man = __search_manager(id); - MM_RM_RETVM_IF(i_man == MM_RESOURCE_MANGER_NOT_FOUND, - MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, + MM_RM_RETVM_IF(idx == MM_RESOURCE_MANGER_NOT_FOUND, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "Resource manager #%"PRIu64" doesn't exist", _mm_rm_hash64(id)); + MM_RM_RETVM_IF(conf == NULL, MM_RESOURCE_MANAGER_ERROR_NONE, "conf is null"); - __release_all_resources((mm_resource_manager_dmn_s*)managers->pdata[i_man]); + i_man = (mm_resource_manager_dmn_p)managers->pdata[idx]; + + __release_all_resources((mm_resource_manager_dmn_s *)managers->pdata[idx]); mm_resource_manager_backend_commit_all(); - g_ptr_array_remove_index_fast(managers, i_man); + g_ptr_array_remove_index_fast(managers, idx); + + type = i_man->type; + + MM_RM_INFO("managers length #%d type %d available volume %d", managers->len, type, conf->max_volume[type]); return MM_RESOURCE_MANAGER_ERROR_NONE; } @@ -208,8 +219,8 @@ mm_resource_manager_error_e _mmrm_dmn_commit(mm_resource_manager_id id, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "Resource manager #%"PRIu64" doesn't exist", _mm_rm_hash64(id)); MM_RM_RETVM_IF( - (releases == NULL || releases[0].type == MM_RESOURCE_MANAGER_NO_RES) && - (acquires == NULL || acquires[0].type == MM_RESOURCE_MANAGER_NO_RES), + (releases == NULL || releases[0].type == MM_RESOURCE_MANAGER_NO_RES) + && (acquires == NULL || acquires[0].type == MM_RESOURCE_MANAGER_NO_RES), MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "Commit request is empty"); @@ -230,6 +241,8 @@ mm_resource_manager_error_e _mmrm_dmn_commit(mm_resource_manager_id id, __handle_release_requests(manager, releases); cb_requests = __handle_acquire_requests(manager, acquires); + MM_RM_RETVM_IF(cb_requests == NULL, MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH, + "not enough free resource volume"); __handle_release_callbacks(cb_requests); if (!mm_resource_manager_backend_commit_all()) { /* @@ -254,8 +267,6 @@ void _mmrm_dmn_status_callback(mm_resource_manager_status_e status) _mmrm_dmn_dbus_status_callback(status); } - - static void __destroy_resource(mm_resource_manager_dmn_res_p res) { if (res == NULL) @@ -284,9 +295,10 @@ static int __search_manager_index(mm_resource_manager_id id) { int i; - for (i = managers->len - 1; i >= 0; i--) + for (i = managers->len - 1; i >= 0; i--) { if (((mm_resource_manager_dmn_p)managers->pdata[i])->id == id) return i; + } return MM_RESOURCE_MANGER_NOT_FOUND; } @@ -297,41 +309,36 @@ static inline mm_resource_manager_dmn_p __search_manager(mm_resource_manager_id return i == MM_RESOURCE_MANGER_NOT_FOUND ? NULL : managers->pdata[i]; } -static mm_resource_manager_error_e __check_release_requests( - mm_resource_manager_dmn_p manager, - mm_resource_manager_dmn_res_request_s *requests) +static mm_resource_manager_error_e __check_release_requests(mm_resource_manager_dmn_p manager, + mm_resource_manager_dmn_res_request_s *requests) { - mm_resource_manager_dmn_res_request_p request; int i; + mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf(); + mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX; - if (requests == NULL) - return MM_RESOURCE_MANAGER_ERROR_NONE; + MM_RM_RETVM_IF(conf == NULL, MM_RESOURCE_MANAGER_ERROR_NONE, "conf is null"); + MM_RM_RETVM_IF(requests == NULL, MM_RESOURCE_MANAGER_ERROR_NONE, "requests is null"); for (; requests->type != MM_RESOURCE_MANAGER_NO_RES; requests++) { - request = requests; - const char *type_s = _mm_resource_manager_get_res_str(request->type); + type = requests->type; + const char *type_s = _mm_resource_manager_get_res_str(type); - MM_RM_RETVM_IF(manager->resources[request->type] == NULL, - MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED, - "There is no resource %s for the platform", type_s); + MM_RM_RETVM_IF(manager->resources[type] == NULL, + MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED, "There is no resource %s for the platform", type_s); - if (manager->resources[request->type]->is_acquired) { - if (manager->resources[request->type]->parts == NULL) { - if (request->volume != MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { - MM_RM_ERROR("Resource %s is acquired fully," - "but a resource part is tried to be released", - type_s); + if (manager->resources[type]->is_acquired) { + if (manager->resources[type]->parts == NULL) { + if (requests->volume != MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { + MM_RM_ERROR("Resource %s is acquired fully, but a resource part is tried to be released", type_s); return MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER; } } else { - for (i = 0; i < manager->resources[request->type]->parts->len && - ((mm_resource_manager_res_volume*) - manager->resources[request->type]->parts->data)[i] != - request->volume; i++); - if (i == manager->resources[request->type]->parts->len) { - MM_RM_ERROR("Part of %s of volume %d is not acquired", - type_s, request->volume); + for (i = 0; i < manager->resources[type]->parts->len + && ((mm_resource_manager_res_volume*)manager->resources[type]->parts->data)[i] + != requests->volume; i++); + if (i == manager->resources[type]->parts->len) { + MM_RM_ERROR("Part of %s of volume %d is not acquired", type_s, requests->volume); return MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER; } } @@ -339,62 +346,59 @@ static mm_resource_manager_error_e __check_release_requests( MM_RM_ERROR("Resource %s is not acquired", type_s); return MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER; } + MM_RM_DEBUG("Release requests are OK type %d available volume %d", type, conf->max_volume[type]); } - MM_RM_DEBUG("Release requests are OK"); - return MM_RESOURCE_MANAGER_ERROR_NONE; } -static mm_resource_manager_dmn_res_request_s* __create_increase_requests( - mm_resource_manager_dmn_res_request_s *releases, - mm_resource_manager_dmn_res_request_s *acquires) +static mm_resource_manager_dmn_res_request_s *__create_increase_requests( + mm_resource_manager_dmn_res_request_s *releases, mm_resource_manager_dmn_res_request_s *acquires) { int i; int result_len = 1; - mm_resource_manager_dmn_res_request_s* result = NULL; - mm_resource_manager_dmn_res_request_s* result_iter = NULL; - mm_resource_manager_res_volume resources[MM_RESOURCE_MANAGER_RES_TYPE_MAX] = {0}; mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf(); + mm_resource_manager_dmn_res_request_s *result = NULL; + mm_resource_manager_dmn_res_request_s *result_iter = NULL; + mm_resource_manager_res_volume resources[MM_RESOURCE_MANAGER_RES_TYPE_MAX] = { 0 }; + + MM_RM_RETVM_IF(conf == NULL, MM_RESOURCE_MANAGER_ERROR_NONE, "conf is null"); for (; acquires->type != MM_RESOURCE_MANAGER_NO_RES; acquires++) { - if ((resources[acquires->type] > 0 || resources[acquires->type] == - MM_RESOURCE_MANAGER_RES_VOLUME_FULL) && acquires->volume == - MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { + if ((resources[acquires->type] > 0 || resources[acquires->type] == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) + && acquires->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { MM_RM_ERROR("The client tries to acquire %s by part and fully at once", _mm_resource_manager_get_res_str(acquires->type)); return NULL; } - if (acquires->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) + if (acquires->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { resources[acquires->type] = MM_RESOURCE_MANAGER_RES_VOLUME_FULL; - else - resources[acquires->type] += acquires->volume; - - if (resources[acquires->type] > conf->max_volume[acquires->type]) { - MM_RM_ERROR( - "The client tries to acquire %d units over max volume of %s", - resources[acquires->type] - conf->max_volume[acquires->type], - _mm_resource_manager_get_res_str(acquires->type)); - return NULL; + } else { + if (conf->max_volume[acquires->type] > 1) + resources[acquires->type] += acquires->volume; + else + resources[acquires->type]++; } + + MM_RM_DEBUG("(type, vol) = (%d, %d)", acquires->type, resources[acquires->type]); } - for (; releases->type != MM_RESOURCE_MANAGER_NO_RES; releases++) - if (resources[releases->type] != MM_RESOURCE_MANAGER_RES_VOLUME_FULL) - resources[releases->type] -= releases->volume; + for (; releases->type != MM_RESOURCE_MANAGER_NO_RES; releases++) { + if (resources[releases->type] > 1) { + resources[releases->type] += releases->volume; + MM_RM_INFO("type %d available volume %d", releases->type, resources[releases->type]); + } + } for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) - if (resources[i] > 0 || - resources[i] == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) + if (resources[i] > 0 || resources[i] == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) result_len++; - result_iter = result = g_new0(mm_resource_manager_dmn_res_request_s, - result_len); + result_iter = result = g_new0(mm_resource_manager_dmn_res_request_s, result_len); for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) { - if (resources[i] > 0 || - resources[i] == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { + if (resources[i] > 0 || resources[i] == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { result_iter->type = i; result_iter->volume = resources[i]; result_iter++; @@ -405,65 +409,63 @@ static mm_resource_manager_dmn_res_request_s* __create_increase_requests( return result; } -static mm_resource_manager_error_e __check_increase_requests( - mm_resource_manager_dmn_p manager, - mm_resource_manager_dmn_res_request_s *requests) +static mm_resource_manager_error_e __check_increase_requests(mm_resource_manager_dmn_p manager, + mm_resource_manager_dmn_res_request_s *requests) { - mm_resource_manager_dmn_res_request_p request; mm_resource_manager_res_volume remaining_volume; mm_resource_manager_dmn_p i_man; mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf(); gboolean resource_conflict = FALSE; - int i, j; - - if (requests == NULL) - return MM_RESOURCE_MANAGER_ERROR_NONE; + int i, j, len; + mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX; - for (; requests->type != MM_RESOURCE_MANAGER_NO_RES; requests++) { + MM_RM_RETVM_IF(conf == NULL, MM_RESOURCE_MANAGER_ERROR_NONE, "conf is null"); + MM_RM_RETVM_IF(requests == NULL, MM_RESOURCE_MANAGER_ERROR_NONE, "requests is null"); - request = requests; - const char *type_s = _mm_resource_manager_get_res_str(request->type); + len = managers->len; - MM_RM_RETVM_IF(manager->resources[request->type] == NULL, + for (; requests->type != MM_RESOURCE_MANAGER_NO_RES; requests++) { + type = requests->type; + const char *type_s = _mm_resource_manager_get_res_str(type); + + MM_RM_RETVM_IF(type < MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER + || type >= MM_RESOURCE_MANAGER_RES_TYPE_MAX, + MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, + "wrong type %d", type); + MM_RM_RETVM_IF(manager->resources[type] == NULL, MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED, "There is no resource %s for the platform", type_s); - remaining_volume = conf->max_volume[request->type]; - for (i = 0; i < managers->len; i++) { - i_man = (mm_resource_manager_dmn_p)managers->pdata[i]; - if (i_man != manager && conf->priority[i_man->app_class] > - conf->priority[manager->app_class] && - i_man->resources[request->type]->is_acquired) { + remaining_volume = conf->max_volume[type]; - if (i_man->resources[request->type]->parts) { - if (request->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { + for (i = 0; i < len; i++) { + i_man = (mm_resource_manager_dmn_p)managers->pdata[i]; - request->priority_error = TRUE; + if (i_man != manager && conf->priority[i_man->app_class] > conf->priority[manager->app_class] + && i_man->resources[type]->is_acquired) { + if (i_man->resources[type]->parts) { + if (requests->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { + requests->priority_error = TRUE; resource_conflict = TRUE; - MM_RM_DEBUG("Resource conflict. Full volume is " - "requested, but only part is available"); + MM_RM_DEBUG("Resource conflict. Full volume is requested, but only part is available"); break; } else { - for (j = 0; j < i_man->resources[request->type]->parts->len; j++) - remaining_volume -= g_array_index( - i_man->resources[request->type]->parts, - mm_resource_manager_res_volume, j); + for (j = 0; j < i_man->resources[type]->parts->len; j++) + remaining_volume -= g_array_index(i_man->resources[type]->parts, + mm_resource_manager_res_volume, j); - if (remaining_volume < request->volume) { - request->priority_error = TRUE; + if (remaining_volume < requests->volume) { + requests->priority_error = TRUE; resource_conflict = TRUE; - MM_RM_DEBUG("Resource conflict. %d of %s are " - "available, but %d required", remaining_volume, - type_s, request->volume); + MM_RM_DEBUG("Resource conflict. %d of %s are available, but %d required", + remaining_volume, type_s, requests->volume); break; } } } else { - - request->priority_error = TRUE; + requests->priority_error = TRUE; resource_conflict = TRUE; - MM_RM_DEBUG("Resource conflict. %s is already " - "acquired fully", type_s); + MM_RM_DEBUG("Resource conflict. %s is already acquired fully", type_s); break; } } @@ -474,203 +476,191 @@ static mm_resource_manager_error_e __check_increase_requests( MM_RM_DEBUG("There is resource conflict"); return MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY; } else { - MM_RM_DEBUG("Increase requests are OK"); + MM_RM_DEBUG("type %d", type); return MM_RESOURCE_MANAGER_ERROR_NONE; } } -static void __sync_increase_acquire_requests( - mm_resource_manager_dmn_res_request_s *increases, - mm_resource_manager_dmn_res_request_s *acquires) +static void __sync_increase_acquire_requests(mm_resource_manager_dmn_res_request_s *increases, + mm_resource_manager_dmn_res_request_s *acquires) { mm_resource_manager_dmn_res_request_s *increase_iter; mm_resource_manager_dmn_res_request_s *acquire_iter; - for (increase_iter = increases; - increase_iter->type != MM_RESOURCE_MANAGER_NO_RES; - increase_iter++) - for (acquire_iter = acquires; - acquire_iter->type != MM_RESOURCE_MANAGER_NO_RES; - acquire_iter++) + for (increase_iter = increases; increase_iter->type != MM_RESOURCE_MANAGER_NO_RES; increase_iter++) { + for (acquire_iter = acquires; acquire_iter->type != MM_RESOURCE_MANAGER_NO_RES; acquire_iter++) { if (acquire_iter->type == increase_iter->type) acquire_iter->priority_error = increase_iter->priority_error; + } + } } -static inline void __add_cb_request(GArray *cb_requests, - mm_resource_manager_dmn_p man, - mm_resource_manager_res_type_e type, - mm_resource_manager_res_volume volume) +static inline void __add_cb_request(GArray *cb_requests,mm_resource_manager_dmn_p man, + mm_resource_manager_res_type_e type, mm_resource_manager_res_volume volume) { mm_resource_manager_dmn_release_cb_request_s *cb_request; g_array_set_size(cb_requests, cb_requests->len + 1); - cb_request = &g_array_index(cb_requests, - mm_resource_manager_dmn_release_cb_request_s, cb_requests->len - 1); + cb_request = &g_array_index(cb_requests, mm_resource_manager_dmn_release_cb_request_s, cb_requests->len - 1); cb_request->manager = man; cb_request->type = type; cb_request->volume = volume; } -static GArray* __handle_acquire_requests(mm_resource_manager_dmn_p manager, +static GArray *__handle_acquire_requests(mm_resource_manager_dmn_p manager, mm_resource_manager_dmn_res_request_s *requests) { mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf(); - mm_resource_manager_dmn_res_request_p request; - mm_resource_manager_res_volume acquired_volume; - mm_resource_manager_dmn_p i_man; - + mm_resource_manager_res_volume acquired_volume = 0; + mm_resource_manager_dmn_p i_man = NULL, j_man = NULL; + const char *res_name = NULL; GArray *cb_requests = NULL; - GArray *parts; - gboolean is_released_fully; - gboolean enough_volume; - int i, j; + GArray *res = NULL; + int i =0, j = 0; + gboolean is_released_called_once = FALSE; + mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX; + mm_resource_manager_res_volume volume = MM_RESOURCE_MANAGER_RES_VOLUME_FULL; - if (requests == NULL) - return NULL; + MM_RM_RETVM_IF(conf == NULL, NULL, "conf is NULL"); + MM_RM_RETVM_IF(requests == NULL, NULL, "requests is NULL"); - cb_requests = g_array_sized_new(FALSE, FALSE, - sizeof(mm_resource_manager_dmn_release_cb_request_s), + cb_requests = g_array_sized_new(FALSE, FALSE, sizeof(mm_resource_manager_dmn_release_cb_request_s), MM_RESOURCE_MANAGER_RESERVED_CALLBACK_ARRAY_SIZE); for (; requests->type != MM_RESOURCE_MANAGER_NO_RES; requests++) { + type = requests->type; + res_name = _mm_resource_manager_get_res_str(type); + volume = requests->volume; - request = requests; - const char *res_name = _mm_resource_manager_get_res_str(request->type); - - if (request->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { + if (volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { MM_RM_DEBUG("Full volume of %s is requested", res_name); for (i = 0; i < managers->len; i++) { i_man = (mm_resource_manager_dmn_p)managers->pdata[i]; - if (!i_man->resources[request->type]->is_acquired || - conf->priority[i_man->app_class] > - conf->priority[manager->app_class]) + if (!i_man->resources[type]->is_acquired + ||conf->priority[i_man->app_class] >conf->priority[manager->app_class]) { + i_man->resources[type]->is_acquired = TRUE; + if (conf->max_instance[type] > 0) + res_count[type]++; continue; + } + + res = i_man->resources[type]->parts; + if (res) { - parts = i_man->resources[request->type]->parts; - if (parts) { - for (j = 0; j < parts->len; j++) { - __add_cb_request(cb_requests, i_man, request->type, - g_array_index(parts, - mm_resource_manager_res_volume, j)); + for (j = 0; j < res->len; j++) { + __add_cb_request(cb_requests, i_man, type, + g_array_index(res, mm_resource_manager_res_volume, j)); - mm_resource_manager_backend_release(request->type); + mm_resource_manager_backend_release(type); } - g_array_free(parts, TRUE); - i_man->resources[request->type]->parts = NULL; - i_man->resources[request->type]->is_acquired = FALSE; + g_array_free(res, TRUE); + i_man->resources[type]->parts = NULL; + i_man->resources[type]->is_acquired = FALSE; MM_RM_DEBUG("All parts of %s are released in RM %"PRIu64, res_name, _mm_rm_hash64(i_man->id)); } else { - __add_cb_request(cb_requests, i_man, request->type, - MM_RESOURCE_MANAGER_RES_VOLUME_FULL); + __add_cb_request(cb_requests, i_man, type, MM_RESOURCE_MANAGER_RES_VOLUME_FULL); - mm_resource_manager_backend_release(request->type); + mm_resource_manager_backend_release(type); - i_man->resources[request->type]->is_acquired = FALSE; + i_man->resources[type]->is_acquired = FALSE; - MM_RM_DEBUG("Full resource %s is released in RM %"PRIu64, - res_name, _mm_rm_hash64(i_man->id)); + MM_RM_DEBUG("Full resource %s is released in RM %"PRIu64" available volume %d", + res_name, _mm_rm_hash64(i_man->id), conf->max_volume[type]); break; } } } else { - MM_RM_DEBUG("%d units of %s are requested", request->volume, - res_name); + MM_RM_INFO("[managers len #%d] [%d type #%d (max #%d)] [%d (max %d) units of %s] are requested", + managers->len, type, res_count[type] + 1, + conf->max_instance[type], volume, conf->max_volume[type], res_name); - acquired_volume = 0; - is_released_fully = FALSE; for (i = 0; i < managers->len; i++) { i_man = (mm_resource_manager_dmn_p)managers->pdata[i]; + res = i_man->resources[type]->parts; - if (!i_man->resources[request->type]->is_acquired || - conf->priority[i_man->app_class] > - conf->priority[manager->app_class]) - continue; + if (!i_man->resources[type]->is_acquired || res + || conf->priority[i_man->app_class] > conf->priority[manager->app_class]) { - parts = i_man->resources[request->type]->parts; - if (parts) { - for (j = 0; j < parts->len; j++) { - acquired_volume += g_array_index(parts, - mm_resource_manager_res_volume, j); + if (conf->volume_would_be_checked[type] && conf->max_volume[type] >= 0 && !res) { + conf->max_volume[type] -= volume; + MM_RM_INFO("[type %d] - %d = %d", type, volume, conf->max_volume[type]); } - } else { - __add_cb_request(cb_requests, i_man, request->type, - MM_RESOURCE_MANAGER_RES_VOLUME_FULL); - mm_resource_manager_backend_release(request->type); + if (conf->max_instance[type] > 0 && conf->max_instance[type] == res_count[type] + && !is_released_called_once) { + for (j = 0; j < managers->len; j++) { + j_man = (mm_resource_manager_dmn_p)managers->pdata[j]; + res = j_man->resources[type]->parts; - i_man->resources[request->type]->is_acquired = FALSE; - is_released_fully = TRUE; + if (res && !j_man->is_released) { + MM_RM_INFO("[#%d] [#%d / #%d] would be released %s in RM %"PRIu64, + managers->len, j + 1, res->len, res_name, _mm_rm_hash64(j_man->id)); - MM_RM_DEBUG("Full resource %s is released in RM %"PRIu64, - res_name, _mm_rm_hash64(i_man->id)); - break; - } - } + j_man->is_released = TRUE; + __add_cb_request(cb_requests, j_man, type, + g_array_index(res, mm_resource_manager_res_volume, 0)); - if (!is_released_fully) { - for (i = 0, - enough_volume = request->volume + acquired_volume <= - conf->max_volume[request->type]; - i < managers->len && !enough_volume; i++) { + mm_resource_manager_backend_release(type); + is_released_called_once = TRUE; + break; + } + } + } - i_man = (mm_resource_manager_dmn_p)managers->pdata[i]; - if (manager == i_man || - !i_man->resources[request->type]->is_acquired || - conf->priority[i_man->app_class] > - conf->priority[manager->app_class]) - continue; + if (conf->max_instance[type] > 0 && !res) + res_count[type]++; - parts = i_man->resources[request->type]->parts; - while (parts->len > 0 && !enough_volume) { + i_man->resources[type]->is_acquired = TRUE; - __add_cb_request(cb_requests, i_man, request->type, - g_array_index(parts, - mm_resource_manager_res_volume, 0)); + if (conf->max_instance[type] < res_count[type]) + break; - acquired_volume -= g_array_index(parts, - mm_resource_manager_res_volume, 0); - enough_volume = request->volume + acquired_volume <= - conf->max_volume[request->type]; + if (conf->volume_would_be_checked[type] && conf->max_volume[type] < 0 + && acquired_volume < volume) { + for (j = 0; j < managers->len; j++) { + j_man = (mm_resource_manager_dmn_p)managers->pdata[j]; + res = j_man->resources[type]->parts; - MM_RM_DEBUG("%d units of %s are released in RM %"PRIu64, - g_array_index(parts, - mm_resource_manager_res_volume, 0), res_name, - _mm_rm_hash64(i_man->id)); + if (j_man->is_released) + continue; - g_array_remove_index_fast(parts, 0); + acquired_volume += g_array_index(res, mm_resource_manager_res_volume, 0); + MM_RM_INFO("[#%d] [#%d / #%d] There are %d units of %s in RM %"PRIu64, + managers->len, j + 1, res->len, acquired_volume, res_name, + _mm_rm_hash64(j_man->id)); - mm_resource_manager_backend_release(request->type); - } + j_man->is_released = TRUE; + __add_cb_request(cb_requests, j_man, type, + g_array_index(res, mm_resource_manager_res_volume, 0)); + + mm_resource_manager_backend_release(type); - if (!parts->len) { - MM_RM_DEBUG("Part array of %s is empty and will be " - "freed in RM %"PRIu64, res_name, - _mm_rm_hash64(i_man->id)); - g_array_free(parts, TRUE); - i_man->resources[request->type]->parts = NULL; - i_man->resources[request->type]->is_acquired = FALSE; + if (acquired_volume >= volume) + break; + } } + + continue; } } - parts = manager->resources[request->type]->parts; - if (parts == NULL) { - parts = g_array_sized_new(FALSE, FALSE, - sizeof(mm_resource_manager_res_volume), - MM_RESOURCE_MANAGER_RESERVED_PART_ARRAY_SIZE); - manager->resources[request->type]->parts = parts; + res = manager->resources[requests->type]->parts; + if (res == NULL) { + res = g_array_sized_new(FALSE, FALSE, sizeof(mm_resource_manager_res_volume), + MM_RESOURCE_MANAGER_RESERVED_PART_ARRAY_SIZE); + manager->resources[requests->type]->parts = res; } - g_array_append_val(parts, request->volume); + g_array_append_val(res, requests->volume); } - manager->resources[request->type]->is_acquired = TRUE; - mm_resource_manager_backend_acquire(request->type); + manager->resources[type]->is_acquired = TRUE; + mm_resource_manager_backend_acquire(type); } return cb_requests; @@ -681,55 +671,82 @@ static void __handle_release_callbacks(GArray *requests) int i; mm_resource_manager_id id; mm_resource_manager_dmn_release_cb_request_s *request; + mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX; + mm_resource_manager_res_volume volume = MM_RESOURCE_MANAGER_RES_VOLUME_FULL; + mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf(); + + MM_RM_RETM_IF(requests == NULL, "requests is NULL"); + MM_RM_RETM_IF(conf == NULL, "conf is NULL"); for (i = 0; i < requests->len; i++) { - request = &g_array_index(requests, - mm_resource_manager_dmn_release_cb_request_s, i); + request = &g_array_index(requests, mm_resource_manager_dmn_release_cb_request_s, i); id = request->manager->id; MM_RM_HASH64(id); + type = request->type; + volume = request->volume; MM_RM_DEBUG("Sending release callback to RM #%"PRIu64" for %s of volume %d", - id, _mm_resource_manager_get_res_str(request->type), - request->volume); - _mmrm_dmn_dbus_release_callback(id, request->type, request->volume); + id, _mm_resource_manager_get_res_str(type), volume); + _mmrm_dmn_dbus_release_callback(id, type, volume); if (__wait_for_release_cb_sync(request->manager->id)) MM_RM_DEBUG("Release callback sync success"); else MM_RM_ERROR("Wait for release callback sync failed"); + + if (conf->volume_would_be_checked[type] && volume != MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { + conf->max_volume[type] += volume; + MM_RM_INFO("type %d available volume + %d = %d", type, volume, conf->max_volume[type]); + } + + if (conf->max_instance[type] > 0 && res_count[type] > 0) { + res_count[type]--; + MM_RM_INFO("The number of type %d #%d", type, res_count[type]); + } } } static void __handle_release_requests(mm_resource_manager_dmn_p manager, mm_resource_manager_dmn_res_request_s *requests) { - mm_resource_manager_dmn_res_request_p request; GArray *parts; int i; + mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX; + mm_resource_manager_res_volume volume = MM_RESOURCE_MANAGER_RES_VOLUME_FULL; + mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf(); - if (requests == NULL) - return; + MM_RM_RETM_IF(conf == NULL, "conf is NULL"); + MM_RM_RETM_IF(requests == NULL, "requests is NULL"); for (; requests->type != MM_RESOURCE_MANAGER_NO_RES; requests++) { - request = requests; + type = requests->type; + volume = requests->volume; - if (request->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { - manager->resources[request->type]->is_acquired = FALSE; + if (volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) { + manager->resources[type]->is_acquired = FALSE; } else { - parts = manager->resources[request->type]->parts; - for (i = 0; i < parts->len && - ((mm_resource_manager_res_volume*)parts->data)[i] != - request->volume; i++); + parts = manager->resources[type]->parts; + for (i = 0; i < parts->len && ((mm_resource_manager_res_volume*)parts->data)[i] != volume; i++); g_array_remove_index_fast(parts, i); if (parts->len == 0) { g_array_free(parts, TRUE); - manager->resources[request->type]->parts = NULL; - manager->resources[request->type]->is_acquired = FALSE; + manager->resources[type]->parts = NULL; + manager->resources[type]->is_acquired = FALSE; } } - mm_resource_manager_backend_release(request->type); + if (conf->volume_would_be_checked[type]) { + conf->max_volume[type] += volume; + MM_RM_INFO("[type %d] + %d = %d", type, volume, conf->max_volume[type]); + } + + if (conf->max_instance[type] > 0) { + res_count[type]--; + MM_RM_INFO("The number of type %d #%d", type, res_count[type]); + } + + mm_resource_manager_backend_release(type); } } @@ -783,7 +800,8 @@ static gboolean __wait_for_release_cb_sync(mm_resource_manager_id id) * the next sync. */ sync.revents = 0; - if (poll(&sync, 1, RELEASE_CB_SYNC_TIMEOUT * 1000) == 0 || (sync.revents & (POLLHUP | POLLERR)) == 0) + if (poll(&sync, 1, RELEASE_CB_SYNC_TIMEOUT * 1000) == 0 + || (sync.revents & (POLLHUP | POLLERR)) == 0) MM_RM_ERROR("The client didn't close the FIFO"); } else { MM_RM_ERROR("Read is failed (revents=%hd,read_size=%zd)", sync.revents, read_size); diff --git a/src/daemon/mm_resource_manager_daemon_priv.h b/src/daemon/mm_resource_manager_daemon_priv.h index 5e48465..25d59bb 100644 --- a/src/daemon/mm_resource_manager_daemon_priv.h +++ b/src/daemon/mm_resource_manager_daemon_priv.h @@ -43,4 +43,5 @@ mm_resource_manager_error_e _mmrm_dmn_commit(mm_resource_manager_id id, mm_resource_manager_dmn_res_request_s *acquires); void _mmrm_dmn_status_callback(mm_resource_manager_status_e status); + #endif /* __MM_RESOURCE_MANAGER_DAEMON_PRIVATE__ */ diff --git a/src/lib/mm_resource_manager.c b/src/lib/mm_resource_manager.c index 2739901..93a8d94 100644 --- a/src/lib/mm_resource_manager.c +++ b/src/lib/mm_resource_manager.c @@ -164,3 +164,14 @@ int mm_resource_manager_get_res_type_volume(mm_resource_manager_h rm, return _mm_resource_manager_get_res_type_volume(rm, type, condition, volume); } + +int mm_resource_manager_get_type_max_instance(mm_resource_manager_h rm, + mm_resource_manager_res_type_e type, int *max_instance) +{ + MM_RM_RETVM_IF(NULL == rm, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + MM_RM_RETVM_IF(type < 0 || type >= MM_RESOURCE_MANAGER_RES_TYPE_MAX, + MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "Wrong resource type"); + MM_RM_RETVM_IF(max_instance == NULL, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "Max instance var is NULL"); + + return _mm_resource_manager_get_type_max_instance(rm, type, max_instance); +} diff --git a/src/lib/mm_resource_manager.h b/src/lib/mm_resource_manager.h index 4e186d9..004f942 100644 --- a/src/lib/mm_resource_manager.h +++ b/src/lib/mm_resource_manager.h @@ -140,7 +140,7 @@ typedef enum { MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< The feature is not supported */ MM_RESOURCE_MANAGER_ERROR_INVALID_STATE, /**< Invalid state */ MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY, /**< Low priority to acquire a resource */ - MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH, /**< There are no enough free resource volume */ + MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH, /**< There are not enough free resource volume */ MM_RESOURCE_MANAGER_ERROR_LAUNCH_FAILURE, /**< Resource manager is not launched */ } mm_resource_manager_error_e; @@ -514,10 +514,32 @@ int mm_resource_manager_get_res_type_max_volume(mm_resource_manager_h rm, * @see mm_resource_manager_res_type_e * @see mm_resource_manager_res_type_cond_e */ -int mm_resource_manager_get_res_type_volume(mm_resource_manager_h rm, - mm_resource_manager_res_type_e type, - mm_resource_manager_res_type_cond_e condition, - mm_resource_manager_res_volume *volume); +int mm_resource_manager_get_res_type_volume(mm_resource_manager_h rm, mm_resource_manager_res_type_e type, + mm_resource_manager_res_type_cond_e condition, mm_resource_manager_res_volume *volume); + +/** + * @brief Gets max instance number of resource part per specified resource @a type parameter. + * @since_tizen 5.5 + * @remakrs This function may return reliable volumes for the same type. + * #MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER is + * returned if there are no specified resource type or condition for + * the platform. + * @param [in] rm Resource manager handle + * @param [in] type Resource type + * @param [out] max instance max number of resource instance + * @return #MM_RESOURCE_MANAGER_ERROR_NONE on success, + * otherwise error code value + * @retval #MM_RESOURCE_MANAGER_ERROR_NONE Successful + * @retval #MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED Resource type or condition + * are not supported + * @pre @a rm must be created by calling mm_resource_manager_create() + * @see mm_resource_manager_create() + * @see mm_resource_manager_res_type_e + * @see mm_resource_manager_res_type_cond_e + */ +int mm_resource_manager_get_type_max_instance(mm_resource_manager_h rm, + mm_resource_manager_res_type_e type, int *max_instance); #ifdef __cplusplus } diff --git a/src/lib/mm_resource_manager_priv.c b/src/lib/mm_resource_manager_priv.c index c3a7cdd..a3633d3 100644 --- a/src/lib/mm_resource_manager_priv.c +++ b/src/lib/mm_resource_manager_priv.c @@ -66,6 +66,7 @@ typedef struct { mm_resource_manager_res_volume __condition_volumes [MM_RESOURCE_MANAGER_RES_TYPE_MAX] [MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX]; + int __max_instance[MM_RESOURCE_MANAGER_RES_TYPE_MAX]; MMResourceManager *dbus_proxy; @@ -478,6 +479,20 @@ int _mm_resource_manager_get_res_type_volume(mm_resource_manager_h rm, } } +int _mm_resource_manager_get_type_max_instance(mm_resource_manager_h rm, + mm_resource_manager_res_type_e type, int *max_instance) +{ + mm_resource_manager_s *handle = MM_RESOURCE_MANAGER(rm); + + if (handle->__max_instance[type] == MM_RESOURCE_MANAGER_NO_RES) { + MM_RM_DEBUG("No resource for the platform"); + return MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED; + } + + *max_instance = handle->__max_instance[type]; + return MM_RESOURCE_MANAGER_ERROR_NONE; +} + void __mm_resource_manager_release_callback(mm_resource_manager_s *handle, mm_resource_manager_id id, mm_resource_manager_res_type_e type, @@ -486,9 +501,9 @@ void __mm_resource_manager_release_callback(mm_resource_manager_s *handle, mm_resource_manager_res_s *resource; mm_resource_manager_id handle_id; gboolean release_all = FALSE; - int j; + int i; - MM_RM_DEBUG("Release callback is emitted for %s of volume %d in RM #%"PRIu64, + MM_RM_INFO("Release callback is emitted for %s of volume %d in RM #%"PRIu64, _mm_resource_manager_get_res_str(type), volume, id); handle_id = handle->id; @@ -496,8 +511,9 @@ void __mm_resource_manager_release_callback(mm_resource_manager_s *handle, if (handle_id == id) { __mm_resources_lock(handle); __mm_resource_handles_unlock(); - for (j = 0; j < handle->resources->len; j++) { - resource = (mm_resource_manager_res_s*)handle->resources->pdata[j]; + + for (i = 0; i < handle->resources->len; i++) { + resource = (mm_resource_manager_res_s*)handle->resources->pdata[i]; if (resource->type == type && resource->volume == volume) { release_all = ((mm_resource_manager_release_cb) @@ -506,7 +522,7 @@ void __mm_resource_manager_release_callback(mm_resource_manager_s *handle, __send_release_cb_sync(handle->id); - g_ptr_array_remove_index_fast(handle->resources, j); + g_ptr_array_remove_index_fast(handle->resources, i); break; } } @@ -539,20 +555,17 @@ void __mm_resource_manager_status_callback(mm_resource_manager_s *handle, static void __mm_resource_handles_lock(void) { - MM_RM_INFO("handles lock"); g_mutex_lock(&handles_lock); } static void __mm_resource_handles_unlock(void) { g_mutex_unlock(&handles_lock); - MM_RM_INFO("handles unlocked"); } static void __mm_resources_lock(mm_resource_manager_s *h) { MM_RM_RETM_IF(!h, "handle is NULL"); - MM_RM_INFO("[handle %p]resources lock", h); g_mutex_lock(&h->resources_lock); } @@ -560,7 +573,6 @@ static void __mm_resources_unlock(mm_resource_manager_s *h) { MM_RM_RETM_IF(!h, "handle is NULL"); g_mutex_unlock(&h->resources_lock); - MM_RM_INFO("[handle %p]resources unlocked", h); } static int __check_resource(mm_resource_manager_s *rm, @@ -577,10 +589,6 @@ static int __check_resource(mm_resource_manager_s *rm, "No resource for the platform"); if (volume > 0) { - MM_RM_RETVM_IF(remaining_local_volume < volume, - MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION, - "Requested volume %d exceeds max value %d", volume, - remaining_local_volume); for (i = 0; i < rm->resources->len; i++) { i_res = (mm_resource_manager_res_p) rm->resources->pdata[i]; if (i_res->type == type && @@ -605,8 +613,11 @@ static int __create_resource(mm_resource_manager_s *rm, { int ret; - MM_RM_RETVM_IF(res == NULL, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, - "NULL pointer"); + mm_resource_manager_s *handle = MM_RESOURCE_MANAGER(rm); + + MM_RM_RETVM_IF(handle == NULL, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, + "NULL handle pointer"); + MM_RM_RETVM_IF(res == NULL, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "NULL pointer"); ret = __check_resource(rm, type, volume); if (ret != MM_RESOURCE_MANAGER_ERROR_NONE) return ret; @@ -623,14 +634,14 @@ static void __destroy_resource(void *res) g_free(res); } -static int __get_resource_index(mm_resource_manager_s *rm, - mm_resource_manager_res_p res) +static int __get_resource_index(mm_resource_manager_s *rm, mm_resource_manager_res_p res) { int i; - for (i = 0; i < rm->resources->len; i++) + for (i = 0; i < rm->resources->len; i++) { if (rm->resources->pdata[i] == (gpointer) res) return i; + } return MM_RESOURCE_MANAGER_RES_NOT_FOUND; } @@ -658,9 +669,10 @@ static gboolean __check_rm_handle(mm_resource_manager_s *handle) { int i; - for (i = 0; i < handles->len; i++) + for (i = 0; i < handles->len; i++) { if (g_ptr_array_index(handles, i) == handle) return TRUE; + } return FALSE; } @@ -681,8 +693,7 @@ static void __send_release_cb_sync(mm_resource_manager_id id) static void __init_lib() { - handles = g_ptr_array_sized_new( - MM_RESOURCE_MANAGER_RESERVED_HANDLE_ARRAY_SIZE); + handles = g_ptr_array_sized_new(MM_RESOURCE_MANAGER_RESERVED_HANDLE_ARRAY_SIZE); MM_RM_RETM_IF(handles == NULL, "API lib cannot be initialized"); MM_RM_INFO("API lib is loaded"); @@ -746,38 +757,31 @@ static int __dbus_init_conf(mm_resource_manager_s *handle) int rm_error = MM_RESOURCE_MANAGER_ERROR_NONE; GVariant *max_volume = NULL; GVariant *cond_volume = NULL; + GVariant *max_instance = NULL; GVariant *tmp; GVariantIter volume_iter; GVariantIter cond_volume_iter; - mmresource_manager_call_conf_sync(handle->dbus_proxy, &rm_error, - &max_volume, &cond_volume, NULL, &error); + mmresource_manager_call_conf_sync(handle->dbus_proxy, &rm_error, &max_volume, + &cond_volume, &max_instance, NULL, &error); MM_RM_RET_IF_GERR(error, "DBus conf msg cannot be sent"); MM_RM_RETVM_IF(max_volume == NULL || cond_volume == NULL, - MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION, - "Variant data are empty"); + MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION, "Variant data are empty"); - if (g_variant_iter_init(&volume_iter, max_volume) == - MM_RESOURCE_MANAGER_RES_TYPE_MAX) { - for (i = 0; g_variant_iter_next(&volume_iter, "i", - &handle->__max_resource_volumes[i]); i++); + if (g_variant_iter_init(&volume_iter, max_volume) == MM_RESOURCE_MANAGER_RES_TYPE_MAX) { + for (i = 0; g_variant_iter_next(&volume_iter, "i", &handle->__max_resource_volumes[i]); i++); g_variant_unref(max_volume); + max_volume = NULL; } else { - g_variant_unref(max_volume); - g_variant_unref(cond_volume); MM_RM_ERROR("Wrong max volume array size"); - return MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION; + goto out; } - if (g_variant_iter_init(&volume_iter, cond_volume) == - MM_RESOURCE_MANAGER_RES_TYPE_MAX) { - for (i = 0; (tmp = g_variant_iter_next_value(&volume_iter)) != NULL; - i++) { - if (g_variant_iter_init(&cond_volume_iter, tmp) == - MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX) { - for (j = 0; g_variant_iter_next(&cond_volume_iter, "i", - &handle->__condition_volumes[i][j]); j++); + if (g_variant_iter_init(&volume_iter, cond_volume) == MM_RESOURCE_MANAGER_RES_TYPE_MAX) { + for (i = 0; (tmp = g_variant_iter_next_value(&volume_iter)) != NULL; i++) { + if (g_variant_iter_init(&cond_volume_iter, tmp) == MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX) { + for (j = 0; g_variant_iter_next(&cond_volume_iter, "i", &handle->__condition_volumes[i][j]); j++); g_variant_unref(tmp); } else { g_variant_unref(tmp); @@ -787,17 +791,30 @@ static int __dbus_init_conf(mm_resource_manager_s *handle) } } g_variant_unref(cond_volume); + cond_volume = NULL; } else { - g_variant_unref(cond_volume); MM_RM_ERROR("Wrong condition volume array size"); - return MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION; + goto out; + } + + if (g_variant_iter_init(&volume_iter, max_instance) == MM_RESOURCE_MANAGER_RES_TYPE_MAX) { + for (i = 0; g_variant_iter_next(&volume_iter, "i", &handle->__max_instance[i]); i++); + g_variant_unref(max_instance); + max_instance = NULL; + } else { + MM_RM_ERROR("Wrong max instance array size"); + goto out; } return rm_error; +out: + g_variant_unref(max_volume); + g_variant_unref(cond_volume); + g_variant_unref(max_instance); + return MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION; } -static int __dbus_create(mm_resource_manager_s *handle, - mm_resource_manager_app_class_e app_class) +static int __dbus_create(mm_resource_manager_s *handle, mm_resource_manager_app_class_e app_class) { GError *error = NULL; int rm_error = MM_RESOURCE_MANAGER_ERROR_NONE; @@ -843,6 +860,7 @@ static int __dbus_commit(mm_resource_manager_s *handle) release_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY); acquire_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY); + for (i = 0; i < handle->resources->len; i++) { resource = (mm_resource_manager_res_p) handle->resources->pdata[i]; @@ -865,7 +883,8 @@ static int __dbus_commit(mm_resource_manager_s *handle) if (release_num + acquire_num == 0) { g_variant_builder_unref(release_builder); g_variant_builder_unref(acquire_builder); - MM_RM_DEBUG("There is nothing to commit - dbus request is not sent"); + MM_RM_DEBUG("There is nothing to commit - dbus request is not sent [%d %d]", + release_num, acquire_num); return rm_error; } @@ -927,13 +946,17 @@ static void __dbus_release_callback(MMResourceManager *object, guint64 arg_id, gint arg_resource_type, gint arg_volume) { mm_resource_manager_s *handle; + mm_resource_manager_id handle_id; gboolean unlock = TRUE; int i; __mm_resource_handles_lock(); + for (i = 0; i < handles->len; i++) { handle = (mm_resource_manager_s*)handles->pdata[i]; - if (handle->dbus_proxy == object) { + handle_id = handle->id; + MM_RM_HASH64(handle_id); + if (handle->dbus_proxy == object && handle_id == arg_id) { __mm_resource_manager_release_callback(handle, arg_id, arg_resource_type, arg_volume); unlock = FALSE; @@ -951,6 +974,7 @@ static void __dbus_status_callback(MMResourceManager *object, gint arg_status) gboolean unlock = TRUE; int i; + MM_RM_INFO("status callback status %d", arg_status); __mm_resource_handles_lock(); for (i = 0; i < handles->len; i++) { handle = (mm_resource_manager_s*)handles->pdata[i]; diff --git a/src/lib/mm_resource_manager_priv.h b/src/lib/mm_resource_manager_priv.h index 5532708..10e3ac7 100644 --- a/src/lib/mm_resource_manager_priv.h +++ b/src/lib/mm_resource_manager_priv.h @@ -53,5 +53,7 @@ int _mm_resource_manager_get_res_type_volume(mm_resource_manager_h rm, mm_resource_manager_res_type_e type, mm_resource_manager_res_type_cond_e condition, mm_resource_manager_res_volume *volume); +int _mm_resource_manager_get_type_max_instance(mm_resource_manager_h rm, + mm_resource_manager_res_type_e type, int *max_instance); #endif /* __MM_RESOURCE_MANAGER_PRIVATE__ */ diff --git a/test/mm_res_manager_test.c b/test/mm_res_manager_test.c index a2473a0..e0d3076 100644 --- a/test/mm_res_manager_test.c +++ b/test/mm_res_manager_test.c @@ -52,7 +52,7 @@ typedef enum { -static const char* resource_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX + 1] = { +static const char *resource_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX + 1] = { "video_decoder(#0)", "video_overlay(#1)", "camera(#2)", @@ -62,18 +62,18 @@ static const char* resource_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX + 1] = { NULL }; -static const char* app_class_str[MM_RESOURCE_MANAGER_APP_CLASS_MAX + 1] = { +static const char *app_class_str[MM_RESOURCE_MANAGER_APP_CLASS_MAX + 1] = { "media", "interrupt", NULL }; -static const char* status_str[MM_RESOURCE_MANAGER_STATUS_MAX + 1] = { +static const char *status_str[MM_RESOURCE_MANAGER_STATUS_MAX + 1] = { "disconnected", NULL }; -static const char* condition_str[MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX + 1] = { +static const char *condition_str[MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX + 1] = { "SD", "HD", "FHD", @@ -81,9 +81,9 @@ static const char* condition_str[MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX + 1] = { NULL }; -static const char* res_state_str[MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE + 2] = { +static const char *res_state_str[MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE + 2] = { "FOR ACQUIRE", - "ACQUIRED ", + "ACQUIRED", "FOR RELEASE", NULL }; @@ -146,12 +146,10 @@ static int release_cb(mm_resource_manager_h rm, g_mutex_lock(&sync_mutex); resources = g_hash_table_lookup(resource_managers, rm); - if (resources) { + if (resources) g_hash_table_remove(resources, resource_h); - } else { - g_print("WARNING: resource manager %p was removed during the release " - "cb call. Nothing is done.", rm); - } + else + g_print("WARNING: resource manager %p was removed during the release cb call. Nothing is done.", rm); g_mutex_unlock(&sync_mutex); return FALSE; } @@ -324,8 +322,7 @@ static void display_conditions(gchar **cmd_tokens) if (!max_cond_width) { max_res_width = get_max_str_len(resource_str); - align = (MAX_CMD_LINE_LEN - max_res_width) / - MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX; + align = (MAX_CMD_LINE_LEN - max_res_width) / MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX; max_cond_width = get_max_str_len(condition_str); if (align > max_cond_width) max_cond_width = align; @@ -433,8 +430,7 @@ static gpointer get_resource_by_index(mm_resource_manager_h rm, int i) gpointer *reses; guint len; - reses = g_hash_table_get_keys_as_array( - g_hash_table_lookup(resource_managers, rm), &len); + reses = g_hash_table_get_keys_as_array(g_hash_table_lookup(resource_managers, rm), &len); res = i < len ? reses[i] : NULL; @@ -443,8 +439,7 @@ static gpointer get_resource_by_index(mm_resource_manager_h rm, int i) return res; } -static mm_resource_manager_res_h get_resource_from_cmd(gchar **cmd_tokens, - mm_resource_manager_h rm) +static mm_resource_manager_res_h get_resource_from_cmd(gchar **cmd_tokens, mm_resource_manager_h rm) { mm_resource_manager_res_h res; int res_i; @@ -617,8 +612,7 @@ static void process_mark_for_release_cmd(gchar **cmd_tokens) g_mutex_lock(&sync_mutex); resources = g_hash_table_lookup(resource_managers, rm); - state_p = (mm_resource_manager_res_state_e *)g_hash_table_lookup( - resources, resource); + state_p = (mm_resource_manager_res_state_e *)g_hash_table_lookup(resources, resource); err = mm_resource_manager_mark_for_release(rm, resource); if (err == MM_RESOURCE_MANAGER_ERROR_NONE) { @@ -635,18 +629,14 @@ static void process_mark_for_release_cmd(gchar **cmd_tokens) g_mutex_unlock(&sync_mutex); } -static gboolean is_marked_for_acquire(gpointer resource, gpointer state, - gpointer user_data) +static gboolean is_marked_for_acquire(gpointer resource, gpointer state, gpointer user_data) { - return *((mm_resource_manager_res_state_e *)state) == - MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE; + return *((mm_resource_manager_res_state_e *)state) == MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE; } -static void mark_all_for_release(gpointer resource, gpointer state, gpointer - user_data) +static void mark_all_for_release(gpointer resource, gpointer state, gpointer user_data) { - mm_resource_manager_res_state_e *state_p = - (mm_resource_manager_res_state_e *)state; + mm_resource_manager_res_state_e *state_p = (mm_resource_manager_res_state_e *)state; if (*state_p == MM_RESOURCE_MANAGER_RES_STATE_ACQUIRED) *state_p = MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE; } @@ -749,8 +739,7 @@ static void process_commit_cmd(gchar **cmd_tokens) g_print("Changes in RM %p were committed successfully\n", rm); break; case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY: - print_api_error("Commit couldn't be done because of resource conflict", - err); + print_api_error("Commit couldn't be done because of resource conflict", err); break; default: print_api_error("Commit couldn't be done", err); @@ -786,8 +775,7 @@ static gboolean input(GIOChannel *channel) GString *cmd_line; cmd_line = g_string_new(NULL); - if (g_io_channel_read_line_string(channel, cmd_line, &read_size, &error) != - G_IO_STATUS_NORMAL) + if (g_io_channel_read_line_string(channel, cmd_line, &read_size, &error) != G_IO_STATUS_NORMAL) return TRUE; g_strstrip(cmd_line->str); @@ -903,8 +891,7 @@ int main(int argc, char *argv[]) int option; if (!check_const_string_arrays()) { - g_print("FATAL ERROR: Resource manager API was changed. " - "The test suite must be changed too.\n"); + g_print("FATAL ERROR: Resource manager API was changed. The test suite must be changed too.\n"); return 1; } @@ -912,9 +899,7 @@ int main(int argc, char *argv[]) switch (option) { case '?': case 'h': - g_print("Usage: %s [-s]\n" - " s - don't display menu\n" - " ?,h - usage\n", argv[0]); + g_print("Usage: %s [-s]\n s - don't display menu\n ?,h - usage\n", argv[0]); return 0; case 's': skip_menu = TRUE; @@ -927,8 +912,7 @@ int main(int argc, char *argv[]) g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL); g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc) input, NULL); - resource_managers = g_hash_table_new_full(NULL, NULL, - free_resource_manager, free_resources); + resource_managers = g_hash_table_new_full(NULL, NULL, free_resource_manager, free_resources); display_menu(); -- 2.7.4