Example #1
0
static int rtswitch_create_ktask(rtswitch_context_t *ctx,
                                 struct rttst_swtest_task *ptask)
{
	rtswitch_task_t *task;
	xnflags_t init_flags;
	struct taskarg arg;
	char name[30];
	int err;

	ptask->flags |= RTSWITCH_KERNEL;
	err = rtswitch_register_task(ctx, ptask);

	if (err)
		return err;

	snprintf(name, sizeof(name), "rtk%d/%u", ptask->index, ctx->cpu);

	task = &ctx->tasks[ptask->index];

	arg.ctx = ctx;
	arg.task = task;

	init_flags = (ptask->flags & RTTST_SWTEST_FPU) ? XNFPU : 0;

	/* Migrate the calling thread to the same CPU as the created task, in
	   order to be sure that the created task is suspended when this function
	   returns. This also allow us to use the stack to pass the parameters to
	   the created task. */
	set_cpus_allowed(current, cpumask_of_cpu(ctx->cpu));

	err = xnpod_init_thread(&task->ktask, rtdm_tbase, name, 1, init_flags, 0, NULL);

	if (!err)
		err = xnpod_start_thread(&task->ktask,
					 0,
					 0,
					 xnarch_cpumask_of_cpu(ctx->cpu),
					 rtswitch_ktask,
					 &arg);
	else
		/* In order to avoid calling xnpod_delete_thread with invalid
		   thread. */
		task->base.flags = 0;

	/* Putting the argument on stack is safe, because the new thread will
	   preempt the current thread immediately, and will suspend only once the
	   arguments on stack are used. */

	return err;
}
Example #2
0
static inline void xntimer_next_remote_shot(xnsched_t *sched)
{
	xnarch_send_timer_ipi(xnarch_cpumask_of_cpu(xnsched_cpu(sched)));
}
Example #3
0
static int rtswitch_create_ktask(rtswitch_context_t *ctx,
				 struct rttst_swtest_task *ptask)
{
	union xnsched_policy_param param;
	struct xnthread_start_attr sattr;
	struct xnthread_init_attr iattr;
	rtswitch_task_t *task;
	xnflags_t init_flags;
	struct taskarg arg;
	char name[30];
	int err;

	/*
	 * Silently disable FP tests in kernel if FPU is not supported
	 * there. Typical case is math emulation support: we can use
	 * it from userland as a synthetic FPU, but there is no sane
	 * way to use it from kernel-based threads (Xenomai or Linux).
	 */
	if (!fp_kernel_supported())
		ptask->flags &= ~RTTST_SWTEST_USE_FPU;
		
	ptask->flags |= RTSWITCH_KERNEL;
	err = rtswitch_register_task(ctx, ptask);

	if (err)
		return err;

	snprintf(name, sizeof(name), "rtk%d/%u", ptask->index, ctx->cpu);

	task = &ctx->tasks[ptask->index];

	arg.ctx = ctx;
	arg.task = task;

	init_flags = (ptask->flags & RTTST_SWTEST_FPU) ? XNFPU : 0;

	/*
	 * Migrate the calling thread to the same CPU as the created
	 * task, in order to be sure that the created task is
	 * suspended when this function returns. This also allow us to
	 * use the stack to pass the parameters to the created
	 * task.
	 */
	set_cpus_allowed(current, cpumask_of_cpu(ctx->cpu));

	iattr.tbase = rtdm_tbase;
	iattr.name = name;
	iattr.flags = init_flags;
	iattr.ops = NULL;
	iattr.stacksize = 0;
	param.rt.prio = 1;

	err = xnpod_init_thread(&task->ktask,
				&iattr, &xnsched_class_rt, &param);
	if (!err) {
		sattr.mode = 0;
		sattr.imask = 0;
		sattr.affinity = xnarch_cpumask_of_cpu(ctx->cpu);
		sattr.entry = rtswitch_ktask;
		sattr.cookie = &arg;
		err = xnpod_start_thread(&task->ktask, &sattr);
	} else
		/*
		 * In order to avoid calling xnpod_delete_thread with
		 * invalid thread.
		 */
		task->base.flags = 0;
	/*
	 * Putting the argument on stack is safe, because the new
	 * thread will preempt the current thread immediately, and
	 * will suspend only once the arguments on stack are used.
	 */

	return err;
}
Example #4
0
void xnsched_init(struct xnsched *sched, int cpu)
{
	char htimer_name[XNOBJECT_NAME_LEN];
	char root_name[XNOBJECT_NAME_LEN];
	union xnsched_policy_param param;
	struct xnthread_init_attr attr;
	struct xnsched_class *p;

	sched->cpu = cpu;

	for_each_xnsched_class(p) {
		if (p->sched_init)
			p->sched_init(sched);
	}

#ifdef CONFIG_SMP
	sprintf(htimer_name, "[host-timer/%u]", cpu);
	sprintf(root_name, "ROOT/%u", cpu);
#else
	strcpy(htimer_name, "[host-timer]");
	strcpy(root_name, "ROOT");
#endif
	sched->status = 0;
	sched->inesting = 0;
	sched->curr = &sched->rootcb;
#ifdef CONFIG_XENO_OPT_PRIOCPL
	xnlock_init(&sched->rpilock);
#endif
	/*
	 * No direct handler here since the host timer processing is
	 * postponed to xnintr_irq_handler(), as part of the interrupt
	 * exit code.
	 */
	xntimer_init(&sched->htimer, &nktbase, NULL);
	xntimer_set_priority(&sched->htimer, XNTIMER_LOPRIO);
	xntimer_set_name(&sched->htimer, htimer_name);
	xntimer_set_sched(&sched->htimer, sched);
	sched->zombie = NULL;
	xnarch_cpus_clear(sched->resched);

	attr.flags = XNROOT | XNSTARTED | XNFPU;
	attr.name = root_name;
	attr.stacksize = 0;
	attr.tbase = &nktbase;
	attr.ops = NULL;
	param.idle.prio = XNSCHED_IDLE_PRIO;

	xnthread_init(&sched->rootcb, &attr,
		      sched, &xnsched_class_idle, &param);

	sched->rootcb.affinity = xnarch_cpumask_of_cpu(cpu);
	xnstat_exectime_set_current(sched, &sched->rootcb.stat.account);
#ifdef CONFIG_XENO_HW_FPU
	sched->fpuholder = &sched->rootcb;
#endif /* CONFIG_XENO_HW_FPU */

	xnarch_init_root_tcb(xnthread_archtcb(&sched->rootcb),
			     &sched->rootcb,
			     xnthread_name(&sched->rootcb));

#ifdef CONFIG_XENO_OPT_WATCHDOG
	xntimer_init(&sched->wdtimer, &nktbase, xnsched_watchdog_handler);
	xntimer_set_name(&sched->wdtimer, "[watchdog]");
	xntimer_set_priority(&sched->wdtimer, XNTIMER_LOPRIO);
	xntimer_set_sched(&sched->wdtimer, sched);
#endif /* CONFIG_XENO_OPT_WATCHDOG */
	xntimerq_init(&sched->timerqueue);
}