Hi,
On 20/03/15 08:45, pi-cheng.chen wrote:
From: Vincent Guittot vincent.guittot@linaro.org
remove useless space align tab remove useless comment
I understand that this patch cleans things up by applying same kind of changes over and over, but I'd still split it in several smaller patches. Maybe a patch for each of the above points?
Signed-off-by: Vincent Guittot vincent.guittot@linaro.org Signed-off-by: Kevin Hilman khilman@linaro.org
src/rt-app.c | 191 +++++++++++++++++++++++++--------------------- src/rt-app_args.c | 77 ++++++++++--------- src/rt-app_parse_config.c | 31 ++++++-- src/rt-app_utils.c | 3 + src/rt-app_utils.h | 4 +- 5 files changed, 174 insertions(+), 132 deletions(-)
diff --git a/src/rt-app.c b/src/rt-app.c index 3c293e7..4629980 100644 --- a/src/rt-app.c +++ b/src/rt-app.c @@ -27,17 +27,13 @@ static volatile int continue_running; static pthread_t *threads; static int nthreads; rtapp_options_t opts;
static ftrace_data_t ft_data = {
.debugfs = "/debug",
.debugfs = "/sys/kernel/debug",
This maybe deserves a standalone patch, as it doesn't fit in any of the points in the changelog.
.trace_fd = -1, .marker_fd = -1,
};
-static inline unsigned int max_run(int min, int max) -{
return min + (((double) rand()) / RAND_MAX) * (max - min);
-}
This as well.
static inline busywait(struct timespec *to) { struct timespec t_step; @@ -52,27 +48,29 @@ void run(int ind, struct timespec *min, struct timespec *max, rtapp_tasks_resource_list_t *blockages, int nblockages) { int i;
//int m = max_run(timespec_to_msec(min), timespec_to_msec(max));
//struct timespec t_start, t_step, t_exec = msec_to_timespec(m); struct timespec t_start, now, t_exec, t_totexec = *max; rtapp_resource_access_list_t *lock, *last;
/* get the start time */
/* Get the start time */ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t_start); for (i = 0; i < nblockages; i++) {
/* Lock resources */ lock = blockages[i].acl; while (lock != NULL) { log_debug("[%d] locking %d", ind, lock->res->index); if (opts.ftrace) log_ftrace(ft_data.marker_fd,
"[%d] locking %d",
ind, lock->res->index);
"[%d] locking %d",
ind, lock->res->index);
I generally prefer to keep arguments aligned with the first argument. Can we keep this convention?
pthread_mutex_lock(&lock->res->mtx); last = lock; lock = lock->next; }
/* Busy wait */ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now); t_exec = timespec_add(&now, &blockages[i].usage); log_debug("[%d] busywait for %lu", ind, timespec_to_usec(&blockages[i].usage));
@@ -81,19 +79,21 @@ void run(int ind, struct timespec *min, struct timespec *max, "[%d] busywait for %d", ind, timespec_to_usec(&blockages[i].usage)); busywait(&t_exec);
/* Unlock resources */ lock = last; while (lock != NULL) { log_debug("[%d] unlocking %d", ind, lock->res->index); if (opts.ftrace) log_ftrace(ft_data.marker_fd,
"[%d] unlocking %d",
ind, lock->res->index);
"[%d] unlocking %d",
ind, lock->res->index); pthread_mutex_unlock(&lock->res->mtx); lock = lock->prev; } }
/* compute finish time for CPUTIME_ID clock */
/* Compute finish time for CPUTIME_ID clock */ t_exec = timespec_add(&t_start, &t_totexec); busywait(&t_exec);
} @@ -108,6 +108,7 @@ shutdown(int sig) { pthread_join(threads[i], NULL); }
if (opts.ftrace) { log_notice("stopping ftrace"); log_ftrace(ft_data.marker_fd, "main ends\n");
@@ -115,6 +116,7 @@ shutdown(int sig) close(ft_data.trace_fd); close(ft_data.marker_fd); }
exit(EXIT_SUCCESS);
}
@@ -122,7 +124,7 @@ void *thread_body(void *arg) { thread_data_t *data = (thread_data_t*) arg; struct sched_param param;
struct timespec t, t_next;
struct timespec t_now, t_next;
Maybe a standalone patch, even if it's just renaming?
unsigned long t_start_usec; unsigned long my_duration_usec; int nperiods;
@@ -162,11 +164,11 @@ void *thread_body(void *arg) case rr: case fifo: fprintf(data->log_handler, "# Policy : %s\n",
(data->sched_policy == rr ? "SCHED_RR" : "SCHED_FIFO"));
(data->sched_policy == rr ? "SCHED_RR" : "SCHED_FIFO")); param.sched_priority = data->sched_prio; ret = pthread_setschedparam(pthread_self(),
data->sched_policy,
¶m);
data->sched_policy,
¶m); if (ret != 0) { errno = ret; perror("pthread_setschedparam");
@@ -174,49 +176,56 @@ void *thread_body(void *arg) }
log_notice("[%d] starting thread with period: %lu, exec: %lu,"
"deadline: %lu, priority: %d",
data->ind,
timespec_to_usec(&data->period),
timespec_to_usec(&data->min_et),
timespec_to_usec(&data->deadline),
data->sched_prio
);
"deadline: %lu, priority: %d",
data->ind,
timespec_to_usec(&data->period),
timespec_to_usec(&data->min_et),
timespec_to_usec(&data->deadline),
data->sched_prio); break; case other: fprintf(data->log_handler, "# Policy : SCHED_OTHER\n");
/* add priority setting */
log_notice("[%d] starting thread with period: %lu, exec: %lu,"
"deadline: %lu",
data->ind,
timespec_to_usec(&data->period),
timespec_to_usec(&data->min_et),
timespec_to_usec(&data->deadline)
);
"deadline: %lu",
data->ind,
timespec_to_usec(&data->period),
timespec_to_usec(&data->min_et),
timespec_to_usec(&data->deadline));
data->lock_pages = 0; /* forced off for SCHED_OTHER */ break;
#ifdef AQUOSA case aquosa: fprintf(data->log_handler, "# Policy : AQUOSA\n");
data->params.Q_min = round((timespec_to_usec(&data->min_et) * (( 100.0 + data->sched_prio ) / 100)) / (data->fragment * 1.0));
data->params.Q = round((timespec_to_usec(&data->max_et) * (( 100.0 + data->sched_prio ) / 100)) / (data->fragment * 1.0));
data->params.P = round(timespec_to_usec(&data->period) / (data->fragment * 1.0));
data->params.Q_min = round((timespec_to_usec(&data->min_et)
* (( 100.0 + data->sched_prio ) / 100)) / (data->fragment * 1.0));
data->params.Q = round((timespec_to_usec(&data->max_et)
* (( 100.0 + data->sched_prio ) / 100)) / (data->fragment * 1.0));
data->params.P = round(timespec_to_usec(&data->period)
/ (data->fragment * 1.0)); data->params.flags = 0;
log_notice("[%d] Creating QRES Server with Q=%ld, P=%ld",
data->ind,data->params.Q, data->params.P);
data->ind,data->params.Q, data->params.P); qos_chk_ok_exit(qres_init());
qos_chk_ok_exit(qres_create_server(&data->params,
&data->sid));
qos_chk_ok_exit(qres_create_server(&data->params,
&data->sid)); log_notice("[%d] AQuoSA server ID: %d", data->ind, data->sid); log_notice("[%d] attaching thread (deadline: %lu) to server %d",
data->ind,
timespec_to_usec(&data->deadline),
data->sid
);
qos_chk_ok_exit(qres_attach_thread(data->sid, 0, 0));
data->ind,
timespec_to_usec(&data->deadline),
data->sid);
break;
qos_chk_ok_exit(qres_attach_thread(data->sid, 0, 0));
break;
#endif
#ifdef DLSCHED case deadline: fprintf(data->log_handler, "# Policy : SCHED_DEADLINE\n"); @@ -226,16 +235,16 @@ void *thread_body(void *arg) attr.sched_policy = SCHED_DEADLINE; attr.sched_priority = 0; attr.sched_runtime = timespec_to_nsec(&data->max_et) +
(timespec_to_nsec(&data->max_et) /100) * BUDGET_OVERP;
(timespec_to_nsec(&data->max_et) /100) * BUDGET_OVERP; attr.sched_deadline = timespec_to_nsec(&data->period); attr.sched_period = timespec_to_nsec(&data->period);
break;
break;
#endif
default: log_error("Unknown scheduling policy %d",
data->sched_policy);
data->sched_policy);
exit(EXIT_FAILURE); }
@@ -253,45 +262,46 @@ void *thread_body(void *arg) if (data->wait_before_start > 0) { log_notice("[%d] Waiting %ld usecs... ", data->ind, data->wait_before_start);
clock_gettime(CLOCK_MONOTONIC, &t);
clock_gettime(CLOCK_MONOTONIC, &t_now); t_next = msec_to_timespec(data->wait_before_start);
t_next = timespec_add(&t, &t_next);
t_next = timespec_add(&t_now, &t_next); clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t_next, NULL); log_notice("[%d] Starting...", data->ind); }
/* if we know the duration we can calculate how many periods we will * do at most, and the log to memory, instead of logging to file. */ timings = NULL; if (data->duration > 0) {
my_duration_usec = (data->duration * 10e6) -
(data->wait_before_start * 1000);
nperiods = (int) ceil( my_duration_usec /
(double) timespec_to_usec(&data->period));
my_duration_usec = (data->duration * 10e6) -
(data->wait_before_start * 1000);
nperiods = (int) ceil( my_duration_usec /
(double) timespec_to_usec(&data->period)); timings = malloc ( nperiods * sizeof(timing_point_t)); } fprintf(data->log_handler, "#idx\tperiod\tmin_et\tmax_et\trel_st\tstart"
"\t\tend\t\tdeadline\tdur.\tslack"
"\tBudget\tUsed Budget\n");
"\t\tend\t\tdeadline\tdur.\tslack"
"\tBudget\tUsed Budget\n");
#ifdef DLSCHED
/* TODO find a better way to handle that constraint */ /* * Set the task to SCHED_DEADLINE as far as possible touching its * budget as little as possible for the first iteration. */ if (data->sched_policy == SCHED_DEADLINE) { log_notice("[%d] starting thread with period: %lu, exec: %lu,"
"deadline: %lu, priority: %d",
data->ind,
attr.sched_period / 1000,
attr.sched_runtime / 1000,
attr.sched_deadline / 1000,
attr.sched_priority
);
"deadline: %lu, priority: %d",
data->ind,
attr.sched_period / 1000,
attr.sched_runtime / 1000,
attr.sched_deadline / 1000,
attr.sched_priority); ret = sched_setattr(tid, &attr, flags); if (ret != 0) {
@@ -306,15 +316,17 @@ void *thread_body(void *arg)
if (opts.ftrace) log_ftrace(ft_data.marker_fd, "[%d] starts", data->ind);
clock_gettime(CLOCK_MONOTONIC, &t);
t_next = t;
data->deadline = timespec_add(&t, &data->deadline);
clock_gettime(CLOCK_MONOTONIC, &t_now);
t_next = t_now;
data->deadline = timespec_add(&t_now, &data->deadline); while (continue_running) { struct timespec t_start, t_end, t_diff, t_slack; if (opts.ftrace) log_ftrace(ft_data.marker_fd, "[%d] begins loop %d", data->ind, i);
clock_gettime(CLOCK_MONOTONIC, &t_start); run(data->ind, &data->min_et, &data->max_et, data->blockages, data->nblockages);
@@ -328,6 +340,7 @@ void *thread_body(void *arg) curr_timing = &timings[i]; else curr_timing = &tmp_timing;
curr_timing->ind = data->ind; curr_timing->period = timespec_to_usec(&data->period); curr_timing->min_et = timespec_to_usec(&data->min_et);
@@ -339,14 +352,15 @@ void *thread_body(void *arg) curr_timing->deadline = timespec_to_usec(&data->deadline); curr_timing->duration = timespec_to_usec(&t_diff); curr_timing->slack = timespec_to_lusec(&t_slack);
#ifdef AQUOSA if (data->sched_policy == aquosa) { curr_timing->budget = data->params.Q; qres_get_exec_time(data->sid,
&abs_used_budget,
NULL);
&abs_used_budget,
NULL); curr_timing->used_budget =
abs_used_budget - prev_abs_used_budget;
abs_used_budget - prev_abs_used_budget; prev_abs_used_budget = abs_used_budget; } else {
@@ -359,9 +373,11 @@ void *thread_body(void *arg)
t_next = timespec_add(&t_next, &data->period); data->deadline = timespec_add(&data->deadline, &data->period);
if (opts.ftrace) log_ftrace(ft_data.marker_fd, "[%d] end loop %d", data->ind, i);
if (curr_timing->slack < 0 && opts.die_on_dmiss) { log_critical("[%d] DEADLINE MISS !!!", data->ind); if (opts.ftrace)
@@ -370,7 +386,11 @@ void *thread_body(void *arg) shutdown(SIGTERM); goto exit_miss; }
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t_next, NULL);
clock_gettime(CLOCK_MONOTONIC, &t_now);
if (timespec_lower(&t_now, &t_next))
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t_next, NULL);
Can you explain, maybe in a separate patch, why we need this change?
i++; }
@@ -393,18 +413,17 @@ exit_miss: log_ftrace(ft_data.marker_fd, "[%d] exiting", data->ind); log_notice("[%d] Exiting.", data->ind); fclose(data->log_handler);
#ifdef AQUOSA if (data->sched_policy == aquosa) { qres_destroy_server(data->sid); qres_cleanup(); } #endif
pthread_exit(NULL);
}
-/* parse a thread token in the form $period:$exec:$deadline:$policy:$prio and
- fills the thread_data structure
- */
int main(int argc, char* argv[]) { @@ -416,6 +435,7 @@ int main(int argc, char* argv[])
parse_command_line(argc, argv, &opts);
/* allocated threads */ nthreads = opts.nthreads; threads = malloc(nthreads * sizeof(pthread_t));
@@ -425,7 +445,7 @@ int main(int argc, char* argv[]) signal(SIGHUP, shutdown); signal(SIGINT, shutdown);
/* if using ftrace open trace and marker fds */
/* if using ftrace, open trace and marker fds */ if (opts.ftrace) { log_notice("configuring ftrace"); strcpy(tmp, ft_data.debugfs);
@@ -454,8 +474,7 @@ int main(int argc, char* argv[]) clock_gettime(CLOCK_MONOTONIC, &t_start);
/* start threads */
for (i = 0; i < nthreads; i++)
{
for (i = 0; i < nthreads; i++) { tdata = &opts.threads_data[i]; if (opts.spacing > 0 ) { /* start the thread, then it will sleep accordingly
@@ -466,19 +485,21 @@ int main(int argc, char* argv[]) } else { tdata->wait_before_start = 0; }
tdata->duration = opts.duration; tdata->main_app_start = t_start; tdata->lock_pages = opts.lock_pages;
#ifdef AQUOSA tdata->fragment = opts.fragment; #endif
if (opts.logdir) { snprintf(tmp, PATH_LENGTH, "%s/%s-%s.log", opts.logdir, opts.logbasename, tdata->name); tdata->log_handler = fopen(tmp, "w");
if (!tdata->log_handler){
if (!tdata->log_handler) { log_error("Cannot open logfile %s", tmp); exit(EXIT_FAILURE); }
@@ -494,8 +515,7 @@ int main(int argc, char* argv[]) }
/* print gnuplot files */
if (opts.logdir && opts.gnuplot)
{
if (opts.logdir && opts.gnuplot) { snprintf(tmp, PATH_LENGTH, "%s/%s-duration.plot", opts.logdir, opts.logbasename); gnuplot_script = fopen(tmp, "w+");
@@ -511,8 +531,7 @@ int main(int argc, char* argv[]) "set ylabel "Exec Time [usec]"\n" "plot ", tmp);
for (i=0; i<nthreads; i++)
{
for (i=0; i<nthreads; i++) { snprintf(tmp, PATH_LENGTH, "%s/%s-duration.plot", opts.logdir, opts.logbasename);
@@ -528,11 +547,12 @@ int main(int argc, char* argv[]) else fprintf(gnuplot_script, ", "); }
fprintf(gnuplot_script, "set terminal wxt\nreplot\n"); fclose(gnuplot_script); snprintf(tmp, PATH_LENGTH, "%s/%s-slack.plot",
opts.logdir, opts.logbasename);
opts.logdir, opts.logbasename); gnuplot_script = fopen(tmp, "w+"); snprintf(tmp, PATH_LENGTH, "%s-slack.eps", opts.logbasename);
@@ -547,8 +567,7 @@ int main(int argc, char* argv[]) "set ylabel "Slack/Tardiness [usec]"\n" "plot ", tmp);
for (i=0; i < nthreads; i++)
{
for (i=0; i < nthreads; i++) { fprintf(gnuplot_script, "\"%s-%s.log\" u ($5/1000):10 w l" " title \"thread [%s] (%s)\"",
@@ -562,19 +581,19 @@ int main(int argc, char* argv[]) fprintf(gnuplot_script, ", ");
}
fprintf(gnuplot_script, "set terminal wxt\nreplot\n"); fclose(gnuplot_script); }
if (opts.duration > 0)
{
if (opts.duration > 0) { sleep(opts.duration); if (opts.ftrace) log_ftrace(ft_data.marker_fd, "main shutdown\n"); shutdown(SIGTERM); }
for (i = 0; i < nthreads; i++) {
for (i = 0; i < nthreads; i++) { pthread_join(threads[i], NULL); }
diff --git a/src/rt-app_args.c b/src/rt-app_args.c index 36e7e51..49ff749 100644 --- a/src/rt-app_args.c +++ b/src/rt-app_args.c @@ -28,7 +28,7 @@ usage (const char* msg, int ex_code) "rt-app <taskset.json>\nOR\n"); #endif printf("rt-app [options] -t <period>:<exec>[:policy"
"[:CPU affinity[:prio[:deadline]]]] -t ...\n\n");
"[:CPU affinity[:prio[:deadline]]]] -t ...\n\n"); printf("-h, --help\t\t:\tshow this help\n"); printf("-f, --fifo\t\t:\tset default policy for threads to SCHED_FIFO\n"); printf("-r, --rr\t\t:\tset default policy fior threads to SCHED_RR\n");
@@ -81,6 +81,7 @@ parse_thread_args(char *arg, int idx, thread_data_t *tdata, policy_t def_policy) token = strtok(str, ":"); tdata->name = malloc(sizeof(char) * 5); tdata->ind = idx;
/* default name for command line threads */ snprintf(tdata->name, 1, "t%d", tdata->ind); tdata->sched_prio = DEFAULT_THREAD_PRIORITY;
@@ -105,10 +106,10 @@ parse_thread_args(char *arg, int idx, thread_data_t *tdata, policy_t def_policy) //TODO: add support for max_et somehow if (exec > period) usage("Exec time cannot be greater than"
" period.", EXIT_INV_COMMANDLINE);
" period.", EXIT_INV_COMMANDLINE); if (exec <= 0 ) usage("Cannot set negative exec time",
EXIT_INV_COMMANDLINE);
EXIT_INV_COMMANDLINE); tdata->min_et = usec_to_timespec(exec); tdata->max_et = usec_to_timespec(exec); i++;
@@ -173,6 +174,7 @@ parse_thread_args(char *arg, int idx, thread_data_t *tdata, policy_t def_policy) } token = strtok(NULL, ":"); }
if ( i < 2 ) { printf("Period and exec time are mandatory\n"); exit(EXIT_INV_COMMANDLINE);
@@ -224,25 +226,27 @@ parse_command_line_options(int argc, char **argv, rtapp_options_t *opts) #ifdef AQUOSA opts->fragment = 1; #endif
static struct option long_options[] = {
{"help", 0, 0, 'h'},
{"fifo", 0, 0, 'f'},
{"rr", 0, 0, 'r'},
{"thread", 1, 0, 't'},
{"spacing", 1, 0, 's'},
{"logdir", 1, 0, 'l'},
{"baselog", 1, 0, 'b'},
{"gnuplot", 1, 0, 'G'},
{"duration", 1, 0, 'D'},
{"ftrace", 0, 0, 'T'},
{"pi_enabled", 0, 0, 'T'},
{"die_on_dmiss", 0, 0, 'M'},
{"help", 0, 0, 'h'},
{"fifo", 0, 0, 'f'},
{"rr", 0, 0, 'r'},
{"thread", 1, 0, 't'},
{"spacing", 1, 0, 's'},
{"logdir", 1, 0, 'l'},
{"baselog", 1, 0, 'b'},
{"gnuplot", 1, 0, 'G'},
{"duration", 1, 0, 'D'},
{"ftrace", 0, 0, 'T'},
{"pi_enabled", 0, 0, 'T'},
{"die_on_dmiss", 0, 0, 'M'},
#ifdef AQUOSA
{"qos", 0, 0, 'q'},
{"frag",1, 0, 'g'},
{"qos", 0, 0, 'q'},
{"frag",1, 0, 'g'},
#endif
{0, 0, 0, 0}
};
{0, 0, 0, 0}
};
#ifdef AQUOSA while (( ch = getopt_long(argc,argv,"D:GKhfrb:s:l:qg:t:TM", long_options, &longopt_idx)) != -1) @@ -259,13 +263,13 @@ parse_command_line_options(int argc, char **argv, rtapp_options_t *opts) case 'f': if (opts->policy != other) usage("Cannot set multiple policies",
EXIT_INV_COMMANDLINE);
EXIT_INV_COMMANDLINE); opts->policy = fifo; break; case 'r': if (opts->policy != other) usage("Cannot set multiple policies",
EXIT_INV_COMMANDLINE);
EXIT_INV_COMMANDLINE); opts->policy = rr; break; case 'b':
@@ -277,26 +281,26 @@ parse_command_line_options(int argc, char **argv, rtapp_options_t *opts) opts->spacing = strtol(optarg, NULL, 0); if (opts->spacing < 0) usage("Cannot set negative spacing",
EXIT_INV_COMMANDLINE);
EXIT_INV_COMMANDLINE); break; case 'l': opts->logdir = strdup(optarg); lstat(opts->logdir, &dirstat); if (! S_ISDIR(dirstat.st_mode)) usage("Cannot stat log directory",
EXIT_INV_COMMANDLINE);
EXIT_INV_COMMANDLINE); break; case 't': if (opts->nthreads > 0) { opts->threads_data = realloc(
opts->threads_data,
(opts->nthreads+1) * \
opts->threads_data,
(opts->nthreads+1) * \ sizeof(thread_data_t)); } parse_thread_args(optarg, opts->nthreads,
&opts->threads_data[opts->nthreads],
opts->policy);
&opts->threads_data[opts->nthreads],
opts->policy); opts->nthreads++; break; case 'G':
@@ -306,7 +310,7 @@ parse_command_line_options(int argc, char **argv, rtapp_options_t *opts) opts->duration = strtol(optarg, NULL, 10); if (opts->duration < 0) usage("Cannot set negative duration",
EXIT_INV_COMMANDLINE);
EXIT_INV_COMMANDLINE); break; case 'K': opts->lock_pages = 0;
@@ -324,26 +328,25 @@ parse_command_line_options(int argc, char **argv, rtapp_options_t *opts) case 'q': if (opts->policy != other) usage("Cannot set multiple policies",
EXIT_INV_COMMANDLINE);
EXIT_INV_COMMANDLINE); opts->policy = aquosa; break; case 'g': opts->fragment = strtol(optarg, NULL, 10); if (opts->fragment < 1 || opts->fragment > 16) usage("Fragment divisor must be between"
"1 and 16", EXIT_INV_COMMANDLINE);
"1 and 16", EXIT_INV_COMMANDLINE); break;
#endif default: log_error("Invalid option %c", ch); usage(NULL, EXIT_INV_COMMANDLINE);
}
}
if ( opts->nthreads < 1) usage("You have to set parameters for at least one thread",
EXIT_INV_COMMANDLINE);
EXIT_INV_COMMANDLINE);
}
@@ -351,18 +354,20 @@ void parse_command_line(int argc, char **argv, rtapp_options_t *opts) { #ifdef JSON
struct stat config_file_stat;
if (argc < 2) usage(NULL, EXIT_SUCCESS);
struct stat config_file_stat;
if (stat(argv[1], &config_file_stat) == 0) { parse_config(argv[1], opts); return;
}
else if (strcmp(argv[1], "-") == 0) {
} else if (strcmp(argv[1], "-") == 0) { parse_config_stdin(opts); return; }
#endif
parse_command_line_options(argc, argv, opts); opts->resources = NULL; opts->nresources = 0;
diff --git a/src/rt-app_parse_config.c b/src/rt-app_parse_config.c index 4d8bff8..7411b45 100644 --- a/src/rt-app_parse_config.c +++ b/src/rt-app_parse_config.c @@ -246,7 +246,6 @@ serialize_acl(rtapp_resource_access_list_t **acl, /* recurse on the rest of resources */ serialize_acl(&(*acl), next_idx, task_resources, resources); }
}
static void @@ -261,10 +260,11 @@ parse_thread_resources(const rtapp_options_t *opts, struct json_object *locks, rtapp_resource_access_list_t *tmp, *head, *last; char debug_msg[512], tmpmsg[512];
data->blockages = malloc(sizeof(rtapp_tasks_resource_list_t) *
json_object_array_length(locks)); data->nblockages = json_object_array_length(locks);
for (i = 0; i< json_object_array_length(locks); i++)
data->blockages = malloc(sizeof(rtapp_tasks_resource_list_t) *
data->nblockages);
for (i = 0; i< data->nblockages; i++)
This might deserve a separate patch as well.
{ res = json_object_array_get_idx(locks, i); if (!json_object_is_type(res, json_type_int)){
@@ -286,6 +286,7 @@ parse_thread_resources(const rtapp_options_t *opts, struct json_object *locks, last = tmp; tmp = tmp->next; } while (tmp != NULL);
/* move first element to list end */ if (last != head) { data->blockages[i].acl = head->next;
@@ -318,7 +319,7 @@ parse_thread_resources(const rtapp_options_t *opts, struct json_object *locks, data->blockages[i].usage = usec_to_timespec(usage_usec); } log_info(PIN "res %d, usage: %d acl: %s", cur_res_idx,
usage_usec, debug_msg);
usage_usec, debug_msg); }
}
@@ -363,6 +364,18 @@ parse_thread_data(char *name, struct json_object *obj, int idx, data->min_et = usec_to_timespec(exec); data->max_et = usec_to_timespec(exec);
/* deadline */
dline = get_int_value_from(obj, "deadline", TRUE, period);
if (dline < exec) {
log_critical(PIN2 "Deadline cannot be less than exec time");
exit(EXIT_INV_CONFIG);
}
if (dline > period) {
log_critical(PIN2 "Deadline cannot be greater than period");
exit(EXIT_INV_CONFIG);
}
data->deadline = usec_to_timespec(dline);
Separate patch for this change as well?
/* policy */ policy_to_string(opts->policy, def_policy); policy = get_string_value_from(obj, "policy", TRUE, def_policy);
@@ -376,7 +389,7 @@ parse_thread_data(char *name, struct json_object *obj, int idx,
/* priority */ data->sched_prio = get_int_value_from(obj, "priority", TRUE,
DEFAULT_THREAD_PRIORITY);
DEFAULT_THREAD_PRIORITY); /* deadline */ dline = get_int_value_from(obj, "deadline", TRUE, period);
@@ -502,8 +515,10 @@ get_opts_from_json_object(struct json_object *root, rtapp_options_t *opts) void parse_config_stdin(rtapp_options_t *opts) {
/* read from stdin until EOF, write to temp file and parse
* as a "normal" config file */
/*
* Read from stdin until EOF, write to temp file and parse
* as a "normal" config file
*/ size_t in_length; char buf[JSON_FILE_BUF_SIZE]; struct json_object *js;
diff --git a/src/rt-app_utils.c b/src/rt-app_utils.c index 0c08f02..9719053 100644 --- a/src/rt-app_utils.c +++ b/src/rt-app_utils.c @@ -224,17 +224,20 @@ void ftrace_write(int mark_fd, const char *fmt, ...) va_start(ap, fmt); n = vsnprintf(tmp, BUF_SIZE, fmt, ap); va_end(ap);
/* If it worked return success */ if (n > -1 && n < size) { write(mark_fd, tmp, n); free(tmp); return; }
/* Else try again with more space */ if (n > -1) /* glibc 2.1 */ size = n+1; else /* glibc 2.0 */ size *= 2;
if ((ntmp = realloc(tmp, size)) == NULL) { free(tmp); log_error("Cannot reallocate ftrace buffer");
diff --git a/src/rt-app_utils.h b/src/rt-app_utils.h index c7444dc..ba01f56 100644 --- a/src/rt-app_utils.h +++ b/src/rt-app_utils.h @@ -121,10 +121,10 @@ timespec_to_nsec(struct timespec *ts); #endif
int -string_to_policy(const char *policy_name, policy_t *policy); +policy_to_string(policy_t policy, char *policy_name);
Is this fixing complaints from compiler? Maybe fix it in a separate patch?
int -policy_to_string(policy_t policy, char *policy_name); +string_to_policy(const char *policy_name, policy_t *policy);
void ftrace_write(int mark_fd, const char *fmt, ...); -- 1.9.1
Thanks a lot again for this effort!
Best,
- Juri