Module: xenomai-rpm Branch: queue/vfile Commit: 55d8e70f780b37d15c676add835a8859f194b437 URL: http://git.xenomai.org/?p=xenomai-rpm.git;a=commit;h=55d8e70f780b37d15c676add835a8859f194b437
Author: Philippe Gerum <r...@xenomai.org> Date: Thu Apr 29 18:22:32 2010 +0200 native: convert to vfile --- ksrc/nucleus/heap.c | 2 +- ksrc/skins/native/alarm.c | 127 +++++++++++++++++++++------------- ksrc/skins/native/buffer.c | 168 +++++++++++++++++++++++++++----------------- ksrc/skins/native/cond.c | 110 +++++++++++++++++------------ ksrc/skins/native/event.c | 132 ++++++++++++++++++++++------------- ksrc/skins/native/heap.c | 142 +++++++++++++++++++++++-------------- ksrc/skins/native/intr.c | 137 ++++++++++++++++++++++-------------- ksrc/skins/native/module.c | 9 +-- ksrc/skins/native/mutex.c | 147 ++++++++++++++++++++++++-------------- ksrc/skins/native/pipe.c | 40 +++++++---- ksrc/skins/native/queue.c | 139 ++++++++++++++++++++++++------------- ksrc/skins/native/sem.c | 124 +++++++++++++++++++++------------ 12 files changed, 792 insertions(+), 485 deletions(-) diff --git a/ksrc/nucleus/heap.c b/ksrc/nucleus/heap.c index 2b148fc..a7e3ae4 100644 --- a/ksrc/nucleus/heap.c +++ b/ksrc/nucleus/heap.c @@ -144,7 +144,7 @@ static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data) p->usable_mem, p->used_mem, p->page_size, - sizeof(p->label), + (int)sizeof(p->label), p->label); return 0; } diff --git a/ksrc/skins/native/alarm.c b/ksrc/skins/native/alarm.c index 1130dfb..eeb714a 100644 --- a/ksrc/skins/native/alarm.c +++ b/ksrc/skins/native/alarm.c @@ -45,67 +45,98 @@ #ifdef CONFIG_PROC_FS -static int __alarm_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) -{ - RT_ALARM *alarm = (RT_ALARM *)data; - char *p = page; - int len; - spl_t s; +struct vfile_priv { + struct xnpholder *curr; + RTIME interval; + unsigned long expiries; +}; - xnlock_get_irqsave(&nklock, s); +struct vfile_data { + char name[XNOBJECT_NAME_LEN]; +}; - p += sprintf(p, "interval=%Lu:expiries=%lu\n", - rt_timer_tsc2ns(xntimer_interval(&alarm->timer_base)), - alarm->expiries); +static int vfile_rewind(struct xnvfile_snapshot_iterator *it) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_ALARM *alarm = xnvfile_priv(it->vfile); -#ifdef CONFIG_XENO_OPT_PERVASIVE - { - xnpholder_t *holder = - getheadpq(xnsynch_wait_queue(&alarm->synch_base)); - - while (holder) { - xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s\n", xnthread_name(sleeper)); - holder = - nextpq(xnsynch_wait_queue(&alarm->synch_base), - holder); - } - } -#endif /* CONFIG_XENO_OPT_PERVASIVE */ + alarm = xeno_h2obj_validate(alarm, XENO_ALARM_MAGIC, RT_ALARM); + if (alarm == NULL) + return -EIDRM; - xnlock_put_irqrestore(&nklock, s); + priv->curr = getheadpq(xnsynch_wait_queue(&alarm->synch_base)); + priv->interval = rt_timer_tsc2ns(xntimer_interval(&alarm->timer_base)); + priv->expiries = alarm->expiries; - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + return xnsynch_nsleepers(&alarm->synch_base); +} - return len; +static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_ALARM *alarm = 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(&alarm->synch_base), + priv->curr); + /* Collect thread name to be output in ->show(). */ + strncpy(p->name, xnthread_name(thread), sizeof(p->name)); + + return 1; } -extern xnptree_t __native_ptree; +static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + struct vfile_data *p = data; + + if (p == NULL) { /* Dump header. */ + xnvfile_printf(it, "%8s %s\n", "INTERVAL", "EXPIRIES"); + xnvfile_printf(it, "%8Lu %lu\n", + priv->interval, priv->expiries); + if (it->nrdata > 0) + /* Alarm is pended -- dump waiters */ + xnvfile_printf(it, "------------------\n"); + } else + xnvfile_printf(it, "%.*s\n", + (int)sizeof(p->name), p->name); -static xnpnode_t __alarm_pnode = { + return 0; +} - .dir = NULL, - .type = "alarms", - .entries = 0, - .read_proc = &__alarm_read_proc, - .write_proc = NULL, - .root = &__native_ptree, +static struct xnvfile_snapshot_ops vfile_ops = { + .rewind = vfile_rewind, + .next = vfile_next, + .show = vfile_show, }; -#else /* !CONFIG_PROC_FS */ +extern struct xnptree __native_ptree; + +static struct xnpnode_file __alarm_pnode = { + .node = { + .dirname = "alarms", + .root = &__native_ptree, + .ops = &xnregistry_vfile_ops, + }, + .vfile = { + .privsz = sizeof(struct vfile_priv), + .datasz = sizeof(struct vfile_data), + .ops = &vfile_ops, + }, +}; -static xnpnode_t __alarm_pnode = { +#else /* !CONFIG_PROC_FS */ - .type = "alarms" +static struct xnpnode_file __alarm_pnode = { + .node = { + .dirname = "alarms", + }, }; #endif /* !CONFIG_PROC_FS */ @@ -226,7 +257,7 @@ int rt_alarm_create(RT_ALARM *alarm, * handles to half-baked objects... */ err = xnregistry_enter((*name) ? alarm->name : "", alarm, - &alarm->handle, &__alarm_pnode); + &alarm->handle, &__alarm_pnode.node); if (err) rt_alarm_delete(alarm); diff --git a/ksrc/skins/native/buffer.c b/ksrc/skins/native/buffer.c index 8aca559..42b75da 100644 --- a/ksrc/skins/native/buffer.c +++ b/ksrc/skins/native/buffer.c @@ -50,81 +50,119 @@ #ifdef CONFIG_PROC_FS -static int __buffer_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) -{ - RT_BUFFER *bf = (RT_BUFFER *)data; - char *p = page; - int len; - spl_t s; - - xnlock_get_irqsave(&nklock, s); - - p += sprintf(p, "type=%s:size=%zu:used=%zu\n", - bf->mode & B_PRIO ? "PRIO" : "FIFO", - bf->bufsz, - bf->fillsz); - - if (xnsynch_nsleepers(&bf->isynch_base) > 0) { - xnpholder_t *holder; - - holder = getheadpq(xnsynch_wait_queue(&bf->osynch_base)); - - while (holder) { - xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s (input)\n", xnthread_name(sleeper)); - holder = - nextpq(xnsynch_wait_queue(&bf->isynch_base), - holder); - } - } +struct vfile_priv { + struct xnpholder *curr; + int mode; + size_t bufsz; + size_t fillsz; + int input; +}; - if (xnsynch_nsleepers(&bf->osynch_base) > 0) { - xnpholder_t *holder; +struct vfile_data { + char name[XNOBJECT_NAME_LEN]; + int input; +}; - holder = getheadpq(xnsynch_wait_queue(&bf->osynch_base)); +static int vfile_rewind(struct xnvfile_snapshot_iterator *it) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_BUFFER *bf = xnvfile_priv(it->vfile); - while (holder) { - xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s (output)\n", xnthread_name(sleeper)); - holder = - nextpq(xnsynch_wait_queue(&bf->osynch_base), - holder); - } - } + bf = xeno_h2obj_validate(bf, XENO_BUFFER_MAGIC, RT_BUFFER); + if (bf == NULL) + return -EIDRM; + + /* Start collecting records from the input wait side. */ + priv->curr = getheadpq(xnsynch_wait_queue(&bf->isynch_base)); + priv->mode = bf->mode; + priv->bufsz = bf->bufsz; + priv->fillsz = bf->fillsz; + priv->input = 1; + + return xnsynch_nsleepers(&bf->isynch_base) + + xnsynch_nsleepers(&bf->osynch_base); +} - xnlock_put_irqrestore(&nklock, s); +static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_BUFFER *bf = xnvfile_priv(it->vfile); + struct vfile_data *p = data; + struct xnthread *thread; + struct xnpqueue *waitq; + + if (priv->curr == NULL) { /* Attempt to switch queues. */ + if (!priv->input) + /* Finished output side, we are done. */ + return 0; + priv->input = 0; + waitq = xnsynch_wait_queue(&bf->osynch_base); + priv->curr = getheadpq(waitq); + if (priv->curr == NULL) + return 0; + } else + waitq = priv->input ? xnsynch_wait_queue(&bf->isynch_base) : + xnsynch_wait_queue(&bf->osynch_base); + + /* Fetch current waiter, advance list cursor. */ + thread = link2thread(priv->curr, plink); + priv->curr = nextpq(waitq, priv->curr); + /* Collect thread name to be output in ->show(). */ + strncpy(p->name, xnthread_name(thread), sizeof(p->name)); + p->input = priv->input; + + return 1; +} - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; +static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + struct vfile_data *p = data; + + if (p == NULL) { /* Dump header. */ + xnvfile_printf(it, "%4s %9s %9s\n", + "TYPE", "TOTALMEM", "USEDMEM"); + xnvfile_printf(it, "%s %9Zu %9Zu\n", + priv->mode & B_PRIO ? "PRIO" : "FIFO", + priv->bufsz, priv->fillsz); + if (it->nrdata > 0) + /* Buffer is pended -- dump waiters */ + xnvfile_printf(it, "\n%3s %s\n", "WAY", "WAITER"); + } else + xnvfile_printf(it, "%3s %.*s\n", + p->input ? "in" : "out", + (int)sizeof(p->name), p->name); - return len; + return 0; } -extern xnptree_t __native_ptree; - -static xnpnode_t __buffer_pnode = { +static struct xnvfile_snapshot_ops vfile_ops = { + .rewind = vfile_rewind, + .next = vfile_next, + .show = vfile_show, +}; - .dir = NULL, - .type = "buffers", - .entries = 0, - .read_proc = &__buffer_read_proc, - .write_proc = NULL, - .root = &__native_ptree, +extern struct xnptree __native_ptree; + +static struct xnpnode_file __buffer_pnode = { + .node = { + .dirname = "buffers", + .root = &__native_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 __buffer_pnode = { - - .type = "buffers" +static struct xnpnode_file __buffer_pnode = { + .node = { + .dirname = "buffers", + }, }; #endif /* !CONFIG_PROC_FS */ @@ -234,7 +272,7 @@ int rt_buffer_create(RT_BUFFER *bf, const char *name, size_t bufsz, int mode) */ if (name) { ret = xnregistry_enter(bf->name, bf, &bf->handle, - &__buffer_pnode); + &__buffer_pnode.node); if (ret) rt_buffer_delete(bf); diff --git a/ksrc/skins/native/cond.c b/ksrc/skins/native/cond.c index 86f83ff..1f8fe52 100644 --- a/ksrc/skins/native/cond.c +++ b/ksrc/skins/native/cond.c @@ -50,64 +50,86 @@ #ifdef CONFIG_PROC_FS -static int __cond_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) -{ - RT_COND *cond = (RT_COND *)data; - char *p = page; - int len; - spl_t s; +struct vfile_priv { + struct xnpholder *curr; +}; - xnlock_get_irqsave(&nklock, s); +struct vfile_data { + char name[XNOBJECT_NAME_LEN]; +}; - if (xnsynch_nsleepers(&cond->synch_base) > 0) { - xnpholder_t *holder; +static int vfile_rewind(struct xnvfile_snapshot_iterator *it) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_COND *cond = xnvfile_priv(it->vfile); - /* Pended condvar -- dump waiters. */ + cond = xeno_h2obj_validate(cond, XENO_COND_MAGIC, RT_COND); + if (cond == NULL) + return -EIDRM; - holder = getheadpq(xnsynch_wait_queue(&cond->synch_base)); + priv->curr = getheadpq(xnsynch_wait_queue(&cond->synch_base)); - while (holder) { - xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s\n", xnthread_name(sleeper)); - holder = - nextpq(xnsynch_wait_queue(&cond->synch_base), - holder); - } - } + return xnsynch_nsleepers(&cond->synch_base); +} - xnlock_put_irqrestore(&nklock, s); +static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_COND *cond = 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(&cond->synch_base), + priv->curr); + /* Collect thread name to be output in ->show(). */ + strncpy(p->name, xnthread_name(thread), sizeof(p->name)); + + return 1; +} - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; +static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_data *p = data; - return len; -} + if (p) /* No header */ + xnvfile_printf(it, "%.*s\n", + (int)sizeof(p->name), p->name); -extern xnptree_t __native_ptree; + return 0; +} -static xnpnode_t __cond_pnode = { +static struct xnvfile_snapshot_ops vfile_ops = { + .rewind = vfile_rewind, + .next = vfile_next, + .show = vfile_show, +}; - .dir = NULL, - .type = "condvars", - .entries = 0, - .read_proc = &__cond_read_proc, - .write_proc = NULL, - .root = &__native_ptree, +extern struct xnptree __native_ptree; + +static struct xnpnode_file __cond_pnode = { + .node = { + .dirname = "condvars", + .root = &__native_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 __cond_pnode = { - - .type = "condvars" +static struct xnpnode_file __cond_pnode = { + .node = { + .dirname = "condvars", + }, }; #endif /* !CONFIG_PROC_FS */ @@ -181,7 +203,7 @@ int rt_cond_create(RT_COND *cond, const char *name) */ if (name) { err = xnregistry_enter(cond->name, cond, &cond->handle, - &__cond_pnode); + &__cond_pnode.node); if (err) rt_cond_delete(cond); diff --git a/ksrc/skins/native/event.c b/ksrc/skins/native/event.c index 5b2a8b5..33c56e0 100644 --- a/ksrc/skins/native/event.c +++ b/ksrc/skins/native/event.c @@ -47,72 +47,106 @@ #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 { + struct xnpholder *curr; + unsigned long value; +}; + +struct vfile_data { + int mode; + unsigned long mask; + char name[XNOBJECT_NAME_LEN]; +}; + +static int vfile_rewind(struct xnvfile_snapshot_iterator *it) { - RT_EVENT *event = (RT_EVENT *)data; - char *p = page; - int len; - spl_t s; + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_EVENT *event = xnvfile_priv(it->vfile); - xnlock_get_irqsave(&nklock, s); + event = xeno_h2obj_validate(event, XENO_EVENT_MAGIC, RT_EVENT); + if (event == NULL) + return -EIDRM; - p += sprintf(p, "=0x%lx\n", event->value); + priv->curr = getheadpq(xnsynch_wait_queue(&event->synch_base)); + priv->value = event->value; - if (xnsynch_nsleepers(&event->synch_base) > 0) { - xnpholder_t *holder; + return xnsynch_nsleepers(&event->synch_base); +} - /* Pended event -- dump waiters. */ +static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_EVENT *event = xnvfile_priv(it->vfile); + struct vfile_data *p = data; + struct xnthread *thread; + RT_TASK *task; - holder = getheadpq(xnsynch_wait_queue(&event->synch_base)); + priv->value = event->value; /* Refresh as we collect. */ - while (holder) { - xnthread_t *sleeper = link2thread(holder, plink); - RT_TASK *task = thread2rtask(sleeper); - const char *mode = - (task->wait_args.event. - mode & EV_ANY) ? "any" : "all"; - unsigned long mask = task->wait_args.event.mask; - p += sprintf(p, "+%s (mask=0x%lx, %s)\n", - xnthread_name(sleeper), mask, mode); - holder = - nextpq(xnsynch_wait_queue(&event->synch_base), - holder); - } - } + if (priv->curr == NULL) + return 0; /* We are done. */ - xnlock_put_irqrestore(&nklock, s); + /* Fetch current waiter, advance list cursor. */ + thread = link2thread(priv->curr, plink); + priv->curr = nextpq(xnsynch_wait_queue(&event->synch_base), + priv->curr); - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + /* Collect thread name to be output in ->show(). */ + strncpy(p->name, xnthread_name(thread), sizeof(p->name)); + task = thread2rtask(thread); + p->mode = task->wait_args.event.mode; + p->mask = task->wait_args.event.mask; - return len; + return 1; } -extern xnptree_t __native_ptree; +static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + struct vfile_data *p = data; + + if (p == NULL) { /* Dump header. */ + /* Always dump current event mask value. */ + xnvfile_printf(it, "=0x%lx\n", priv->value); + if (it->nrdata > 0) + xnvfile_printf(it, "\n%10s %4s %s\n", + "MASK", "MODE", "WAITER"); + } else + xnvfile_printf(it, "0x%-8lx %4s %.*s\n", + p->mask, + p->mode & EV_ANY ? "any" : "all", + (int)sizeof(p->name), p->name); + + return 0; +} -static xnpnode_t __event_pnode = { +static struct xnvfile_snapshot_ops vfile_ops = { + .rewind = vfile_rewind, + .next = vfile_next, + .show = vfile_show, +}; - .dir = NULL, - .type = "events", - .entries = 0, - .read_proc = &__event_read_proc, - .write_proc = NULL, - .root = &__native_ptree, +extern struct xnptree __native_ptree; + +static struct xnpnode_file __event_pnode = { + .node = { + .dirname = "events", + .root = &__native_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 __event_pnode = { + .node = { + .dirname = "events", + }, }; #endif /* !CONFIG_PROC_FS */ @@ -205,7 +239,7 @@ int rt_event_create(RT_EVENT *event, */ if (name) { err = xnregistry_enter(event->name, event, &event->handle, - &__event_pnode); + &__event_pnode.node); if (err) rt_event_delete(event); diff --git a/ksrc/skins/native/heap.c b/ksrc/skins/native/heap.c index 2a5de8c..7cb03ba 100644 --- a/ksrc/skins/native/heap.c +++ b/ksrc/skins/native/heap.c @@ -51,73 +51,109 @@ #ifdef CONFIG_PROC_FS -static int __heap_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) -{ - RT_HEAP *heap = (RT_HEAP *)data; - char *p = page; - int len; - spl_t s; - - p += sprintf(p, "type=%s:size=%lu:used=%lu:numaps=%lu\n", - (heap->mode & H_SHARED) == H_SHARED ? "shared" : - (heap->mode & H_MAPPABLE) ? "mappable" : "kernel", - xnheap_usable_mem(&heap->heap_base), - xnheap_used_mem(&heap->heap_base), - heap->heap_base.archdep.numaps); +struct vfile_priv { + struct xnpholder *curr; + int mode; + size_t usable_mem; + size_t used_mem; + int nrmaps; +}; - xnlock_get_irqsave(&nklock, s); +struct vfile_data { + char name[XNOBJECT_NAME_LEN]; + size_t size; +}; - if (xnsynch_nsleepers(&heap->synch_base) > 0) { - xnpholder_t *holder; +static int vfile_rewind(struct xnvfile_snapshot_iterator *it) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_HEAP *heap = xnvfile_priv(it->vfile); - /* Pended heap -- dump waiters. */ + heap = xeno_h2obj_validate(heap, XENO_HEAP_MAGIC, RT_HEAP); + if (heap == NULL) + return -EIDRM; - holder = getheadpq(xnsynch_wait_queue(&heap->synch_base)); + priv->curr = getheadpq(xnsynch_wait_queue(&heap->synch_base)); + priv->mode = heap->mode; + priv->usable_mem = xnheap_usable_mem(&heap->heap_base); + priv->used_mem = xnheap_used_mem(&heap->heap_base); + priv->nrmaps = heap->heap_base.archdep.numaps; - while (holder) { - xnthread_t *sleeper = link2thread(holder, plink); - size_t size = sleeper->wait_u.buffer.size; - p += sprintf(p, "+%s (size=%zd)\n", - xnthread_name(sleeper), size); - holder = - nextpq(xnsynch_wait_queue(&heap->synch_base), - holder); - } - } + return xnsynch_nsleepers(&heap->synch_base); +} - xnlock_put_irqrestore(&nklock, s); +static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_HEAP *heap = 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(&heap->synch_base), + priv->curr); + /* Collect thread info to be output in ->show(). */ + strncpy(p->name, xnthread_name(thread), sizeof(p->name)); + p->size = thread->wait_u.buffer.size; + + return 1; +} - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; +static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + struct vfile_data *p = data; + + if (p == NULL) { /* Dump header. */ + xnvfile_printf(it, "%5s %9s %9s %s\n", + "TYPE", "TOTALMEM", "USEDMEM", "NRMAPS"); + xnvfile_printf(it, "%5s %9Zu %9Zu %d\n", + priv->mode & H_SHARED ? "shared" : + (priv->mode & H_MAPPABLE) ? "mappable" : "kernel", + priv->usable_mem, + priv->used_mem, + priv->nrmaps); + if (it->nrdata > 0) + /* Heap is pended -- dump waiters */ + xnvfile_printf(it, "\n%7s %s\n", "REQSZ", "WAITER"); + } else + xnvfile_printf(it, "%7Zu %.*s\n", + p->size, (int)sizeof(p->name), p->name); - return len; + return 0; } -extern xnptree_t __native_ptree; - -static xnpnode_t __heap_pnode = { +static struct xnvfile_snapshot_ops vfile_ops = { + .rewind = vfile_rewind, + .next = vfile_next, + .show = vfile_show, +}; - .dir = NULL, - .type = "heaps", - .entries = 0, - .read_proc = &__heap_read_proc, - .write_proc = NULL, - .root = &__native_ptree, +extern struct xnptree __native_ptree; + +static struct xnpnode_file __heap_pnode = { + .node = { + .dirname = "heaps", + .root = &__native_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 __heap_pnode = { - - .type = "heaps" +static struct xnpnode_file __heap_pnode = { + .node = { + .dirname = "heap", + }, }; #endif /* !CONFIG_PROC_FS */ @@ -313,7 +349,7 @@ int rt_heap_create(RT_HEAP *heap, const char *name, size_t heapsize, int mode) */ if (name) { err = xnregistry_enter(heap->name, heap, &heap->handle, - &__heap_pnode); + &__heap_pnode.node); if (err) rt_heap_delete(heap); diff --git a/ksrc/skins/native/intr.c b/ksrc/skins/native/intr.c index a69bd46..0377864 100644 --- a/ksrc/skins/native/intr.c +++ b/ksrc/skins/native/intr.c @@ -58,72 +58,101 @@ static unsigned long __intr_get_hits(RT_INTR *intr) #ifdef CONFIG_PROC_FS -static int __intr_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) -{ - RT_INTR *intr = (RT_INTR *)data; - char *p = page; - int len; - spl_t s; - - xnlock_get_irqsave(&nklock, s); +struct vfile_priv { + struct xnpholder *curr; + int mode; + unsigned long hits; + unsigned int pending; +}; -#ifdef CONFIG_XENO_OPT_PERVASIVE - { - xnpholder_t *holder; +struct vfile_data { + char name[XNOBJECT_NAME_LEN]; +}; - p += sprintf(p, "hits=%lu, pending=%u, mode=0x%x\n", - __intr_get_hits(intr), intr->pending, - intr->mode); +static int vfile_rewind(struct xnvfile_snapshot_iterator *it) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_INTR *intr = xnvfile_priv(it->vfile); - /* Pended interrupt -- dump waiters. */ + intr = xeno_h2obj_validate(intr, XENO_INTR_MAGIC, RT_INTR); + if (intr == NULL) + return -EIDRM; - holder = getheadpq(xnsynch_wait_queue(&intr->synch_base)); + priv->curr = getheadpq(xnsynch_wait_queue(&intr->synch_base)); + priv->mode = intr->mode; + priv->hits = __intr_get_hits(intr); + priv->pending = intr->pending; - while (holder) { - xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s\n", xnthread_name(sleeper)); - holder = - nextpq(xnsynch_wait_queue(&intr->synch_base), - holder); - } - } -#else /* !CONFIG_XENO_OPT_PERVASIVE */ - p += sprintf(p, "hits=%lu\n", __intr_get_hits(intr)); -#endif /* CONFIG_XENO_OPT_PERVASIVE */ + return xnsynch_nsleepers(&intr->synch_base); +} - xnlock_put_irqrestore(&nklock, s); +static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_INTR *intr = 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(&intr->synch_base), + priv->curr); + /* Collect thread name to be output in ->show(). */ + strncpy(p->name, xnthread_name(thread), sizeof(p->name)); + + return 1; +} - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; +static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + struct vfile_data *p = data; + + if (p == NULL) { /* Dump header. */ + xnvfile_printf(it, "%9s %2s %s\n", + "HITS", "PENDING", "MODE"); + xnvfile_printf(it, "%9lu %u 0x%x\n", + priv->hits, priv->pending, priv->mode); + if (it->nrdata > 0) + /* Interrupt is pended -- dump waiters */ + xnvfile_printf(it, "-------------------\n"); + } else + xnvfile_printf(it, "%.*s\n", + (int)sizeof(p->name), p->name); - return len; + return 0; } -extern xnptree_t __native_ptree; - -static xnpnode_t __intr_pnode = { +static struct xnvfile_snapshot_ops vfile_ops = { + .rewind = vfile_rewind, + .next = vfile_next, + .show = vfile_show, +}; - .dir = NULL, - .type = "interrupts", - .entries = 0, - .read_proc = &__intr_read_proc, - .write_proc = NULL, - .root = &__native_ptree, +extern struct xnptree __native_ptree; + +static struct xnpnode_file __intr_pnode = { + .node = { + .dirname = "interrupts", + .root = &__native_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 __intr_pnode = { - - .type = "interrupts" +static struct xnpnode_file __intr_pnode = { + .node = { + .dirname = "interrupts", + }, }; #endif /* !CONFIG_PROC_FS */ @@ -288,7 +317,7 @@ int rt_intr_create(RT_INTR *intr, */ if (!err && name) err = xnregistry_enter(intr->name, intr, &intr->handle, - &__intr_pnode); + &__intr_pnode.node); if (err) rt_intr_delete(intr); diff --git a/ksrc/skins/native/module.c b/ksrc/skins/native/module.c index 1a51bcf..60ca5aa 100644 --- a/ksrc/skins/native/module.c +++ b/ksrc/skins/native/module.c @@ -54,14 +54,7 @@ xntbase_t *__native_tbase; xeno_rholder_t __native_global_rholder; -#ifdef CONFIG_PROC_FS -xnptree_t __native_ptree = { - - .dir = NULL, - .name = "native", - .entries = 0, -}; -#endif /* CONFIG_PROC_FS */ +DEFINE_XNPTREE(__native_ptree, "native"); int SKIN_INIT(native) { diff --git a/ksrc/skins/native/mutex.c b/ksrc/skins/native/mutex.c index 6cf7eb1..3f07c21 100644 --- a/ksrc/skins/native/mutex.c +++ b/ksrc/skins/native/mutex.c @@ -53,83 +53,120 @@ #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 { + 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) { - RT_MUTEX *mutex = (RT_MUTEX *)data; + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_MUTEX *mutex = xnvfile_priv(it->vfile); + struct xnthread *owner; #ifdef CONFIG_XENO_FASTSYNCH xnhandle_t lock_state; -#endif /* CONFIG_XENO_FASTSYNCH */ - xnthread_t *owner; - char *p = page; - int len; - spl_t s; - - xnlock_get_irqsave(&nklock, s); +#endif + mutex = xeno_h2obj_validate(mutex, XENO_MUTEX_MAGIC, RT_MUTEX); + if (mutex == NULL) + return -EIDRM; -#ifndef CONFIG_XENO_FASTSYNCH - owner = xnsynch_owner(&mutex->synch_base); -#else /* CONFIG_XENO_FASTSYNCH */ +#ifdef CONFIG_XENO_FASTSYNCH lock_state = xnarch_atomic_get(mutex->synch_base.fastlock); - owner = (lock_state == XN_NO_HANDLE) ? NULL : xnthread_lookup(xnsynch_fast_mask_claimed(lock_state)); - if (!owner && lock_state != XN_NO_HANDLE) - p += sprintf(p, "=<DAMAGED HANDLE!>"); + if (owner == NULL && lock_state != XN_NO_HANDLE) + strncpy(priv->owner, "<DAMAGED HANDLE>", + sizeof(priv->owner)); else -#endif /* CONFIG_XENO_FASTSYNCH */ - if (owner) { - /* Locked mutex -- dump owner and waiters, if any. */ - xnpholder_t *holder; +#else /* !CONFIG_XENO_FASTSYNCH */ + owner = xnsynch_owner(&mutex->synch_base); +#endif /* !CONFIG_XENO_FASTSYNCH */ + 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)); + priv->curr = getheadpq(xnsynch_wait_queue(&mutex->synch_base)); - holder = getheadpq(xnsynch_wait_queue(&mutex->synch_base)); + return xnsynch_nsleepers(&mutex->synch_base); +} - while (holder) { - xnthread_t *sleeper = link2thread(holder, plink); +static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_MUTEX *mutex = 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(&mutex->synch_base), + priv->curr); + /* Collect thread name to be output in ->show(). */ + strncpy(p->name, xnthread_name(thread), sizeof(p->name)); + + return 1; +} - p += sprintf(p, "+%s\n", xnthread_name(sleeper)); - holder = nextpq(xnsynch_wait_queue(&mutex->synch_base), - holder); +static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + struct vfile_data *p = data; + + if (p == NULL) { /* Dump header. */ + if (*priv->owner == 0) + /* Unlocked mutex. */ + xnvfile_printf(it, "=unlocked\n"); + else { + xnvfile_printf(it, "=locked by %.*s\n", + (int)sizeof(priv->owner), priv->owner); + if (it->nrdata > 0) + /* Mutex is contended -- dump waiters */ + xnvfile_printf(it, "--------------------\n"); } } else - /* Mutex unlocked. */ - p += sprintf(p, "=unlocked\n"); - - xnlock_put_irqrestore(&nklock, s); - - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + xnvfile_printf(it, "%.*s\n", + (int)sizeof(p->name), p->name); - return len; + return 0; } -extern xnptree_t __native_ptree; - -static xnpnode_t __mutex_pnode = { +static struct xnvfile_snapshot_ops vfile_ops = { + .rewind = vfile_rewind, + .next = vfile_next, + .show = vfile_show, +}; - .dir = NULL, - .type = "mutexes", - .entries = 0, - .read_proc = &__mutex_read_proc, - .write_proc = NULL, - .root = &__native_ptree, +extern struct xnptree __native_ptree; + +static struct xnpnode_file __mutex_pnode = { + .node = { + .dirname = "mutexes", + .root = &__native_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 __mutex_pnode = { - - .type = "mutexes" +static struct xnpnode_file __mutex_pnode = { + .node = { + .dirname = "mutexes", + }, }; #endif /* !CONFIG_PROC_FS */ @@ -166,7 +203,7 @@ int rt_mutex_create_inner(RT_MUTEX *mutex, const char *name, */ if (name) { err = xnregistry_enter(mutex->name, mutex, &mutex->handle, - &__mutex_pnode); + &__mutex_pnode.node); if (err) rt_mutex_delete_inner(mutex); diff --git a/ksrc/skins/native/pipe.c b/ksrc/skins/native/pipe.c index d756758..d8a1d91 100644 --- a/ksrc/skins/native/pipe.c +++ b/ksrc/skins/native/pipe.c @@ -54,28 +54,38 @@ #ifdef CONFIG_PROC_FS -static ssize_t __pipe_link_proc(char *buf, int count, void *data) +static char *__pipe_link_target(void *obj) { - RT_PIPE *pipe = (RT_PIPE *)data; - return snprintf(buf, count, "/dev/rtp%d", pipe->minor); -} + RT_PIPE *pipe = obj; + char *buf; + + /* XXX: older kernels don't have kasprintf(). */ + buf = kmalloc(32, GFP_KERNEL); + if (buf == NULL) + return buf; + + snprintf(buf, 32, "/dev/rtp%d", pipe->minor); -extern xnptree_t __native_ptree; + return buf; +} -static xnpnode_t __pipe_pnode = { +extern struct xnptree __native_ptree; - .dir = NULL, - .type = "pipes", - .entries = 0, - .link_proc = &__pipe_link_proc, - .root = &__native_ptree, +static struct xnpnode_link __pipe_pnode = { + .node = { + .dirname = "pipes", + .root = &__native_ptree, + .ops = &xnregistry_vlink_ops, + }, + .target = __pipe_link_target, }; #else /* !CONFIG_PROC_FS */ -static xnpnode_t __pipe_pnode = { - - .type = "pipes" +static struct xnpnode_link __pipe_pnode = { + .node = { + .dirname = "pipes", + }, }; #endif /* !CONFIG_PROC_FS */ @@ -352,7 +362,7 @@ int rt_pipe_create(RT_PIPE *pipe, const char *name, int minor, size_t poolsize) */ if (name) { err = xnregistry_enter(pipe->name, pipe, &pipe->handle, - &__pipe_pnode); + &__pipe_pnode.node); if (err) rt_pipe_delete(pipe); } diff --git a/ksrc/skins/native/queue.c b/ksrc/skins/native/queue.c index 6a71165..6734003 100644 --- a/ksrc/skins/native/queue.c +++ b/ksrc/skins/native/queue.c @@ -49,68 +49,110 @@ #ifdef CONFIG_PROC_FS -static int __queue_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) -{ - RT_QUEUE *q = (RT_QUEUE *)data; - char *p = page; - int len; - spl_t s; - - p += sprintf(p, "type=%s:poolsz=%lu:usedmem=%lu:limit=%d:mcount=%d\n", - q->mode & Q_SHARED ? "shared" : "local", - xnheap_usable_mem(&q->bufpool), xnheap_used_mem(&q->bufpool), - q->qlimit, countq(&q->pendq)); +struct vfile_priv { + struct xnpholder *curr; + int mode; + size_t usable_mem; + size_t used_mem; + size_t limit; + size_t count; +}; - xnlock_get_irqsave(&nklock, s); +struct vfile_data { + char name[XNOBJECT_NAME_LEN]; +}; - if (xnsynch_nsleepers(&q->synch_base) > 0) { - xnpholder_t *holder; +static int vfile_rewind(struct xnvfile_snapshot_iterator *it) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_QUEUE *q = xnvfile_priv(it->vfile); - /* Pended queue -- dump waiters. */ + q = xeno_h2obj_validate(q, XENO_QUEUE_MAGIC, RT_QUEUE); + if (q == NULL) + return -EIDRM; - holder = getheadpq(xnsynch_wait_queue(&q->synch_base)); + priv->curr = getheadpq(xnsynch_wait_queue(&q->synch_base)); + priv->mode = q->mode; + priv->usable_mem = xnheap_usable_mem(&q->bufpool); + priv->used_mem = xnheap_used_mem(&q->bufpool); + priv->limit = q->qlimit; + priv->count = countq(&q->pendq); - while (holder) { - xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s\n", xnthread_name(sleeper)); - holder = - nextpq(xnsynch_wait_queue(&q->synch_base), holder); - } - } + return xnsynch_nsleepers(&q->synch_base); +} - xnlock_put_irqrestore(&nklock, s); +static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_QUEUE *q = 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(&q->synch_base), + priv->curr); + /* Collect thread name to be output in ->show(). */ + strncpy(p->name, xnthread_name(thread), sizeof(p->name)); + + return 1; +} - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; +static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + struct vfile_data *p = data; + + if (p == NULL) { /* Dump header. */ + xnvfile_printf(it, "%5s %9s %9s %6s %s\n", + "TYPE", "TOTALMEM", "USEDMEM", + "QLIMIT", "MCOUNT"); + xnvfile_printf(it, "%4s %9Zu %9Zu %6Zu %Zu\n", + priv->mode & Q_SHARED ? "shared" : "local", + priv->usable_mem, + priv->used_mem, + priv->limit, + priv->count); + if (it->nrdata > 0) + /* Queue is pended -- dump waiters */ + xnvfile_printf(it, "-------------------------------------------\n"); + } else + xnvfile_printf(it, "%.*s\n", + (int)sizeof(p->name), p->name); - return len; + return 0; } -extern xnptree_t __native_ptree; - -static xnpnode_t __queue_pnode = { +static struct xnvfile_snapshot_ops vfile_ops = { + .rewind = vfile_rewind, + .next = vfile_next, + .show = vfile_show, +}; - .dir = NULL, - .type = "queues", - .entries = 0, - .read_proc = &__queue_read_proc, - .write_proc = NULL, - .root = &__native_ptree, +extern struct xnptree __native_ptree; + +static struct xnpnode_file __q_pnode = { + .node = { + .dirname = "queues", + .root = &__native_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 __q_pnode = { + .node = { + .dirname = "queues", + }, }; #endif /* !CONFIG_PROC_FS */ @@ -276,7 +318,8 @@ int rt_queue_create(RT_QUEUE *q, * handles to half-baked objects... */ if (name) { - err = xnregistry_enter(q->name, q, &q->handle, &__queue_pnode); + err = xnregistry_enter(q->name, q, + &q->handle, &__q_pnode.node); if (err) rt_queue_delete(q); } diff --git a/ksrc/skins/native/sem.c b/ksrc/skins/native/sem.c index 0afea09..8e47627 100644 --- a/ksrc/skins/native/sem.c +++ b/ksrc/skins/native/sem.c @@ -50,67 +50,101 @@ #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 { + struct xnpholder *curr; + unsigned long count; +}; + +struct vfile_data { + char name[XNOBJECT_NAME_LEN]; +}; + +static int vfile_rewind(struct xnvfile_snapshot_iterator *it) { - RT_SEM *sem = (RT_SEM *)data; - char *p = page; - int len; - spl_t s; + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_SEM *sem = xnvfile_priv(it->vfile); - xnlock_get_irqsave(&nklock, s); + sem = xeno_h2obj_validate(sem, XENO_SEM_MAGIC, RT_SEM); + if (sem == NULL) + return -EIDRM; - if (xnsynch_nsleepers(&sem->synch_base) == 0) - /* Idle/posted semaphore -- dump count. */ - p += sprintf(p, "=%lu\n", sem->count); - else { - xnpholder_t *holder; + priv->curr = getheadpq(xnsynch_wait_queue(&sem->synch_base)); + priv->count = sem->count; - /* Pended semaphore -- dump waiters. */ + return xnsynch_nsleepers(&sem->synch_base); +} - holder = getheadpq(xnsynch_wait_queue(&sem->synch_base)); +static int vfile_next(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + RT_SEM *sem = xnvfile_priv(it->vfile); + struct vfile_data *p = data; + struct xnthread *thread; - while (holder) { - xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s\n", xnthread_name(sleeper)); - holder = - nextpq(xnsynch_wait_queue(&sem->synch_base), - holder); - } - } + /* + * Refresh the semaphore count as we get waiters, to reduce + * the odds for inconsistency (that value may change while + * collecting records, and we don't want to touch the revision + * tag each time that value changes). + */ + priv->count = sem->count; - xnlock_put_irqrestore(&nklock, s); + 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(&sem->synch_base), + priv->curr); + /* Collect thread name to be output in ->show(). */ + strncpy(p->name, xnthread_name(thread), sizeof(p->name)); - return len; + return 1; } -extern xnptree_t __native_ptree; +static int vfile_show(struct xnvfile_snapshot_iterator *it, void *data) +{ + struct vfile_priv *priv = xnvfile_iterator_priv(it); + struct vfile_data *p = data; + + if (p == NULL) { /* Dump header. */ + if (it->nrdata == 0) + /* Idle/posted semaphore -- just dump count. */ + xnvfile_printf(it, "=%lu\n", priv->count); + } 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 = &__native_ptree, +static struct xnvfile_snapshot_ops vfile_ops = { + .rewind = vfile_rewind, + .next = vfile_next, + .show = vfile_show, }; -#else /* !CONFIG_PROC_FS */ +extern struct xnptree __native_ptree; + +static struct xnpnode_file __sem_pnode = { + .node = { + .dirname = "semaphores", + .root = &__native_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 */ @@ -204,7 +238,7 @@ int rt_sem_create(RT_SEM *sem, const char *name, unsigned long icount, int mode) */ if (name) { err = xnregistry_enter(sem->name, sem, &sem->handle, - &__sem_pnode); + &__sem_pnode.node); if (err) rt_sem_delete(sem); } _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git