static int __wind_task_priorityget(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); WIND_TCB *pTcb; int prio; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(prio))) return -EFAULT; if (handle) pTcb = (WIND_TCB *)xnregistry_fetch(handle); else pTcb = __wind_task_current(curr); if (!pTcb) return S_objLib_OBJ_ID_ERROR; if (taskPriorityGet((TASK_ID) pTcb, &prio) == ERROR) return wind_errnoget(); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &prio, sizeof(prio)); return 0; }
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; }
static int __wind_task_self(struct pt_regs *regs) { WIND_TCB_PLACEHOLDER ph; WIND_TCB *pTcb; pTcb = __wind_task_current(current); if (!pTcb) /* Calls on behalf of a non-task context beget an error for the user-space interface. */ return S_objLib_OBJ_ID_ERROR; ph.handle = xnthread_handle(&pTcb->threadbase); /* Copy back the task handle. */ return __xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &ph, sizeof(ph)); }
static int __wind_task_suspend(struct task_struct *curr, struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); WIND_TCB *pTcb; if (handle) pTcb = (WIND_TCB *)xnregistry_fetch(handle); else pTcb = __wind_task_current(curr); if (!pTcb) return S_objLib_OBJ_ID_ERROR; if (taskSuspend((TASK_ID) pTcb) == ERROR) return wind_errnoget(); return 0; }
static int __wind_task_delete(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); WIND_TCB *pTcb; if (handle) pTcb = __wind_lookup_task(handle); else pTcb = __wind_task_current(current); if (!pTcb) return S_objLib_OBJ_ID_ERROR; if (taskDelete((TASK_ID) pTcb) == ERROR) return wind_errnoget(); return 0; }
static int __wind_task_priorityget(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); WIND_TCB *pTcb; int prio; if (handle) pTcb = __wind_lookup_task(handle); else pTcb = __wind_task_current(current); if (!pTcb) return S_objLib_OBJ_ID_ERROR; if (taskPriorityGet((TASK_ID) pTcb, &prio) == ERROR) return wind_errnoget(); return __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), &prio, sizeof(prio)); }
static int __wind_task_self(struct task_struct *curr, struct pt_regs *regs) { WIND_TCB_PLACEHOLDER ph; WIND_TCB *pTcb; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg1(regs), sizeof(ph))) return -EFAULT; pTcb = __wind_task_current(curr); if (!pTcb) /* Calls on behalf of a non-task context beget an error for the user-space interface. */ return S_objLib_OBJ_ID_ERROR; ph.handle = xnthread_handle(&pTcb->threadbase); /* Copy back the task handle. */ __xn_copy_to_user(curr, (void __user *)__xn_reg_arg1(regs), &ph, sizeof(ph)); return 0; }
static int __wind_int_context(struct task_struct *curr, struct pt_regs *regs) { WIND_TCB *pTcb = __wind_task_current(curr); return pTcb && xnthread_base_priority(&pTcb->threadbase) == XNCORE_IRQ_PRIO; }