Module: xenomai-rpm Branch: queue/vfile Commit: 6d822e82521f8784720f6a955e875b86d1088b64 URL: http://git.xenomai.org/?p=xenomai-rpm.git;a=commit;h=6d822e82521f8784720f6a955e875b86d1088b64
Author: Philippe Gerum <r...@xenomai.org> Date: Thu Jun 10 12:22:48 2010 +0200 nucleus/timebase: convert to vfile --- include/nucleus/timebase.h | 14 ++- ksrc/nucleus/timebase.c | 345 ++++++++++++++++++++------------------------ ksrc/nucleus/timer.c | 51 +++---- 3 files changed, 189 insertions(+), 221 deletions(-) diff --git a/include/nucleus/timebase.h b/include/nucleus/timebase.h index 5c8678e..40dc54a 100644 --- a/include/nucleus/timebase.h +++ b/include/nucleus/timebase.h @@ -30,6 +30,8 @@ #if defined(__KERNEL__) || defined(__XENO_SIM__) +#include <nucleus/vfile.h> + struct xntimer; typedef struct xntbops { @@ -75,9 +77,9 @@ typedef struct xntbase { #define link2tbase(ln) container_of(ln, xntbase_t, link) #ifdef CONFIG_XENO_OPT_STATS - xnqueue_t timerq; /* !< Timer holder in timebase. */ - - int timerq_rev; /* !< Revision (for non-atomic list walks). */ + struct xnvfile_snapshot vfile; /* !< Virtual file for access. */ + struct xnvfile_rev_tag revtag; /* !< Revision (for non-atomic list walks). */ + struct xnqueue timerq; /* !< Timer holder in timebase. */ #endif /* CONFIG_XENO_OPT_STATS */ } xntbase_t; @@ -322,8 +324,6 @@ do { \ removeq(&nktimebaseq, &nktbase.link); \ } while (0) -#endif /* __KERNEL__ || __XENO_SIM__ */ - void xntbase_init_proc(void); void xntbase_cleanup_proc(void); @@ -336,6 +336,10 @@ static inline void xntbase_declare_proc(xntbase_t *base) { } static inline void xntbase_remove_proc(xntbase_t *base) { } #endif /* !CONFIG_XENO_OPT_STATS */ +extern struct xnvfile_rev_tag tbaselist_tag; + +#endif /* __KERNEL__ || __XENO_SIM__ */ + /*...@}*/ #endif /* !_XENO_NUCLEUS_TIMEBASE_H */ diff --git a/ksrc/nucleus/timebase.c b/ksrc/nucleus/timebase.c index 48be711..87cde0b 100644 --- a/ksrc/nucleus/timebase.c +++ b/ksrc/nucleus/timebase.c @@ -165,6 +165,7 @@ int xntbase_alloc(const char *name, u_long period, u_long flags, xntbase_declare_proc(base); xnlock_get_irqsave(&nklock, s); appendq(&nktimebaseq, &base->link); + xnvfile_touch_tag(&tbaselist_tag); xnlock_put_irqrestore(&nklock, s); xnarch_declare_tbase(base); @@ -209,6 +210,7 @@ void xntbase_free(xntbase_t *base) xnlock_get_irqsave(&nklock, s); removeq(&nktimebaseq, &base->link); + xnvfile_touch_tag(&tbaselist_tag); xnlock_put_irqrestore(&nklock, s); xnarch_free_host_mem(base, sizeof(*base)); @@ -620,256 +622,225 @@ EXPORT_SYMBOL_GPL(xntbase_adjust_time); #ifdef CONFIG_PROC_FS -#include <linux/proc_fs.h> +struct xnvfile_rev_tag tbaselist_tag; -#ifdef CONFIG_XENO_OPT_STATS +static struct xnvfile_snapshot_ops tbase_vfile_ops; -#include <linux/seq_file.h> - -static struct proc_dir_entry *tmstat_proc_root; - -struct tmstat_seq_iterator { - int nentries; - struct tmstat_seq_info { - int cpu; - unsigned int scheduled; - unsigned int fired; - xnticks_t timeout; - xnticks_t interval; - xnflags_t status; - char handler[12]; - char name[XNOBJECT_NAME_LEN]; - } stat_info[1]; +struct tbase_vfile_priv { + struct xnholder *curr; }; -static void *tmstat_seq_start(struct seq_file *seq, loff_t *pos) -{ - struct tmstat_seq_iterator *iter = seq->private; +struct tbase_vfile_data { + unsigned int enabled : 1; + unsigned int set : 1; + unsigned int isolated : 1; + unsigned int periodic : 1; + xnticks_t jiffies; + unsigned long tickvalue; + char name[XNOBJECT_NAME_LEN]; +}; - if (*pos > iter->nentries) - return NULL; +static struct xnvfile_snapshot tbase_vfile = { + .privsz = sizeof(struct tbase_vfile_priv), + .datasz = sizeof(struct tbase_vfile_data), + .tag = &tbaselist_tag, + .ops = &tbase_vfile_ops, +}; - if (*pos == 0) - return SEQ_START_TOKEN; +static int tbase_vfile_rewind(struct xnvfile_snapshot_iterator *it) +{ + struct tbase_vfile_priv *priv = xnvfile_iterator_priv(it); + + priv->curr = getheadq(&nktimebaseq); - return iter->stat_info + *pos - 1; + return countq(&nktimebaseq); } -static void *tmstat_seq_next(struct seq_file *seq, void *v, loff_t *pos) +static int tbase_vfile_next(struct xnvfile_snapshot_iterator *it, void *data) { - struct tmstat_seq_iterator *iter = seq->private; + struct tbase_vfile_priv *priv = xnvfile_iterator_priv(it); + struct tbase_vfile_data *p = data; + struct xntbase *base; - ++*pos; + if (priv->curr == NULL) + return 0; - if (*pos > iter->nentries) - return NULL; + base = link2tbase(priv->curr); + priv->curr = nextq(&nktimebaseq, priv->curr); - return iter->stat_info + *pos - 1; + xnobject_copy_name(p->name, base->name); + p->tickvalue = base->tickvalue; + p->jiffies = base->jiffies; + p->enabled = xntbase_enabled_p(base); + p->set = xntbase_timeset_p(base); + p->isolated = xntbase_isolated_p(base); + p->periodic = xntbase_periodic_p(base); + + return 1; } -static int tmstat_seq_show(struct seq_file *seq, void *v) +static int tbase_vfile_show(struct xnvfile_snapshot_iterator *it, + void *data) { - if (v == SEQ_START_TOKEN) - seq_printf(seq, - "%-3s %-10s %-10s %-10s %-10s %-11s %-15s\n", - "CPU", "SCHEDULED", "FIRED", "TIMEOUT", - "INTERVAL", "HANDLER", "NAME"); - else { - struct tmstat_seq_info *p = v; - char timeout_buf[21] = "- "; - char interval_buf[21] = "- "; + struct tbase_vfile_data *p = data; - if (!testbits(p->status, XNTIMER_DEQUEUED)) - snprintf(timeout_buf, sizeof(timeout_buf), "%-10llu", - p->timeout); - if (testbits(p->status, XNTIMER_PERIODIC)) - snprintf(interval_buf, sizeof(interval_buf), "%-10llu", - p->interval); - seq_printf(seq, - "%-3u %-10u %-10u %s %s %-11s %-15s\n", - p->cpu, p->scheduled, p->fired, timeout_buf, - interval_buf, p->handler, p->name); + if (p == NULL) { + xnvfile_printf(it, "%-10s %10s %10s %s\n", + "NAME", "RESOLUTION", "JIFFIES", "STATUS"); + return 0; } + if (p->periodic) + xnvfile_printf(it, "%-10s %10lu %10Lu %s%s%s\n", + p->name, + p->tickvalue, + p->jiffies, + p->enabled ? "enabled" : "disabled", + p->set ? ",set" : ",unset", + p->isolated ? ",isolated" : ""); + else + xnvfile_printf(it, "%-10s %10s %10s %s\n", + p->name, + "1", + "n/a", + "enabled,set"); return 0; } -static void tmstat_seq_stop(struct seq_file *seq, void *v) -{ -} - -static struct seq_operations tmstat_op = { - .start = &tmstat_seq_start, - .next = &tmstat_seq_next, - .stop = &tmstat_seq_stop, - .show = &tmstat_seq_show +static struct xnvfile_snapshot_ops tbase_vfile_ops = { + .rewind = tbase_vfile_rewind, + .next = tbase_vfile_next, + .show = tbase_vfile_show, }; -static int tmstat_seq_open(struct inode *inode, struct file *file) -{ - xntbase_t *base = PDE(inode)->data; - struct tmstat_seq_iterator *iter = NULL; - struct seq_file *seq; - xnholder_t *holder; - struct tmstat_seq_info *stat_info; - int err, count, tmq_rev; - spl_t s; - - if (!xnpod_active_p()) - return -ESRCH; - - xnlock_get_irqsave(&nklock, s); - - restart: - count = countq(&base->timerq); - holder = getheadq(&base->timerq); - tmq_rev = base->timerq_rev; +#ifdef CONFIG_XENO_OPT_STATS - xnlock_put_irqrestore(&nklock, s); +struct xnvfile_directory tmstat_vfroot; - if (iter) - kfree(iter); - iter = kmalloc(sizeof(*iter) - + (count - 1) * sizeof(struct tmstat_seq_info), - GFP_KERNEL); - if (!iter) - return -ENOMEM; +static struct xnvfile_snapshot_ops tmstat_vfile_ops; - err = seq_open(file, &tmstat_op); +struct tmstat_vfile_priv { + struct xnholder *curr; +}; - if (err) { - kfree(iter); - return err; - } +struct tmstat_vfile_data { + int cpu; + unsigned int scheduled; + unsigned int fired; + xnticks_t timeout; + xnticks_t interval; + xnflags_t status; + char handler[12]; + char name[XNOBJECT_NAME_LEN]; +}; - iter->nentries = 0; +static int tmstat_vfile_rewind(struct xnvfile_snapshot_iterator *it) +{ + struct tmstat_vfile_priv *priv = xnvfile_iterator_priv(it); + struct xntbase *base = xnvfile_priv(it->vfile); - /* Take a snapshot element-wise, restart if something changes - underneath us. */ + priv->curr = getheadq(&base->timerq); - while (holder) { - xntimer_t *timer; + return countq(&base->timerq); +} - xnlock_get_irqsave(&nklock, s); +static int tmstat_vfile_next(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct tmstat_vfile_priv *priv = xnvfile_iterator_priv(it); + struct xntbase *base = xnvfile_priv(it->vfile); + struct tmstat_vfile_data *p = data; + struct xntimer *timer; - if (base->timerq_rev != tmq_rev) - goto restart; + if (priv->curr == NULL) + return 0; - timer = tblink2timer(holder); - /* Skip inactive timers */ - if (xnstat_counter_get(&timer->scheduled) == 0) - goto skip; + timer = tblink2timer(priv->curr); + priv->curr = nextq(&base->timerq, priv->curr); - stat_info = &iter->stat_info[iter->nentries++]; + if (xnstat_counter_get(&timer->scheduled) == 0) + return VFILE_SEQ_SKIP; - stat_info->cpu = xnsched_cpu(xntimer_sched(timer)); - stat_info->scheduled = xnstat_counter_get(&timer->scheduled); - stat_info->fired = xnstat_counter_get(&timer->fired); - stat_info->timeout = xntimer_get_timeout(timer); - stat_info->interval = xntimer_get_interval(timer); - stat_info->status = timer->status; - memcpy(stat_info->handler, timer->handler_name, - sizeof(stat_info->handler)-1); - stat_info->handler[sizeof(stat_info->handler)-1] = 0; - xnobject_copy_name(stat_info->name, timer->name); + p->cpu = xnsched_cpu(xntimer_sched(timer)); + p->scheduled = xnstat_counter_get(&timer->scheduled); + p->fired = xnstat_counter_get(&timer->fired); + p->timeout = xntimer_get_timeout(timer); + p->interval = xntimer_get_interval(timer); + p->status = timer->status; + memcpy(p->handler, timer->handler_name, + sizeof(p->handler)-1); + p->handler[sizeof(p->handler)-1] = 0; + xnobject_copy_name(p->name, timer->name); - skip: - holder = nextq(&base->timerq, holder); + return 1; +} - xnlock_put_irqrestore(&nklock, s); +static int tmstat_vfile_show(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct tmstat_vfile_data *p = data; + char timeout_buf[] = "- "; + char interval_buf[] = "- "; + + if (p == NULL) + xnvfile_printf(it, + "%-3s %-10s %-10s %-10s %-10s %-11s %-15s\n", + "CPU", "SCHEDULED", "FIRED", "TIMEOUT", + "INTERVAL", "HANDLER", "NAME"); + else { + if (!testbits(p->status, XNTIMER_DEQUEUED)) + snprintf(timeout_buf, sizeof(timeout_buf), "%-10llu", + p->timeout); + if (testbits(p->status, XNTIMER_PERIODIC)) + snprintf(interval_buf, sizeof(interval_buf), "%-10llu", + p->interval); + xnvfile_printf(it, + "%-3u %-10u %-10u %s %s %-11s %-15s\n", + p->cpu, p->scheduled, p->fired, timeout_buf, + interval_buf, p->handler, p->name); } - seq = file->private_data; - seq->private = iter; - return 0; } -static struct file_operations tmstat_seq_operations = { - .owner = THIS_MODULE, - .open = tmstat_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release_private, +static struct xnvfile_snapshot_ops tmstat_vfile_ops = { + .rewind = tmstat_vfile_rewind, + .next = tmstat_vfile_next, + .show = tmstat_vfile_show, }; -void xntbase_declare_proc(xntbase_t *base) +void xntbase_declare_proc(struct xntbase *base) { - struct proc_dir_entry *entry; - - entry = rthal_add_proc_seq(base->name, &tmstat_seq_operations, 0, - tmstat_proc_root); - if (entry) - entry->data = base; + memset(&base->vfile, 0, sizeof(base->vfile)); + base->vfile.privsz = sizeof(struct tmstat_vfile_priv); + base->vfile.datasz = sizeof(struct tmstat_vfile_data); + base->vfile.tag = &base->revtag; + base->vfile.ops = &tmstat_vfile_ops; + + xnvfile_init_snapshot(base->name, &base->vfile, &tmstat_vfroot); + xnvfile_priv(&base->vfile) = base; } -void xntbase_remove_proc(xntbase_t *base) +void xntbase_remove_proc(struct xntbase *base) { - remove_proc_entry(base->name, tmstat_proc_root); + xnvfile_destroy_snapshot(&base->vfile); } #endif /* CONFIG_XENO_OPT_STATS */ -static int timebase_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) -{ - xnholder_t *holder; - xntbase_t *tbase; - char *p = page; - int len = 0; - - p += sprintf(p, "%-10s %10s %10s %s\n", - "NAME", "RESOLUTION", "JIFFIES", "STATUS"); - - for (holder = getheadq(&nktimebaseq); - holder != NULL; holder = nextq(&nktimebaseq, holder)) { - tbase = link2tbase(holder); - if (xntbase_periodic_p(tbase)) - p += sprintf(p, "%-10s %10lu %10Lu %s%s%s\n", - tbase->name, - tbase->tickvalue, - tbase->jiffies, - xntbase_enabled_p(tbase) ? "enabled" : "disabled", - xntbase_timeset_p(tbase) ? ",set" : ",unset", - xntbase_isolated_p(tbase) ? ",isolated" : ""); - else - p += sprintf(p, "%-10s %10s %10s %s\n", - tbase->name, - "1", - "n/a", - "enabled,set"); - } - - len = p - page - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; - - return len; -} - void xntbase_init_proc(void) { #ifdef CONFIG_XENO_OPT_STATS - tmstat_proc_root = - create_proc_entry("timerstat", S_IFDIR, rthal_proc_root); + xnvfile_init_dir("timerstat", &tmstat_vfroot, &nkvfroot); #endif /* CONFIG_XENO_OPT_STATS */ - rthal_add_proc_leaf("timebases", &timebase_read_proc, NULL, NULL, - rthal_proc_root); + xnvfile_init_snapshot("timebases", &tbase_vfile, &nkvfroot); } void xntbase_cleanup_proc(void) { - remove_proc_entry("timebases", rthal_proc_root); + xnvfile_destroy_snapshot(&tbase_vfile); #ifdef CONFIG_XENO_OPT_STATS - /* All timebases must have been deregistered now. */ + /* All timebases must have been deregistered by now. */ XENO_ASSERT(NUCLEUS, !getheadq(&nktimebaseq), ;); - remove_proc_entry("timerstat", rthal_proc_root); + xnvfile_destroy_dir(&tmstat_vfroot); #endif /* CONFIG_XENO_OPT_STATS */ } diff --git a/ksrc/nucleus/timer.c b/ksrc/nucleus/timer.c index d813c4f..d267ce4 100644 --- a/ksrc/nucleus/timer.c +++ b/ksrc/nucleus/timer.c @@ -868,10 +868,10 @@ void __xntimer_init(xntimer_t *timer, xntbase_t *base, xnlock_get_irqsave(&nklock, s); appendq(&base->timerq, &timer->tblink); - base->timerq_rev++; + xnvfile_touch(&base->vfile); xnlock_put_irqrestore(&nklock, s); } -#endif /* CONFIG_XENO_OPT_TIMING_PERIODIC */ +#endif /* CONFIG_XENO_OPT_STATS */ xnarch_init_display_context(timer); } @@ -910,7 +910,7 @@ void xntimer_destroy(xntimer_t *timer) timer->sched = NULL; #ifdef CONFIG_XENO_OPT_STATS removeq(&xntimer_base(timer)->timerq, &timer->tblink); - xntimer_base(timer)->timerq_rev++; + xnvfile_touch(&xntimer_base(timer)->vfile); #endif /* CONFIG_XENO_OPT_TIMING_PERIODIC */ xnlock_put_irqrestore(&nklock, s); } @@ -1111,51 +1111,44 @@ xntbops_t nktimer_ops_aperiodic = { #ifdef CONFIG_PROC_FS -#include <linux/proc_fs.h> +#include <nucleus/vfile.h> -static int timer_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) +static int timer_vfile_show(struct xnvfile_regular_iterator *it, void *data) { const char *tm_status, *wd_status = ""; - int len; if (xnpod_active_p() && xntbase_enabled_p(&nktbase)) { tm_status = "on"; #ifdef CONFIG_XENO_OPT_WATCHDOG wd_status = "+watchdog"; #endif /* CONFIG_XENO_OPT_WATCHDOG */ - } - else + } else tm_status = "off"; - len = sprintf(page, - "status=%s%s:setup=%Lu:clock=%Lu:timerdev=%s:clockdev=%s\n", - tm_status, wd_status, xnarch_tsc_to_ns(nktimerlat), - xntbase_get_rawclock(&nktbase), - XNARCH_TIMER_DEVICE, XNARCH_CLOCK_DEVICE); - - len -= off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; - - return len; + xnvfile_printf(it, + "status=%s%s:setup=%Lu:clock=%Lu:timerdev=%s:clockdev=%s\n", + tm_status, wd_status, xnarch_tsc_to_ns(nktimerlat), + xntbase_get_rawclock(&nktbase), + XNARCH_TIMER_DEVICE, XNARCH_CLOCK_DEVICE); + return 0; } +static struct xnvfile_regular_ops timer_vfile_ops = { + .show = timer_vfile_show, +}; + +static struct xnvfile_regular timer_vfile = { + .ops = &timer_vfile_ops, +}; + void xntimer_init_proc(void) { - rthal_add_proc_leaf("timer", &timer_read_proc, NULL, NULL, - rthal_proc_root); + xnvfile_init_regular("timer", &timer_vfile, &nkvfroot); } void xntimer_cleanup_proc(void) { - remove_proc_entry("timer", rthal_proc_root); + xnvfile_destroy_regular(&timer_vfile); } #endif /* CONFIG_PROC_FS */ _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git