Esempio n. 1
0
u_long t_getreg(u_long tid, u_long regnum, u_long *regvalue)
{
	u_long err = SUCCESS;
	psostask_t *task;
	spl_t s;

	xnlock_get_irqsave(&nklock, s);

	if (tid == 0)
		task = psos_current_task();
	else {
		task = psos_h2obj_active(tid, PSOS_TASK_MAGIC, psostask_t);

		if (!task) {
			err = psos_handle_error(tid, PSOS_TASK_MAGIC, psostask_t);
			goto unlock_and_exit;
		}
	}

	if (regnum >= PSOSTASK_NOTEPAD_REGS) {
		err = ERR_REGNUM;
		goto unlock_and_exit;
	}

	*regvalue = task->notepad[regnum];

unlock_and_exit:

	xnlock_put_irqrestore(&nklock, s);

	return err;
}
Esempio n. 2
0
u_long t_delete(u_long tid)
{
	u_long err = SUCCESS;
	psostask_t *task;
	spl_t s;

	if (tid == 0)
		xnpod_delete_self();	/* Never returns */

	xnlock_get_irqsave(&nklock, s);

	task = psos_h2obj_active(tid, PSOS_TASK_MAGIC, psostask_t);

	if (!task) {
		err = psos_handle_error(tid, PSOS_TASK_MAGIC, psostask_t);
		goto unlock_and_exit;
	}

	xnpod_delete_thread(&task->threadbase);

unlock_and_exit:

	xnlock_put_irqrestore(&nklock, s);

	return err;
}
Esempio n. 3
0
u_long t_setpri(u_long tid, u_long newprio, u_long *oldprio)
{
	union xnsched_policy_param param;
	u_long err = SUCCESS;
	psostask_t *task;
	spl_t s;

	xnlock_get_irqsave(&nklock, s);

	if (tid == 0) {
		if (xnpod_unblockable_p())
			return -EPERM;
		task = psos_current_task();
	}
	else {
		task = psos_h2obj_active(tid, PSOS_TASK_MAGIC, psostask_t);

		if (!task) {
			err =
				psos_handle_error(tid, PSOS_TASK_MAGIC, psostask_t);
			goto unlock_and_exit;
		}
	}

	*oldprio = xnthread_current_priority(&task->threadbase);

	if (newprio != 0) {
		if (newprio < 1 || newprio > 255) {
			err = ERR_SETPRI;
			goto unlock_and_exit;
		}

		if (newprio != *oldprio) {
			param.rt.prio = newprio;
			xnpod_set_thread_schedparam(&task->threadbase,
						    &xnsched_class_rt, &param);
			xnpod_schedule();
		}
	}

unlock_and_exit:

	xnlock_put_irqrestore(&nklock, s);

	return err;
}
Esempio n. 4
0
u_long t_start(u_long tid,
	       u_long mode,
	       void (*startaddr) (u_long, u_long, u_long, u_long),
	       u_long targs[])
{
	u_long err = SUCCESS;
	xnflags_t xnmode;
	psostask_t *task;
	spl_t s;
	int n;

	/* We have no error case here: just clear out any unwanted bit. */
	mode &= ~T_START_MASK;

	xnlock_get_irqsave(&nklock, s);

	task = psos_h2obj_active(tid, PSOS_TASK_MAGIC, psostask_t);

	if (!task) {
		err = psos_handle_error(tid, PSOS_TASK_MAGIC, psostask_t);
		goto unlock_and_exit;
	}

	if (!xnthread_test_state(&task->threadbase, XNDORMANT)) {
		err = ERR_ACTIVE;	/* Task already started */
		goto unlock_and_exit;
	}

	xnmode = psos_mode_to_xeno(mode);

	task->entry = startaddr;

#ifdef CONFIG_XENO_OPT_PERVASIVE
	if (xnthread_test_state(&task->threadbase, XNSHADOW)) {
		memset(task->args, 0, sizeof(task->args));
		/* The shadow will be returned the exact values passed
		 * to t_start(), since the trampoline is performed at
		 * user-space level. We just relay the information
		 * from t_create() to t_start() here.*/
		xnpod_start_thread(&task->threadbase,
				   xnmode,
				   (int)((mode >> 8) & 0x7),
				   XNPOD_ALL_CPUS, (void (*)(void *))startaddr, targs);
	}
Esempio n. 5
0
u_long t_suspend(u_long tid)
{
	u_long err = SUCCESS;
	psostask_t *task;
	spl_t s;

	if (tid == 0) {
		if (xnpod_unblockable_p())
			return -EPERM;

		xnpod_suspend_self();

		if (xnthread_test_info(&psos_current_task()->threadbase, XNBREAK))
			return -EINTR;

		return SUCCESS;
	}

	xnlock_get_irqsave(&nklock, s);

	task = psos_h2obj_active(tid, PSOS_TASK_MAGIC, psostask_t);

	if (!task) {
		err = psos_handle_error(tid, PSOS_TASK_MAGIC, psostask_t);
		goto unlock_and_exit;
	}

	if (xnthread_test_state(&task->threadbase, XNSUSP)) {
		err = ERR_SUSP;	/* Task already suspended. */
		goto unlock_and_exit;
	}

	xnpod_suspend_thread(&task->threadbase, XNSUSP, XN_INFINITE, XN_RELATIVE, NULL);

	if (xnthread_test_info(&task->threadbase, XNBREAK))
		err = -EINTR;

unlock_and_exit:

	xnlock_put_irqrestore(&nklock, s);

	return err;
}
Esempio n. 6
0
u_long t_resume(u_long tid)
{
	u_long err = SUCCESS;
	psostask_t *task;
	spl_t s;

	xnlock_get_irqsave(&nklock, s);

	if (tid == 0) {
		if (xnpod_unblockable_p()) {
			err = -EPERM;
			goto unlock_and_exit;
		}

		/* Would be admittedly silly, but silly code does
		 * exist, and it's a matter of returning ERR_NOTSUSP
		 * instead of ERR_OBJID. */
		task = psos_current_task();
	}
	else {
		task = psos_h2obj_active(tid, PSOS_TASK_MAGIC, psostask_t);

		if (!task) {
			err = psos_handle_error(tid, PSOS_TASK_MAGIC, psostask_t);
			goto unlock_and_exit;
		}
	}

	if (!xnthread_test_state(&task->threadbase, XNSUSP)) {
		err = ERR_NOTSUSP;	/* Task not suspended. */
		goto unlock_and_exit;
	}

	xnpod_resume_thread(&task->threadbase, XNSUSP);
	xnpod_schedule();

unlock_and_exit:

	xnlock_put_irqrestore(&nklock, s);

	return err;
}
Esempio n. 7
0
u_long ev_send(u_long tid, u_long events)
{
	u_long err = SUCCESS;
	psosevent_t *evgroup;
	psostask_t *task;
	spl_t s;

	xnlock_get_irqsave(&nklock, s);

	task = psos_h2obj_active(tid, PSOS_TASK_MAGIC, psostask_t);

	if (!task) {
		err = psos_handle_error(tid, PSOS_TASK_MAGIC, psostask_t);
		goto unlock_and_exit;
	}

	evgroup = &task->evgroup;
	evgroup->events |= events;

	/* Only the task to which the event group pertains can
	   pend on it. */

	if (!emptypq_p(xnsynch_wait_queue(&evgroup->synchbase))) {
		u_long flags = task->waitargs.evgroup.flags;
		u_long bits = task->waitargs.evgroup.events;

		if (((flags & EV_ANY) && (bits & evgroup->events) != 0) ||
		    (!(flags & EV_ANY) && ((bits & evgroup->events) == bits))) {
			xnsynch_wakeup_one_sleeper(&evgroup->synchbase);
			task->waitargs.evgroup.events =
			    (bits & evgroup->events);
			evgroup->events &= ~bits;
			xnpod_schedule();
		}
	}

      unlock_and_exit:

	xnlock_put_irqrestore(&nklock, s);

	return err;
}
Esempio n. 8
0
u_long t_restart(u_long tid, u_long targs[])
{
	u_long err = SUCCESS;
	psostask_t *task;
	spl_t s;
	int n;

	if (xnpod_unblockable_p())
		return -EPERM;

	xnlock_get_irqsave(&nklock, s);

	if (tid == 0)
		task = psos_current_task();
	else {
		task = psos_h2obj_active(tid, PSOS_TASK_MAGIC, psostask_t);

		if (!task) {
			err = psos_handle_error(tid, PSOS_TASK_MAGIC, psostask_t);
			goto unlock_and_exit;
		}

		if (xnthread_test_state(&task->threadbase, XNDORMANT)) {
			err = ERR_NACTIVE;
			goto unlock_and_exit;
		}
	}

	for (n = 0; n < 4; n++)
		task->args[n] = targs ? targs[n] : 0;

	xnpod_restart_thread(&task->threadbase);

unlock_and_exit:

	xnlock_put_irqrestore(&nklock, s);

	return err;
}
Esempio n. 9
0
u_long t_start(u_long tid,
	       u_long mode,
	       void (*startaddr) (u_long, u_long, u_long, u_long),
	       u_long targs[])
{
	struct xnthread_start_attr attr;
	u_long err = SUCCESS;
	xnflags_t xnmode;
	psostask_t *task;
	spl_t s;

	/* We have no error case here: just clear out any unwanted bit. */
	mode &= ~T_START_MASK;

	xnlock_get_irqsave(&nklock, s);

	task = psos_h2obj_active(tid, PSOS_TASK_MAGIC, psostask_t);

	if (!task) {
		err = psos_handle_error(tid, PSOS_TASK_MAGIC, psostask_t);
		goto unlock_and_exit;
	}

	if (!xnthread_test_state(&task->threadbase, XNDORMANT)) {
		err = ERR_ACTIVE;	/* Task already started */
		goto unlock_and_exit;
	}

	xnmode = psos_mode_to_xeno(mode);
	if (xnmode & XNRRB) {
		xnpod_set_thread_tslice(&task->threadbase, psos_time_slice);
		xnmode &= ~XNRRB;
	}

	task->entry = startaddr;

	attr.mode = xnmode;
	attr.imask = (int)((mode >> 8) & 0x7);
	attr.affinity = XNPOD_ALL_CPUS;

	if (targs)
		memcpy(task->args, targs, sizeof(task->args));
	else
		memset(task->args, 0, sizeof(task->args));

#ifdef CONFIG_XENO_OPT_PERVASIVE
	if (xnthread_test_state(&task->threadbase, XNSHADOW)) {
		attr.entry = (void (*)(void *))startaddr;
		attr.cookie = (void *)xnthread_handle(&task->threadbase);
	} else
#endif /* CONFIG_XENO_OPT_PERVASIVE */
	{
		attr.entry = psostask_trampoline;
		attr.cookie = task;
	}

	xnpod_start_thread(&task->threadbase, &attr);

unlock_and_exit:

	xnlock_put_irqrestore(&nklock, s);

	return err;
}