Module: xenomai-rpm
Branch: queue/vfile
Commit: 4aa261c7a22e73e76a6138772af1d7e7f06ce146
URL:    
http://git.xenomai.org/?p=xenomai-rpm.git;a=commit;h=4aa261c7a22e73e76a6138772af1d7e7f06ce146

Author: Philippe Gerum <r...@xenomai.org>
Date:   Tue Jun  8 08:43:19 2010 +0200

vrtx: convert to vfile

---

 ksrc/skins/vrtx/event.c  |  149 +++++++++++++++++++++++++++++++---------------
 ksrc/skins/vrtx/heap.c   |   75 +++++++++++++----------
 ksrc/skins/vrtx/mb.c     |  132 +++++++++++++++++++++++++++-------------
 ksrc/skins/vrtx/module.c |    9 +---
 ksrc/skins/vrtx/mx.c     |  146 ++++++++++++++++++++++++++++++---------------
 ksrc/skins/vrtx/pt.c     |   77 ++++++++++++++----------
 ksrc/skins/vrtx/queue.c  |  134 ++++++++++++++++++++++++++++-------------
 ksrc/skins/vrtx/sem.c    |  131 +++++++++++++++++++++++++++-------------
 8 files changed, 557 insertions(+), 296 deletions(-)

diff --git a/ksrc/skins/vrtx/event.c b/ksrc/skins/vrtx/event.c
index d0d30ec..6d5285f 100644
--- a/ksrc/skins/vrtx/event.c
+++ b/ksrc/skins/vrtx/event.c
@@ -27,72 +27,123 @@ static xnqueue_t vrtx_event_q;
 
 #ifdef CONFIG_PROC_FS
 
-static int __event_read_proc(char *page,
-                            char **start,
-                            off_t off, int count, int *eof, void *data)
+struct vfile_priv {
+       int nrdata;
+       struct xnpholder *curr;
+       int value;
+};
+
+struct vfile_data {
+       int opt;
+       int mask;
+       char name[XNOBJECT_NAME_LEN];
+};
+
+static int vfile_rewind(struct xnvfile_snapshot_iterator *it)
 {
-       vrtxevent_t *evgroup = (vrtxevent_t *)data;
-       char *p = page;
-       int len;
-       spl_t s;
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vrtxevent *evgroup = xnvfile_priv(it->vfile);
 
-       xnlock_get_irqsave(&nklock, s);
+       priv->nrdata = xnsynch_nsleepers(&evgroup->synchbase);
+       priv->curr = getheadpq(xnsynch_wait_queue(&evgroup->synchbase));
+       priv->value = evgroup->events;
 
-       p += sprintf(p, "=0x%x\n", evgroup->events);
+       return 0;
+}
 
-       if (xnsynch_nsleepers(&evgroup->synchbase) > 0) {
-               xnpholder_t *holder;
+static void *vfile_begin(struct xnvfile_snapshot_iterator *it)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
 
-               /* Pended event -- dump waiters. */
+       if (priv->nrdata == 0)
+               /* No output beside the header. */
+               return VFILE_SEQ_EMPTY;
 
-               holder = getheadpq(xnsynch_wait_queue(&evgroup->synchbase));
+       return kmalloc(priv->nrdata * sizeof(struct vfile_data),
+                      GFP_KERNEL);
+}
 
-               while (holder) {
-                       xnthread_t *sleeper = link2thread(holder, plink);
-                       vrtxtask_t *task = thread2vrtxtask(sleeper);
-                       const char *mode =
-                           (task->waitargs.evgroup.
-                            opt & 1) ? "all" : "any";
-                       int mask = task->waitargs.evgroup.mask;
-                       p += sprintf(p, "+%s (mask=0x%x, %s)\n",
-                                    xnthread_name(sleeper), mask, mode);
-                       holder =
-                           nextpq(xnsynch_wait_queue(&evgroup->synchbase),
-                                  holder);
-               }
-       }
+static void vfile_end(struct xnvfile_snapshot_iterator *it, void *buf)
+{
+       kfree(buf);
+}
 
-       xnlock_put_irqrestore(&nklock, s);
+static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vrtxevent *evgroup = xnvfile_priv(it->vfile);
+       struct vfile_data *p = data;
+       struct xnthread *thread;
+       struct vrtxtask *task;
+
+       priv->value = evgroup->events; /* Refresh as we collect. */
+
+       if (priv->curr == NULL)
+               return 0;       /* We are done. */
 
-       len = (p - page) - off;
-       if (len <= off + count)
-               *eof = 1;
-       *start = page + off;
-       if (len > count)
-               len = count;
-       if (len < 0)
-               len = 0;
+       /* Fetch current waiter, advance list cursor. */
+       thread = link2thread(priv->curr, plink);
+       priv->curr = nextpq(xnsynch_wait_queue(&evgroup->synchbase),
+                           priv->curr);
 
-       return len;
+       /* Collect thread name to be output in ->show(). */
+       strncpy(p->name, xnthread_name(thread), sizeof(p->name));
+       task = thread2vrtxtask(thread);
+       p->opt = task->waitargs.evgroup.opt;
+       p->mask = task->waitargs.evgroup.mask;
+
+       return 1;
 }
 
-extern xnptree_t __vrtx_ptree;
+static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vfile_data *p = data;
+
+       if (p == NULL) {        /* Dump header. */
+               /* Always dump current event mask value. */
+               xnvfile_printf(it, "=0x%x\n", priv->value);
+               if (priv->nrdata > 0)
+                       xnvfile_printf(it, "\n%10s  %4s  %s\n",
+                                      "MASK", "MODE", "WAITER");
+       } else
+               xnvfile_printf(it, "0x%-8x  %4s  %.*s\n",
+                              p->mask,
+                              p->opt & 1 ? "all" : "any",
+                              (int)sizeof(p->name), p->name);
+
+       return 0;
+}
 
-static xnpnode_t __event_pnode = {
+static struct xnvfile_snapshot_ops vfile_ops = {
+       .rewind = vfile_rewind,
+       .begin = vfile_begin,
+       .next = vfile_next,
+       .end = vfile_end,
+       .show = vfile_show,
+};
 
-       .dir = NULL,
-       .type = "events",
-       .entries = 0,
-       .read_proc = &__event_read_proc,
-       .write_proc = NULL,
-       .root = &__vrtx_ptree,
+extern struct xnptree __vrtx_ptree;
+
+static struct xnpnode_file __event_pnode = {
+       .node = {
+               .dirname = "events",
+               .root = &__vrtx_ptree,
+               .ops = &xnregistry_vfile_ops,
+       },
+       .vfile = {
+               .privsz = sizeof(struct vfile_priv),
+               .datasz = sizeof(struct vfile_data),
+               .ops = &vfile_ops,
+       },
 };
 
 #else /* !CONFIG_PROC_FS */
 
-static xnpnode_t __event_pnode = {
-
-       .type = "events"
+static struct xnpnode_file __vrtx_pnode = {
+       .node = {
+               .dirname = "events",
+       },
 };
 
 #endif /* !CONFIG_PROC_FS */
@@ -160,7 +211,7 @@ int sc_fcreate(int *errp)
        xnlock_put_irqrestore(&nklock, s);
 
        sprintf(evgroup->name, "ev%d", evid);
-       xnregistry_enter(evgroup->name, evgroup, &evgroup->handle, 
&__event_pnode);
+       xnregistry_enter(evgroup->name, evgroup, &evgroup->handle, 
&__event_pnode.node);
 
        *errp = RET_OK;
 
diff --git a/ksrc/skins/vrtx/heap.c b/ksrc/skins/vrtx/heap.c
index 5f70675..59190f0 100644
--- a/ksrc/skins/vrtx/heap.c
+++ b/ksrc/skins/vrtx/heap.c
@@ -27,46 +27,57 @@ static xnqueue_t vrtx_heap_q;
 
 #ifdef CONFIG_PROC_FS
 
-static int __heap_read_proc(char *page,
-                           char **start,
-                           off_t off, int count, int *eof, void *data)
+struct vfile_priv {
+       size_t heapsz;
+       size_t memused;
+};
+
+static int vfile_rewind(struct xnvfile_snapshot_iterator *it)
 {
-       vrtxheap_t *heap = (vrtxheap_t *)data;
-       char *p = page;
-       int len;
-
-       p += sprintf(p, "size=%lu:used=%lu\n",
-                    xnheap_usable_mem(&heap->sysheap), 
xnheap_used_mem(&heap->sysheap));
-
-       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;
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vrtxheap *heap = xnvfile_priv(it->vfile);
+
+       priv->heapsz = xnheap_usable_mem(&heap->sysheap);
+       priv->memused = xnheap_used_mem(&heap->sysheap);
+
+       return 0;
 }
 
-extern xnptree_t __vrtx_ptree;
+static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+
+       xnvfile_printf(it, "size=%lu:used=%lu\n",
+                      priv->heapsz, priv->memused);
+
+       return 0;
+}
 
-static xnpnode_t __heap_pnode = {
+static struct xnvfile_snapshot_ops vfile_ops = {
+       .rewind = vfile_rewind,
+       .show = vfile_show,
+};
 
-       .dir = NULL,
-       .type = "heaps",
-       .entries = 0,
-       .read_proc = &__heap_read_proc,
-       .write_proc = NULL,
-       .root = &__vrtx_ptree,
+extern struct xnptree __vrtx_ptree;
+
+static struct xnpnode_file __heap_pnode = {
+       .node = {
+               .dirname = "heaps",
+               .root = &__vrtx_ptree,
+               .ops = &xnregistry_vfile_ops,
+       },
+       .vfile = {
+               .privsz = sizeof(struct vfile_priv),
+               .ops = &vfile_ops,
+       },
 };
 
 #else /* !CONFIG_PROC_FS */
 
-static xnpnode_t __heap_pnode = {
-
-       .type = "heaps"
+static struct xnpnode_file __heap_pnode = {
+       .node = {
+               .dirname = "heaps",
+       },
 };
 
 #endif /* !CONFIG_PROC_FS */
@@ -221,7 +232,7 @@ int sc_hcreate(char *heapaddr, u_long heapsize, unsigned 
log2psize, int *errp)
        xnlock_put_irqrestore(&nklock, s);
 
        sprintf(heap->name, "heap%d", hid);
-       xnregistry_enter(heap->name, heap, &heap->handle, &__heap_pnode);
+       xnregistry_enter(heap->name, heap, &heap->handle, &__heap_pnode.node);
 
        *errp = RET_OK;
 
diff --git a/ksrc/skins/vrtx/mb.c b/ksrc/skins/vrtx/mb.c
index 12f8449..56a93d6 100644
--- a/ksrc/skins/vrtx/mb.c
+++ b/ksrc/skins/vrtx/mb.c
@@ -30,64 +30,110 @@ static xnqueue_t vrtx_mbox_q;
 
 #ifdef CONFIG_PROC_FS
 
-static int __mb_read_proc(char *page,
-                         char **start,
-                         off_t off, int count, int *eof, void *data)
+struct vfile_priv {
+       int nrdata;
+       struct xnpholder *curr;
+       char *msg;
+};
+
+struct vfile_data {
+       char name[XNOBJECT_NAME_LEN];
+};
+
+static int vfile_rewind(struct xnvfile_snapshot_iterator *it)
 {
-       vrtxmb_t *mb = (vrtxmb_t *)data;
-       char *p = page;
-       int len;
-       spl_t s;
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vrtxmb *mb = xnvfile_priv(it->vfile);
 
-       xnlock_get_irqsave(&nklock, s);
+       priv->nrdata = xnsynch_nsleepers(&mb->synchbase);
+       priv->curr = getheadpq(xnsynch_wait_queue(&mb->synchbase));
+       priv->msg = mb->msg;
 
-       if (xnsynch_nsleepers(&mb->synchbase) > 0) {
-               xnpholder_t *holder;
+       return 0;
+}
 
-               holder = getheadpq(xnsynch_wait_queue(&mb->synchbase));
+static void *vfile_begin(struct xnvfile_snapshot_iterator *it)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
 
-               while (holder) {
-                       xnthread_t *sleeper = link2thread(holder, plink);
-                       p += sprintf(p, "+%s\n", xnthread_name(sleeper));
-                       holder =
-                           nextpq(xnsynch_wait_queue(&mb->synchbase),
-                                  holder);
-               }
-       } else
-               /* Mailbox not pended. */
-               p += sprintf(p, "=%p\n", mb->msg);
+       if (priv->nrdata == 0)
+               /* No output beside the header. */
+               return VFILE_SEQ_EMPTY;
 
-       xnlock_put_irqrestore(&nklock, s);
+       return kmalloc(priv->nrdata * sizeof(struct vfile_data),
+                      GFP_KERNEL);
+}
 
-       len = (p - page) - off;
-       if (len <= off + count)
-               *eof = 1;
-       *start = page + off;
-       if (len > count)
-               len = count;
-       if (len < 0)
-               len = 0;
+static void vfile_end(struct xnvfile_snapshot_iterator *it, void *buf)
+{
+       kfree(buf);
+}
 
-       return len;
+static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vrtxmb *mb = xnvfile_priv(it->vfile);
+       struct vfile_data *p = data;
+       struct xnthread *thread;
+
+       if (priv->curr == NULL)
+               return 0;       /* We are done. */
+
+       /* Fetch current waiter, advance list cursor. */
+       thread = link2thread(priv->curr, plink);
+       priv->curr = nextpq(xnsynch_wait_queue(&mb->synchbase),
+                           priv->curr);
+
+       /* Collect thread name to be output in ->show(). */
+       strncpy(p->name, xnthread_name(thread), sizeof(p->name));
+
+       return 1;
 }
 
-extern xnptree_t __vrtx_ptree;
+static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vfile_data *p = data;
+
+       if (p == NULL) {        /* Dump header. */
+               if (priv->nrdata == 0)
+                       xnvfile_printf(it, "=%p\n", priv->msg);
+       } else
+               xnvfile_printf(it, "%.*s\n",
+                              (int)sizeof(p->name), p->name);
+
+       return 0;
+}
 
-static xnpnode_t __mb_pnode = {
+static struct xnvfile_snapshot_ops vfile_ops = {
+       .rewind = vfile_rewind,
+       .begin = vfile_begin,
+       .next = vfile_next,
+       .end = vfile_end,
+       .show = vfile_show,
+};
 
-       .dir = NULL,
-       .type = "mailboxes",
-       .entries = 0,
-       .read_proc = &__mb_read_proc,
-       .write_proc = NULL,
-       .root = &__vrtx_ptree,
+extern struct xnptree __vrtx_ptree;
+
+static struct xnpnode_file __mb_pnode = {
+       .node = {
+               .dirname = "mailboxes",
+               .root = &__vrtx_ptree,
+               .ops = &xnregistry_vfile_ops,
+       },
+       .vfile = {
+               .privsz = sizeof(struct vfile_priv),
+               .datasz = sizeof(struct vfile_data),
+               .ops = &vfile_ops,
+       },
 };
 
 #else /* !CONFIG_PROC_FS */
 
-static xnpnode_t __mb_pnode = {
-
-       .type = "mailboxes"
+static struct xnpnode_file __mb_pnode = {
+       .node = {
+               .dirname = "mailboxes",
+       },
 };
 
 #endif /* !CONFIG_PROC_FS */
@@ -213,7 +259,7 @@ vrtxmb_t *mb_map(char **mboxp)
        mb_hash(mboxp, mb);
 
        sprintf(mb->name, "m...@%p", mboxp);
-       xnregistry_enter(mb->name, mb, &mb->handle, &__mb_pnode);
+       xnregistry_enter(mb->name, mb, &mb->handle, &__mb_pnode.node);
 
        return mb;
 }
diff --git a/ksrc/skins/vrtx/module.c b/ksrc/skins/vrtx/module.c
index 4c1f7b4..b2fbb56 100644
--- a/ksrc/skins/vrtx/module.c
+++ b/ksrc/skins/vrtx/module.c
@@ -50,14 +50,7 @@ MODULE_PARM_DESC(task_stacksize, "Default size of VRTX task 
stack (in bytes)");
 
 xntbase_t *vrtx_tbase;
 
-#ifdef CONFIG_PROC_FS
-xnptree_t __vrtx_ptree = {
-
-       .dir = NULL,
-       .name = "vrtx",
-       .entries = 0,
-};
-#endif /* CONFIG_PROC_FS */
+DEFINE_XNPTREE(__vrtx_ptree, "vrtx");
 
 int sc_gversion(void)
 {
diff --git a/ksrc/skins/vrtx/mx.c b/ksrc/skins/vrtx/mx.c
index 813a1a6..a4180fb 100644
--- a/ksrc/skins/vrtx/mx.c
+++ b/ksrc/skins/vrtx/mx.c
@@ -27,71 +27,121 @@ static xnqueue_t vrtx_mx_q;
 
 #ifdef CONFIG_PROC_FS
 
-static int __mutex_read_proc(char *page,
-                            char **start,
-                            off_t off, int count, int *eof, void *data)
+struct vfile_priv {
+       int nrdata;
+       struct xnpholder *curr;
+       char owner[XNOBJECT_NAME_LEN];
+};
+
+struct vfile_data {
+       char name[XNOBJECT_NAME_LEN];
+};
+
+static int vfile_rewind(struct xnvfile_snapshot_iterator *it)
 {
-       vrtxmx_t *mx = (vrtxmx_t *)data;
-       xnthread_t *owner;
-       char *p = page;
-       int len;
-       spl_t s;
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vrtxmx *mx = xnvfile_priv(it->vfile);
+       struct xnthread *owner;
 
-       xnlock_get_irqsave(&nklock, s);
+       priv->nrdata = xnsynch_nsleepers(&mx->synchbase);
+       priv->curr = getheadpq(xnsynch_wait_queue(&mx->synchbase));
 
        owner = xnsynch_owner(&mx->synchbase);
-       if (owner) {
-               xnpholder_t *holder;
-
-               /* Locked mx -- dump owner and waiters, if any. */
+       if (owner)
+               strncpy(priv->owner, xnthread_name(owner),
+                       sizeof(priv->owner));
+       else
+               *priv->owner = 0;
 
-               p += sprintf(p, "=locked by %s\n",
-                            xnthread_name(owner));
+       return 0;
+}
 
-               holder = getheadpq(xnsynch_wait_queue(&mx->synchbase));
+static void *vfile_begin(struct xnvfile_snapshot_iterator *it)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
 
-               while (holder) {
-                       xnthread_t *sleeper = link2thread(holder, plink);
-                       p += sprintf(p, "+%s\n", xnthread_name(sleeper));
-                       holder =
-                           nextpq(xnsynch_wait_queue(&mx->synchbase),
-                                  holder);
-               }
-       } else
-               /* Mutex unlocked. */
-               p += sprintf(p, "=unlocked\n");
+       if (priv->nrdata == 0)
+               /* No output beside the header. */
+               return VFILE_SEQ_EMPTY;
 
-       xnlock_put_irqrestore(&nklock, s);
+       return kmalloc(priv->nrdata * sizeof(struct vfile_data),
+                      GFP_KERNEL);
+}
 
-       len = (p - page) - off;
-       if (len <= off + count)
-               *eof = 1;
-       *start = page + off;
-       if (len > count)
-               len = count;
-       if (len < 0)
-               len = 0;
+static void vfile_end(struct xnvfile_snapshot_iterator *it, void *buf)
+{
+       kfree(buf);
+}
 
-       return len;
+static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vrtxmx *mx = xnvfile_priv(it->vfile);
+       struct vfile_data *p = data;
+       struct xnthread *thread;
+
+       if (priv->curr == NULL)
+               return 0;       /* We are done. */
+
+       /* Fetch current waiter, advance list cursor. */
+       thread = link2thread(priv->curr, plink);
+       priv->curr = nextpq(xnsynch_wait_queue(&mx->synchbase),
+                           priv->curr);
+       /* Collect thread name to be output in ->show(). */
+       strncpy(p->name, xnthread_name(thread), sizeof(p->name));
+
+       return 1;
 }
 
-extern xnptree_t __vrtx_ptree;
+static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vfile_data *p = data;
+
+       if (p == NULL) {        /* Dump header. */
+               if (*priv->owner) {
+                       xnvfile_printf(it, "locked by %s\n", priv->owner);
+                       if (priv->nrdata > 0)
+                               /* Mutex is pended -- dump waiters */
+                               xnvfile_printf(it, 
"-------------------------------------------\n");
+               } else
+                       xnvfile_printf(it, "unlocked\n");
+       } else
+               xnvfile_printf(it, "%.*s\n",
+                              (int)sizeof(p->name), p->name);
 
-static xnpnode_t __mutex_pnode = {
+       return 0;
+}
 
-       .dir = NULL,
-       .type = "mutexes",
-       .entries = 0,
-       .read_proc = &__mutex_read_proc,
-       .write_proc = NULL,
-       .root = &__vrtx_ptree,
+static struct xnvfile_snapshot_ops vfile_ops = {
+       .rewind = vfile_rewind,
+       .begin = vfile_begin,
+       .next = vfile_next,
+       .end = vfile_end,
+       .show = vfile_show,
 };
 
-#else /* !CONFIG_PROC_FS */
+extern struct xnptree __vrtx_ptree;
+
+static struct xnpnode_file __mutex_pnode = {
+       .node = {
+               .dirname = "mutexes",
+               .root = &__vrtx_ptree,
+               .ops = &xnregistry_vfile_ops,
+       },
+       .vfile = {
+               .privsz = sizeof(struct vfile_priv),
+               .datasz = sizeof(struct vfile_data),
+               .ops = &vfile_ops,
+       },
+};
 
-static xnpnode_t __mutex_pnode = {
+#else /* !CONFIG_PROC_FS */
 
-       .type = "mutexes"
+static struct xnpnode_file __mutex_pnode = {
+       .node = {
+               .dirname = "mutexes",
+       },
 };
 
 #endif /* !CONFIG_PROC_FS */
@@ -166,7 +216,7 @@ int sc_mcreate(unsigned int opt, int *errp)
        xnlock_put_irqrestore(&nklock, s);
 
        sprintf(mx->name, "mx%d", mid);
-       xnregistry_enter(mx->name, mx, &mx->handle, &__mutex_pnode);
+       xnregistry_enter(mx->name, mx, &mx->handle, &__mutex_pnode.node);
 
        *errp = RET_OK;
 
diff --git a/ksrc/skins/vrtx/pt.c b/ksrc/skins/vrtx/pt.c
index 154d0c3..db79642 100644
--- a/ksrc/skins/vrtx/pt.c
+++ b/ksrc/skins/vrtx/pt.c
@@ -26,46 +26,59 @@ static xnqueue_t vrtx_pt_q;
 
 #ifdef CONFIG_PROC_FS
 
-static int __pt_read_proc(char *page,
-                         char **start,
-                         off_t off, int count, int *eof, void *data)
+struct vfile_priv {
+       u_long bsize;
+       u_long fblks;
+       u_long ublks;
+};
+
+static int vfile_rewind(struct xnvfile_snapshot_iterator *it)
 {
-       vrtxpt_t *pt = (vrtxpt_t *)data;
-       char *p = page;
-       int len;
-
-       p += sprintf(p, "bsize=%lu:f_blocks=%lu:u_blocks=%lu\n",
-                    pt->bsize, pt->fblks, pt->ublks);
-
-       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;
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vrtxpt *pt = xnvfile_priv(it->vfile);
+
+       priv->bsize = pt->bsize;
+       priv->fblks = pt->fblks;
+       priv->ublks = pt->ublks;
+
+       return 0;
 }
 
-extern xnptree_t __vrtx_ptree;
+static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+
+       xnvfile_printf(it, "bsize=%lu:f_blocks=%lu:u_blocks=%lu\n",
+                      priv->bsize, priv->fblks, priv->ublks);
 
-static xnpnode_t __pt_pnode = {
+       return 0;
+}
 
-       .dir = NULL,
-       .type = "partitions",
-       .entries = 0,
-       .read_proc = &__pt_read_proc,
-       .write_proc = NULL,
-       .root = &__vrtx_ptree,
+static struct xnvfile_snapshot_ops vfile_ops = {
+       .rewind = vfile_rewind,
+       .show = vfile_show,
 };
 
-#else /* !CONFIG_PROC_FS */
+extern struct xnptree __vrtx_ptree;
+
+static struct xnpnode_file __pt_pnode = {
+       .node = {
+               .dirname = "partitions",
+               .root = &__vrtx_ptree,
+               .ops = &xnregistry_vfile_ops,
+       },
+       .vfile = {
+               .privsz = sizeof(struct vfile_priv),
+               .ops = &vfile_ops,
+       },
+};
 
-static xnpnode_t __pt_pnode = {
+#else /* !CONFIG_PROC_FS */
 
-       .type = "partitions"
+static struct xnpnode_file __pt_pnode = {
+       .node = {
+               .dirname = "partitions",
+       },
 };
 
 #endif /* !CONFIG_PROC_FS */
@@ -205,7 +218,7 @@ int sc_pcreate(int pid, char *paddr, long psize, long 
bsize, int *errp)
        xnlock_put_irqrestore(&nklock, s);
 
        sprintf(pt->name, "pt%d", pid);
-       xnregistry_enter(pt->name, pt, &pt->handle, &__pt_pnode);
+       xnregistry_enter(pt->name, pt, &pt->handle, &__pt_pnode.node);
 
        return pid;
 }
diff --git a/ksrc/skins/vrtx/queue.c b/ksrc/skins/vrtx/queue.c
index 7b5d109..efc5b1c 100644
--- a/ksrc/skins/vrtx/queue.c
+++ b/ksrc/skins/vrtx/queue.c
@@ -27,65 +27,115 @@ static xnqueue_t vrtx_queue_q;
 
 #ifdef CONFIG_PROC_FS
 
-static int __queue_read_proc(char *page,
-                            char **start,
-                            off_t off, int count, int *eof, void *data)
+struct vfile_priv {
+       int nrdata;
+       struct xnpholder *curr;
+       int qused;
+       int qsize;
+};
+
+struct vfile_data {
+       char name[XNOBJECT_NAME_LEN];
+};
+
+static int vfile_rewind(struct xnvfile_snapshot_iterator *it)
 {
-       vrtxqueue_t *queue = (vrtxqueue_t *)data;
-       char *p = page;
-       int len;
-       spl_t s;
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vrtxqueue *queue = xnvfile_priv(it->vfile);
 
-       p += sprintf(p, "mcount=%d, qsize=%d\n", queue->qused, queue->qsize);
+       priv->nrdata = xnsynch_nsleepers(&queue->synchbase);
+       priv->curr = getheadpq(xnsynch_wait_queue(&queue->synchbase));
+       priv->qused = queue->qused;
+       priv->qsize = queue->qsize;
 
-       xnlock_get_irqsave(&nklock, s);
+       return 0;
+}
 
-       if (xnsynch_nsleepers(&queue->synchbase) > 0) {
-               xnpholder_t *holder;
+static void *vfile_begin(struct xnvfile_snapshot_iterator *it)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
 
-               /* Pended queue -- dump waiters. */
+       if (priv->nrdata == 0)
+               /* No output beside the header. */
+               return VFILE_SEQ_EMPTY;
 
-               holder = getheadpq(xnsynch_wait_queue(&queue->synchbase));
+       return kmalloc(priv->nrdata * sizeof(struct vfile_data),
+                      GFP_KERNEL);
+}
 
-               while (holder) {
-                       xnthread_t *sleeper = link2thread(holder, plink);
-                       p += sprintf(p, "+%s\n", xnthread_name(sleeper));
-                       holder =
-                           nextpq(xnsynch_wait_queue(&queue->synchbase), 
holder);
-               }
-       }
+static void vfile_end(struct xnvfile_snapshot_iterator *it, void *buf)
+{
+       kfree(buf);
+}
 
-       xnlock_put_irqrestore(&nklock, s);
+static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vrtxqueue *queue = xnvfile_priv(it->vfile);
+       struct vfile_data *p = data;
+       struct xnthread *thread;
+
+       if (priv->curr == NULL)
+               return 0;       /* We are done. */
 
-       len = (p - page) - off;
-       if (len <= off + count)
-               *eof = 1;
-       *start = page + off;
-       if (len > count)
-               len = count;
-       if (len < 0)
-               len = 0;
+       /* Fetch current waiter, advance list cursor. */
+       thread = link2thread(priv->curr, plink);
+       priv->curr = nextpq(xnsynch_wait_queue(&queue->synchbase),
+                           priv->curr);
 
-       return len;
+       /* Collect thread name to be output in ->show(). */
+       strncpy(p->name, xnthread_name(thread), sizeof(p->name));
+
+       return 1;
 }
 
-extern xnptree_t __vrtx_ptree;
+static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vfile_data *p = data;
+
+       if (p == NULL) {        /* Dump header. */
+               xnvfile_printf(it, "mcount=%d, qsize=%d\n",
+                              priv->qused, priv->qsize);
+               if (priv->nrdata > 0)
+                       /* Queue is pended -- dump waiters */
+                       xnvfile_printf(it, 
"-------------------------------------------\n");
+       } else
+               xnvfile_printf(it, "%.*s\n",
+                              (int)sizeof(p->name), p->name);
+
+       return 0;
+}
 
-static xnpnode_t __queue_pnode = {
+static struct xnvfile_snapshot_ops vfile_ops = {
+       .rewind = vfile_rewind,
+       .begin = vfile_begin,
+       .next = vfile_next,
+       .end = vfile_end,
+       .show = vfile_show,
+};
 
-       .dir = NULL,
-       .type = "queues",
-       .entries = 0,
-       .read_proc = &__queue_read_proc,
-       .write_proc = NULL,
-       .root = &__vrtx_ptree,
+extern struct xnptree __vrtx_ptree;
+
+static struct xnpnode_file __queue_pnode = {
+       .node = {
+               .dirname = "queues",
+               .root = &__vrtx_ptree,
+               .ops = &xnregistry_vfile_ops,
+       },
+       .vfile = {
+               .privsz = sizeof(struct vfile_priv),
+               .datasz = sizeof(struct vfile_data),
+               .ops = &vfile_ops,
+       },
 };
 
 #else /* !CONFIG_PROC_FS */
 
-static xnpnode_t __queue_pnode = {
-
-       .type = "queues"
+static struct xnpnode_file __queue_pnode = {
+       .node = {
+               .dirname = "queues",
+       },
 };
 
 #endif /* !CONFIG_PROC_FS */
@@ -178,7 +228,7 @@ int sc_qecreate(int qid, int qsize, int opt, int *errp)
        xnlock_put_irqrestore(&nklock, s);
 
        sprintf(queue->name, "q%d", qid);
-       xnregistry_enter(queue->name, queue, &queue->handle, &__queue_pnode);
+       xnregistry_enter(queue->name, queue, &queue->handle, 
&__queue_pnode.node);
 
        return qid;
 }
diff --git a/ksrc/skins/vrtx/sem.c b/ksrc/skins/vrtx/sem.c
index 330465a..cc757b4 100644
--- a/ksrc/skins/vrtx/sem.c
+++ b/ksrc/skins/vrtx/sem.c
@@ -27,65 +27,112 @@ static xnqueue_t vrtx_sem_q;
 
 #ifdef CONFIG_PROC_FS
 
-static int sem_read_proc(char *page,
-                        char **start,
-                        off_t off, int count, int *eof, void *data)
+struct vfile_priv {
+       int nrdata;
+       struct xnpholder *curr;
+       unsigned long count;
+};
+
+struct vfile_data {
+       char name[XNOBJECT_NAME_LEN];
+};
+
+static int vfile_rewind(struct xnvfile_snapshot_iterator *it)
 {
-       vrtxsem_t *sem = (vrtxsem_t *)data;
-       char *p = page;
-       int len;
-       spl_t s;
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vrtxsem *sem = xnvfile_priv(it->vfile);
 
-       xnlock_get_irqsave(&nklock, s);
+       priv->nrdata = xnsynch_nsleepers(&sem->synchbase);
+       priv->curr = getheadpq(xnsynch_wait_queue(&sem->synchbase));
+       priv->count = sem->count;
 
-       p += sprintf(p, "value=%lu\n", sem->count);
+       return 0;
+}
 
-       if (xnsynch_nsleepers(&sem->synchbase) == 0) {
-               xnpholder_t *holder;
+static void *vfile_begin(struct xnvfile_snapshot_iterator *it)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
 
-               /* Pended semaphore -- dump waiters. */
+       if (priv->nrdata == 0)
+               /* No output beside the header. */
+               return VFILE_SEQ_EMPTY;
 
-               holder = getheadpq(xnsynch_wait_queue(&sem->synchbase));
+       return kmalloc(priv->nrdata * sizeof(struct vfile_data),
+                      GFP_KERNEL);
+}
 
-               while (holder) {
-                       xnthread_t *sleeper = link2thread(holder, plink);
-                       p += sprintf(p, "+%s\n", xnthread_name(sleeper));
-                       holder =
-                           nextpq(xnsynch_wait_queue(&sem->synchbase), holder);
-               }
-       }
+static void vfile_end(struct xnvfile_snapshot_iterator *it, void *buf)
+{
+       kfree(buf);
+}
 
-       xnlock_put_irqrestore(&nklock, s);
+static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vrtxsem *sem = xnvfile_priv(it->vfile);
+       struct vfile_data *p = data;
+       struct xnthread *thread;
 
-       len = (p - page) - off;
-       if (len <= off + count)
-               *eof = 1;
-       *start = page + off;
-       if (len > count)
-               len = count;
-       if (len < 0)
-               len = 0;
+       if (priv->curr == NULL)
+               return 0;       /* We are done. */
 
-       return len;
+       /* Fetch current waiter, advance list cursor. */
+       thread = link2thread(priv->curr, plink);
+       priv->curr = nextpq(xnsynch_wait_queue(&sem->synchbase),
+                           priv->curr);
+
+       /* Collect thread name to be output in ->show(). */
+       strncpy(p->name, xnthread_name(thread), sizeof(p->name));
+
+       return 1;
 }
 
-extern xnptree_t __vrtx_ptree;
+static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data)
+{
+       struct vfile_priv *priv = xnvfile_snapshot_iterator_priv(it);
+       struct vfile_data *p = data;
+
+       if (p == NULL) {        /* Dump header. */
+               xnvfile_printf(it, "value=%lu\n", priv->count);
+               if (priv->nrdata > 0)
+                       /* Semaphore is pended -- dump waiters */
+                       xnvfile_printf(it, 
"-------------------------------------------\n");
+       } else
+               xnvfile_printf(it, "%.*s\n",
+                              (int)sizeof(p->name), p->name);
 
-static xnpnode_t __sem_pnode = {
+       return 0;
+}
 
-       .dir = NULL,
-       .type = "semaphores",
-       .entries = 0,
-       .read_proc = &sem_read_proc,
-       .write_proc = NULL,
-       .root = &__vrtx_ptree,
+static struct xnvfile_snapshot_ops vfile_ops = {
+       .rewind = vfile_rewind,
+       .begin = vfile_begin,
+       .next = vfile_next,
+       .end = vfile_end,
+       .show = vfile_show,
 };
 
-#else /* !CONFIG_PROC_FS */
+extern struct xnptree __vrtx_ptree;
+
+static struct xnpnode_file __sem_pnode = {
+       .node = {
+               .dirname = "semaphores",
+               .root = &__vrtx_ptree,
+               .ops = &xnregistry_vfile_ops,
+       },
+       .vfile = {
+               .privsz = sizeof(struct vfile_priv),
+               .datasz = sizeof(struct vfile_data),
+               .ops = &vfile_ops,
+       },
+};
 
-static xnpnode_t __sem_pnode = {
+#else /* !CONFIG_PROC_FS */
 
-       .type = "semaphores"
+static struct xnpnode_file __sem_pnode = {
+       .node = {
+               .dirname = "semaphores",
+       },
 };
 
 #endif /* !CONFIG_PROC_FS */
@@ -164,7 +211,7 @@ int sc_screate(unsigned initval, int opt, int *errp)
        xnlock_put_irqrestore(&nklock, s);
 
        sprintf(sem->name, "sem%d", semid);
-       xnregistry_enter(sem->name, sem, &sem->handle, &__sem_pnode);
+       xnregistry_enter(sem->name, sem, &sem->handle, &__sem_pnode.node);
 
        *errp = RET_OK;
 


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to