From: Vincent Guittot vincent.guittot@linaro.org
Instead of using numbers as resource names, introduce a new way that allows to describe resource names in plain string in "resources" objects.
Signed-off-by: Vincent Guittot vincent.guittot@linaro.org Signed-off-by: Pi-Cheng Chen pi-cheng.chen@linaro.org --- src/rt-app.c | 4 +- src/rt-app_parse_config.c | 137 ++++++++++++++++++++++++++++++++-------------- src/rt-app_types.h | 12 +++- 3 files changed, 108 insertions(+), 45 deletions(-)
diff --git a/src/rt-app.c b/src/rt-app.c index bad3e21..0a4fe2e 100644 --- a/src/rt-app.c +++ b/src/rt-app.c @@ -193,7 +193,7 @@ void run(int ind, struct timespec *min, struct timespec *max, log_ftrace(ft_data.marker_fd, "[%d] locking %d", ind, lock->res->index); - pthread_mutex_lock(&lock->res->mtx); + pthread_mutex_lock(&(lock->res->res.mtx.obj)); last = lock; lock = lock->next; } @@ -215,7 +215,7 @@ void run(int ind, struct timespec *min, struct timespec *max, log_ftrace(ft_data.marker_fd, "[%d] unlocking %d", ind, lock->res->index); - pthread_mutex_unlock(&lock->res->mtx); + pthread_mutex_unlock(&(lock->res->res.mtx.obj)); lock = lock->prev; } } diff --git a/src/rt-app_parse_config.c b/src/rt-app_parse_config.c index 36a68de..9e08ffd 100644 --- a/src/rt-app_parse_config.c +++ b/src/rt-app_parse_config.c @@ -120,7 +120,6 @@ get_int_value_from(struct json_object *where, set_default_if_needed(key, value, have_def, def_value); assure_type_is(value, where, key, json_type_int); i_value = json_object_get_int(value); - json_object_put(value); log_info(PIN "key: %s, value: %d, type <int>", key, i_value); return i_value; } @@ -137,7 +136,6 @@ get_bool_value_from(struct json_object *where, set_default_if_needed(key, value, have_def, def_value); assure_type_is(value, where, key, json_type_boolean); b_value = json_object_get_boolean(value); - json_object_put(value); log_info(PIN "key: %s, value: %d, type <bool>", key, b_value); return b_value; } @@ -158,46 +156,85 @@ get_string_value_from(struct json_object *where, } assure_type_is(value, where, key, json_type_string); s_value = strdup(json_object_get_string(value)); - json_object_put(value); log_info(PIN "key: %s, value: %s, type <string>", key, s_value); return s_value; }
+static int init_mutex_resource(rtapp_resource_t *data, const rtapp_options_t *opts) +{ + log_info(PIN "Init: %s mutex", data->name); + + pthread_mutexattr_init(&data->res.mtx.attr); + if (opts->pi_enabled) { + pthread_mutexattr_setprotocol( + &data->res.mtx.attr, + PTHREAD_PRIO_INHERIT); + } + pthread_mutex_init(&data->res.mtx.obj, + &data->res.mtx.attr); +} + +static void +parse_resource_data(char *name, struct json_object *obj, int idx, + rtapp_resource_t *data, const rtapp_options_t *opts) +{ + char *type, *target; + char def_type[RTAPP_RESOURCE_DESCR_LENGTH]; + + log_info(PFX "Parsing resources %s [%d]", name, idx); + + /* common and defaults */ + data->index = idx; + data->name = strdup(name); + + init_mutex_resource(data, opts); +} + static void parse_resources(struct json_object *resources, rtapp_options_t *opts) { int i; - int res = json_object_get_int(resources); - log_info(PFX "Creating %d resources", res); - opts->resources = malloc(sizeof(rtapp_resource_t) * res); - for (i = 0; i < res; i++) { - pthread_mutexattr_init(&opts->resources[i].mtx_attr); - if (opts->pi_enabled) { - pthread_mutexattr_setprotocol( - &opts->resources[i].mtx_attr, - PTHREAD_PRIO_INHERIT); + struct lh_entry *entry; char *key; struct json_object *val; int idx; + + log_info(PFX "Parsing resource section"); + + if (json_object_is_type(resources, json_type_object)) { + opts->nresources = 0; + foreach(resources, entry, key, val, idx) { + opts->nresources++; + } + + log_info(PFX "Found %d Resources", opts->nresources); + opts->resources = malloc(sizeof(rtapp_resource_t) * opts->nresources); + + foreach (resources, entry, key, val, idx) { + parse_resource_data(key, val, idx, &opts->resources[idx], opts); } - pthread_mutex_init(&opts->resources[i].mtx, - &opts->resources[i].mtx_attr); - opts->resources[i].index = i; } - opts->nresources = res; +} + +static int get_resource_index(const char *name, rtapp_resource_t *resources) +{ + int i=0; + + while (strcmp(resources[i].name, name) != 0) + i++; + + return i; }
static void serialize_acl(rtapp_resource_access_list_t **acl, - int idx, + const char *name, struct json_object *task_resources, rtapp_resource_t *resources) { - int i, next_idx, found; + int i, idx, found; struct json_object *access, *res, *next_res; rtapp_resource_access_list_t *tmp; - char s_idx[5]; + const char * next_name;
- /* as keys are string in the json, we need a string for searching - * the resource */ - snprintf(s_idx, 5, "%d", idx); + idx = get_resource_index(name, resources);
if (!(*acl)) { *acl = malloc( sizeof(rtapp_resource_access_list_t)); @@ -225,10 +262,10 @@ serialize_acl(rtapp_resource_access_list_t **acl, } }
- res = get_in_object(task_resources, s_idx, TRUE); + res = get_in_object(task_resources, name, TRUE); if (!res) return; - assure_type_is(res, task_resources, s_idx, json_type_object); + assure_type_is(res, task_resources, name, json_type_object);
access = get_in_object(res, "access", TRUE); if (!access) @@ -237,14 +274,22 @@ serialize_acl(rtapp_resource_access_list_t **acl,
for (i=0; i<json_object_array_length(access); i++) { + char res_name[5]; + next_res = json_object_array_get_idx(access, i); - if (!json_object_is_type(next_res, json_type_int)){ - log_critical("Invalid resource index"); - exit(EXIT_INV_CONFIG); - } - next_idx = json_object_get_int(next_res); + if (!json_object_is_type(next_res, json_type_string)){ + if (!json_object_is_type(next_res, json_type_int)){ + log_critical("Invalid resource index"); + exit(EXIT_INV_CONFIG); + } else { + snprintf(res_name, 5, "%d", json_object_get_int(next_res)); + next_name = res_name; + } + log_critical("Legacy resource index"); + } else + next_name = json_object_get_string(next_res); /* recurse on the rest of resources */ - serialize_acl(&(*acl), next_idx, task_resources, resources); + serialize_acl(&(*acl), next_name, task_resources, resources); } }
@@ -252,10 +297,11 @@ static void parse_thread_resources(const rtapp_options_t *opts, struct json_object *locks, struct json_object *task_resources, thread_data_t *data) { - int i,j, cur_res_idx, usage_usec; + int i, j, usage_usec; struct json_object *res; int res_dur; - char res_name[4]; + char res_name[5]; + const char *cur_res_name;
rtapp_resource_access_list_t *tmp, *head, *last; char debug_msg[512], tmpmsg[512]; @@ -267,15 +313,21 @@ parse_thread_resources(const rtapp_options_t *opts, struct json_object *locks, for (i = 0; i< data->nblockages; i++) { res = json_object_array_get_idx(locks, i); - if (!json_object_is_type(res, json_type_int)){ - log_critical("Invalid resource index"); - exit(EXIT_INV_CONFIG); - } - cur_res_idx = json_object_get_int(res); + if (!json_object_is_type(res, json_type_string)) { + if (!json_object_is_type(res, json_type_int)) { + log_critical("Invalid resource index"); + exit(EXIT_INV_CONFIG); + } else { + snprintf(res_name, 5, "%d", json_object_get_int(res)); + cur_res_name = res_name; + } + log_critical("Legacy resource index"); + } else + cur_res_name = json_object_get_string(res);
data->blockages[i].usage = usec_to_timespec(0); data->blockages[i].acl = NULL; - serialize_acl(&data->blockages[i].acl, cur_res_idx, + serialize_acl(&data->blockages[i].acl, cur_res_name, task_resources, opts->resources);
/* since the "current" resource is returned as the first @@ -307,8 +359,7 @@ parse_thread_resources(const rtapp_options_t *opts, struct json_object *locks,
log_info(PIN "key: acl %s", debug_msg);
- snprintf(res_name, 4, "%d", cur_res_idx); - res = get_in_object(task_resources, res_name, TRUE); + res = get_in_object(task_resources, cur_res_name, TRUE); if (!res) { usage_usec = 0; data->blockages[i].usage = usec_to_timespec(0); @@ -318,7 +369,7 @@ parse_thread_resources(const rtapp_options_t *opts, struct json_object *locks, usage_usec = get_int_value_from(res, "duration", TRUE, 0); data->blockages[i].usage = usec_to_timespec(usage_usec); } - log_info(PIN "res %d, usage: %d acl: %s", cur_res_idx, + log_info(PIN "res %s, usage: %d acl: %s", cur_res_name, usage_usec, debug_msg); } } @@ -335,6 +386,7 @@ parse_thread_data(char *name, struct json_object *obj, int idx, int i, cpu_idx;
log_info(PFX "Parsing thread %s [%d]", name, idx); + /* common and defaults */ data->ind = idx; data->name = strdup(name); @@ -524,8 +576,11 @@ get_opts_from_json_object(struct json_object *root, rtapp_options_t *opts) log_info(PFX "resources: %s", json_object_to_json_string(resources));
parse_global(global, opts); + json_object_put(global); parse_resources(resources, opts); + json_object_put(resources); parse_tasks(tasks, opts); + json_object_put(tasks);
}
diff --git a/src/rt-app_types.h b/src/rt-app_types.h index 8bec201..a1a62fd 100644 --- a/src/rt-app_types.h +++ b/src/rt-app_types.h @@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #endif /* AQUOSA */
#define RTAPP_POLICY_DESCR_LENGTH 16 +#define RTAPP_RESOURCE_DESCR_LENGTH 16 #define RTAPP_FTRACE_PATH_LENGTH 256 /* exit codes */
@@ -56,11 +57,18 @@ typedef enum policy_t #endif } policy_t;
+struct _rtapp_mutex { + pthread_mutex_t obj; + pthread_mutexattr_t attr; +} ; + /* Shared resources */ typedef struct _rtapp_resource_t { - pthread_mutex_t mtx; - pthread_mutexattr_t mtx_attr; + union { + struct _rtapp_mutex mtx; + } res; int index; + char *name; } rtapp_resource_t;
typedef struct _rtapp_resource_access_list_t {