Basically, this patch enhances the statistics one can obtain via rt_task_inquire. It adds the task's
- accumulated execution time - context switches - mode switches - page faults to RT_TASK_INFO. To provide this data, our existing exectime stats had to be extended so that the collected data no longer gets reset upon dump of /proc/xenomai/stat. At this change, the patch also removes the unused xnthread::stime. Credits go to Daniel Simon for writing the initial version and contributing to the succeeding revisions I made. Jan PS: Patches and Changelog fragments can also be found at the usual place: http://www.rts.uni-hannover.de/rtaddon/patches/xenomai
--- include/native/task.h | 19 +++++++++++++++---- include/nucleus/stat.h | 12 +++++++++++- include/nucleus/thread.h | 7 ++++--- ksrc/nucleus/module.c | 9 +++++---- ksrc/nucleus/pod.c | 6 +++--- ksrc/nucleus/thread.c | 1 - ksrc/skins/native/task.c | 9 +++++++++ 7 files changed, 47 insertions(+), 16 deletions(-) Index: xenomai/include/native/task.h =================================================================== --- xenomai.orig/include/native/task.h +++ xenomai/include/native/task.h @@ -77,19 +77,30 @@ struct rt_task; /** Structure containing task-information useful to users. * * @see rt_task_inquire() + * + * @note Marked (*) fields will be set to 0 by rt_task_inquire() if + * statistics support is disabled in the nucleus. */ typedef struct rt_task_info { - + int bprio; /**< Base priority. */ int cprio; /**< Current priority. May change through Priority Inheritance.*/ - + unsigned status; /**< Task's status. @see native_task_status */ - + RTIME relpoint; /**< Time of next release.*/ - + char name[XNOBJECT_NAME_LEN]; /**< Symbolic name assigned at creation. */ + RTIME exectime; /**< Execution time in primary mode in nanoseconds (*). */ + + int modeswitches; /**< Number of primary->secondary mode switches (*). */ + + int ctxswitches; /**< Number of context switches (*). */ + + int pagefaults; /**< Number of triggered page faults (*). */ + } RT_TASK_INFO; #define RT_MCB_FSTORE_LIMIT 64 Index: xenomai/include/nucleus/stat.h =================================================================== --- xenomai.orig/include/nucleus/stat.h +++ xenomai/include/nucleus/stat.h @@ -67,6 +67,13 @@ do { \ (sched)->current_account = (new_account); \ } while (0) +/* Obtain content of xnstat_runtime_t */ +#define xnstat_runtime_get_start(account) ((account)->start) +#define xnstat_runtime_get_total(account) ((account)->total) + +/* Obtain last account switch date of considered sched */ +#define xnstat_runtime_get_last_switch(sched) ((sched)->last_account_switch) + /* Reset statistics from inside the accounted entity (e.g. after CPU migration). */ #define xnstat_runtime_reset_stats(stat) \ @@ -104,9 +111,12 @@ typedef struct xnstat_runtime { #define xnstat_runtime_now() ({ 0; }) #define xnstat_runtime_update(sched, date) do { } while (0) -#define xnstat_runtime_set_current(sched, new_account) ({ (void)sched; NULL; }) +#define xnstat_runtime_set_current(sched, new_account) ({ (void)sched; NULL; }) #define xnstat_runtime_get_current(sched) ({ (void)sched; NULL; }) #define xnstat_runtime_finalize(sched, new_account) do { } while (0) +#define xnstat_runtime_get_start(account) ({ 0; }) +#define xnstat_runtime_get_total(account) ({ 0; }) +#define xnstat_runtime_get_last_switch(sched) ({ 0; }) #define xnstat_runtime_reset_stats(account) do { } while (0) typedef struct xnstat_counter { Index: xenomai/include/nucleus/thread.h =================================================================== --- xenomai.orig/include/nucleus/thread.h +++ xenomai/include/nucleus/thread.h @@ -205,7 +205,8 @@ typedef struct xnthread { xnstat_counter_t ssw; /* Primary -> secondary mode switch count */ xnstat_counter_t csw; /* Context switches (includes secondary -> primary switches) */ xnstat_counter_t pf; /* Number of page faults */ - xnstat_runtime_t account; /* Runtime accounting entity */ + xnstat_runtime_t account; /* Execution time accounting entity */ + xnstat_runtime_t lastperiod; /* Interval marker for execution time reports */ } stat; int errcode; /* Local errno */ @@ -235,8 +236,6 @@ typedef struct xnthread { char name[XNOBJECT_NAME_LEN]; /* Symbolic name of thread */ - xnticks_t stime; /* Start time */ - void (*entry)(void *cookie); /* Thread entry routine */ void *cookie; /* Cookie to pass to the entry routine */ @@ -294,6 +293,8 @@ typedef struct xnhook { 0 : xnarch_user_pid(xnthread_archtcb(thread))) #define xnthread_affinity(thread) ((thread)->affinity) #define xnthread_affine_p(thread, cpu) xnarch_cpu_isset(cpu, (thread)->affinity) +#define xnthread_get_exectime(thread) xnstat_runtime_get_total(&(thread)->stat.account) +#define xnthread_get_lastswitch(thread) xnstat_runtime_get_last_switch((thread)->sched) /* Class-level operations for threads. */ static inline int xnthread_get_denormalized_prio(xnthread_t *t) Index: xenomai/ksrc/nucleus/module.c =================================================================== --- xenomai.orig/ksrc/nucleus/module.c +++ xenomai/ksrc/nucleus/module.c @@ -421,16 +421,17 @@ static int stat_seq_open(struct inode *i stat_info->csw = xnstat_counter_get(&thread->stat.csw); stat_info->pf = xnstat_counter_get(&thread->stat.pf); - period = sched->last_account_switch - thread->stat.account.start; + period = sched->last_account_switch - thread->stat.lastperiod.start; if (!period && thread == sched->runthread) { stat_info->runtime = 1; stat_info->account_period = 1; } else { - stat_info->runtime = thread->stat.account.total; + stat_info->runtime = thread->stat.account.total - + thread->stat.lastperiod.total; stat_info->account_period = period; } - thread->stat.account.total = 0; - thread->stat.account.start = sched->last_account_switch; + thread->stat.lastperiod.total = thread->stat.account.total; + thread->stat.lastperiod.start = sched->last_account_switch; holder = nextq(&nkpod->threadq, holder); Index: xenomai/ksrc/nucleus/pod.c =================================================================== --- xenomai.orig/ksrc/nucleus/pod.c +++ xenomai/ksrc/nucleus/pod.c @@ -832,7 +832,6 @@ int xnpod_start_thread(xnthread_t *threa thread->imode = (mode & XNTHREAD_MODE_BITS); thread->entry = entry; thread->cookie = cookie; - thread->stime = xnarch_get_cpu_time(); if (xnthread_test_state(thread, XNRRB)) thread->rrcredit = thread->rrperiod; @@ -1781,8 +1780,9 @@ int xnpod_migrate_thread(int cpu) xnpod_schedule(); - /* Reset execution time stats due to unsync'ed TSCs */ - xnstat_runtime_reset_stats(&thread->stat.account); + /* Reset execution time measurement period so that we don't mess up + per-CPU statistics. */ + xnstat_runtime_reset_stats(&thread->stat.lastperiod); unlock_and_exit: Index: xenomai/ksrc/nucleus/thread.c =================================================================== --- xenomai.orig/ksrc/nucleus/thread.c +++ xenomai/ksrc/nucleus/thread.c @@ -103,7 +103,6 @@ int xnthread_init(xnthread_t *thread, thread->imode = 0; thread->entry = NULL; thread->cookie = 0; - thread->stime = 0; thread->ops = ops; inith(&thread->glink); Index: xenomai/ksrc/skins/native/task.c =================================================================== --- xenomai.orig/ksrc/skins/native/task.c +++ xenomai/ksrc/skins/native/task.c @@ -1121,6 +1121,7 @@ int rt_task_unblock(RT_TASK *task) int rt_task_inquire(RT_TASK *task, RT_TASK_INFO *info) { int err = 0; + xnticks_t raw_exectime; spl_t s; if (!task) { @@ -1144,6 +1145,14 @@ int rt_task_inquire(RT_TASK *task, RT_TA info->cprio = xnthread_current_priority(&task->thread_base); info->status = xnthread_state_flags(&task->thread_base); info->relpoint = xntimer_get_date(&task->thread_base.ptimer); + raw_exectime = xnthread_get_exectime(&task->thread_base); + if (task->thread_base.sched->runthread == &task->thread_base) + raw_exectime += xnstat_runtime_now() - + xnthread_get_lastswitch(&task->thread_base); + info->exectime = xnarch_tsc_to_ns(raw_exectime); + info->modeswitches = xnstat_counter_get(&task->thread_base.stat.ssw); + info->ctxswitches = xnstat_counter_get(&task->thread_base.stat.csw); + info->pagefaults = xnstat_counter_get(&task->thread_base.stat.pf); unlock_and_exit:
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core