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

Reply via email to