void __wind_wd_handler(void *cookie) { wind_wd_t *wd = (wind_wd_t *)cookie; if (wd->plink.last == wd->plink.next) { /* Not linked? */ appendq(&wd->rh->wdpending, &wd->plink); if (countq(&wd->rh->wdpending) == 1) xnsynch_flush(&wd->rh->wdsynch, 0); } }
int xnpipe_flush(int minor, int mode) { struct xnpipe_state *state; int msgcount; spl_t s; if (minor < 0 || minor >= XNPIPE_NDEVS) return -ENODEV; state = &xnpipe_states[minor]; xnlock_get_irqsave(&nklock, s); if (!testbits(state->status, XNPIPE_KERN_CONN)) { xnlock_put_irqrestore(&nklock, s); return -EBADF; } msgcount = countq(&state->outq) + countq(&state->inq); if (mode & XNPIPE_OFLUSH) state->ionrd -= xnpipe_flushq(state, outq, free_obuf, s); if (mode & XNPIPE_IFLUSH) xnpipe_flushq(state, inq, free_ibuf, s); if (testbits(state->status, XNPIPE_USER_WSYNC) && msgcount > countq(&state->outq) + countq(&state->inq)) { __setbits(state->status, XNPIPE_USER_WSYNC_READY); xnpipe_schedule_request(); } xnlock_put_irqrestore(&nklock, s); return 0; }
static int vfile_rewind(struct xnvfile_snapshot_iterator *it) { struct vfile_priv *priv = xnvfile_iterator_priv(it); wind_msgq_t *q = xnvfile_priv(it->vfile); q = wind_h2obj_active((MSG_Q_ID)q, WIND_MSGQ_MAGIC, wind_msgq_t); if (q == NULL) return -EIDRM; priv->curr = getheadpq(xnsynch_wait_queue(&q->synchbase)); priv->flags = xnsynch_test_flags(&q->synchbase, XNSYNCH_PRIO); priv->mlength = q->msg_length; priv->mcount = countq(&q->msgq); return xnsynch_nsleepers(&q->synchbase); }
static int msgq_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { wind_msgq_t *queue = (wind_msgq_t *)data; char *p = page; int len; spl_t s; p += sprintf(p, "porder=%s:mlength=%u:mcount=%d\n", xnsynch_test_flags(&queue->synchbase, XNSYNCH_PRIO) ? "prio" : "fifo", queue->msg_length, countq(&queue->msgq)); xnlock_get_irqsave(&nklock, s); if (xnsynch_nsleepers(&queue->synchbase) > 0) { xnpholder_t *holder; /* Pended queue -- dump waiters. */ holder = getheadpq(xnsynch_wait_queue(&queue->synchbase)); while (holder) { xnthread_t *sleeper = link2thread(holder, plink); p += sprintf(p, "+%s\n", xnthread_name(sleeper)); holder = nextpq(xnsynch_wait_queue(&queue->synchbase), holder); } } 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; return len; }
static ssize_t xnpipe_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { struct xnpipe_state *state = file->private_data; struct xnpipe_mh *mh; int pollnum, ret; spl_t s; if (count == 0) return 0; if (!access_ok(VERIFY_READ, buf, count)) return -EFAULT; xnlock_get_irqsave(&nklock, s); retry: if (!testbits(state->status, XNPIPE_KERN_CONN)) { xnlock_put_irqrestore(&nklock, s); return -EPIPE; } pollnum = countq(&state->inq) + countq(&state->outq); xnlock_put_irqrestore(&nklock, s); mh = state->ops.alloc_ibuf(count + sizeof(*mh), state->xstate); if (mh == (struct xnpipe_mh *)-1) return -ENOMEM; if (mh == NULL) { if (file->f_flags & O_NONBLOCK) return -EWOULDBLOCK; xnlock_get_irqsave(&nklock, s); if (xnpipe_wait(state, XNPIPE_USER_WSYNC, s, pollnum > countq(&state->inq) + countq(&state->outq))) { xnlock_put_irqrestore(&nklock, s); return -ERESTARTSYS; } goto retry; } inith(xnpipe_m_link(mh)); xnpipe_m_size(mh) = count; xnpipe_m_rdoff(mh) = 0; if (copy_from_user(xnpipe_m_data(mh), buf, count)) { state->ops.free_ibuf(mh, state->xstate); return -EFAULT; } xnlock_get_irqsave(&nklock, s); appendq(&state->inq, &mh->link); /* Wake up a Xenomai sleeper if any. */ if (xnsynch_wakeup_one_sleeper(&state->synchbase)) xnpod_schedule(); if (state->ops.input) { ret = state->ops.input(mh, 0, state->xstate); if (ret) count = (size_t)ret; } if (file->f_flags & O_SYNC) { if (!emptyq_p(&state->inq)) { if (xnpipe_wait(state, XNPIPE_USER_WSYNC, s, emptyq_p(&state->inq))) count = -ERESTARTSYS; } } xnlock_put_irqrestore(&nklock, s); return (ssize_t)count; }