static int __wind_wd_wait(struct task_struct *curr, struct pt_regs *regs) { xnholder_t *holder; wind_rholder_t *rh; WIND_TCB *pTcb; wind_wd_t *wd; int err = 0; spl_t s; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg1(regs), sizeof(wd->wdt))) return -EFAULT; rh = wind_get_rholder(); xnlock_get_irqsave(&nklock, s); pTcb = __wind_task_current(curr); if (xnthread_base_priority(&pTcb->threadbase) != XNCORE_IRQ_PRIO) /* Renice the waiter above all regular tasks if needed. */ xnpod_renice_thread(&pTcb->threadbase, XNCORE_IRQ_PRIO); if (!emptyq_p(&rh->wdpending)) goto pull_event; xnsynch_sleep_on(&rh->wdsynch, XN_INFINITE, XN_RELATIVE); if (xnthread_test_info(&pTcb->threadbase, XNBREAK)) { err = -EINTR; /* Unblocked. */ goto unlock_and_exit; } if (xnthread_test_info(&pTcb->threadbase, XNRMID)) { err = -EIDRM; /* Watchdog deleted while pending. */ goto unlock_and_exit; } pull_event: holder = getq(&rh->wdpending); if (holder) { wd = link2wind_wd(holder); /* We need the following to mark the watchdog as unqueued. */ inith(holder); xnlock_put_irqrestore(&nklock, s); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg1(regs), &wd->wdt, sizeof(wd->wdt)); return 0; } unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }
static int __wind_wd_wait(struct pt_regs *regs) { union xnsched_policy_param param; xnholder_t *holder; wind_rholder_t *rh; WIND_TCB *pTcb; wind_wd_t *wd; int err = 0; spl_t s; rh = wind_get_rholder(); xnlock_get_irqsave(&nklock, s); pTcb = __wind_task_current(current); if (xnthread_base_priority(&pTcb->threadbase) != XNSCHED_IRQ_PRIO) { /* Boost the waiter above all regular tasks if needed. */ param.rt.prio = XNSCHED_IRQ_PRIO; xnpod_set_thread_schedparam(&pTcb->threadbase, &xnsched_class_rt, ¶m); } if (!emptyq_p(&rh->wdpending)) goto pull_event; xnsynch_sleep_on(&rh->wdsynch, XN_INFINITE, XN_RELATIVE); if (xnthread_test_info(&pTcb->threadbase, XNBREAK)) { err = -EINTR; /* Unblocked. */ goto unlock_and_exit; } if (xnthread_test_info(&pTcb->threadbase, XNRMID)) { err = -EIDRM; /* Watchdog deleted while pending. */ goto unlock_and_exit; } pull_event: holder = getq(&rh->wdpending); if (holder) { wd = link2wind_wd(holder); /* We need the following to mark the watchdog as unqueued. */ inith(holder); xnlock_put_irqrestore(&nklock, s); return __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &wd->wdt, sizeof(wd->wdt)); } unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }