Esempio n. 1
0
int rt_task_init(RT_TASK *task,
		 void (*body) (int),
		 int cookie,
		 int stack_size,
		 int priority, int uses_fpu, void (*sigfn) (void))
{
	union xnsched_policy_param param;
	struct xnthread_start_attr sattr;
	struct xnthread_init_attr iattr;
	xnflags_t bflags = 0;
	int ret;
	spl_t s;

	if (priority < XNSCHED_LOW_PRIO ||
	    priority > XNSCHED_HIGH_PRIO || task->magic == RTAI_TASK_MAGIC)
		return -EINVAL;

	priority = XNSCHED_HIGH_PRIO - priority + 1;	/* Normalize. */

	if (uses_fpu)
#ifdef CONFIG_XENO_HW_FPU
		bflags |= XNFPU;
#else /* !CONFIG_XENO_HW_FPU */
		return -EINVAL;
#endif /* CONFIG_XENO_HW_FPU */

	iattr.tbase = rtai_tbase;
	iattr.name = NULL;
	iattr.flags = bflags;
	iattr.ops = &__rtai_task_ops;
	iattr.stacksize = stack_size;
	param.rt.prio = priority;

	if (xnpod_init_thread(&task->thread_base,
			      &iattr, &xnsched_class_rt, &param) != 0)
		/* Assume this is the only possible failure. */
		return -ENOMEM;

	xnarch_cpus_clear(task->affinity);
	inith(&task->link);
	task->suspend_depth = 1;
	task->cookie = cookie;
	task->body = body;
	task->sigfn = sigfn;

	if (xnarch_cpus_empty(task->affinity))
		task->affinity = XNPOD_ALL_CPUS;

	xnlock_get_irqsave(&nklock, s);

	sattr.mode = XNSUSP;	/* Suspend on startup. */
	sattr.imask = 0;
	sattr.affinity = task->affinity;
	sattr.entry = rt_task_trampoline;
	sattr.cookie = task;
	ret = xnpod_start_thread(&task->thread_base, &sattr);
	if (ret)
		goto unlock_and_exit;

	task->magic = RTAI_TASK_MAGIC;
	appendq(&__rtai_task_q, &task->link);

#ifdef CONFIG_XENO_FASTSYNCH
	/* We need an anonymous registry entry to obtain a handle for fast
	   mutex locking. */
	ret = xnthread_register(&task->thread_base, "");
	if (ret) {
		xnpod_abort_thread(&task->thread_base);
		goto unlock_and_exit;
	}
#endif /* CONFIG_XENO_FASTSYNCH */

	/* Add a switch hook only if a signal function has been declared
	   at least once for some created task. */

	if (sigfn != NULL && __rtai_task_sig++ == 0)
		xnpod_add_hook(XNHOOK_THREAD_SWITCH, &__task_switch_hook);

      unlock_and_exit:

	xnlock_put_irqrestore(&nklock, s);

	return ret ? -EINVAL : 0;
}
Esempio n. 2
0
u_long t_create(const char *name,
		u_long prio,
		u_long sstack, u_long ustack, u_long flags, u_long *tid_r)
{
	union xnsched_policy_param param;
	struct xnthread_init_attr attr;
	xnflags_t bflags = 0;
	psostask_t *task;
	u_long err;
	spl_t s;
	int n;

	/* Xenomai extension: we accept priority level #0 for creating
	   non-RT tasks (i.e. underlaid by SCHED_NORMAL pthreads),
	   which are allowed to call into the pSOS emulator, usually
	   for synchronization services. */

	if (prio > 255)
		return ERR_PRIOR;

	task = (psostask_t *)xnmalloc(sizeof(*task));

	if (!task)
		return ERR_NOTCB;

	if (flags & T_FPU)
		bflags |= XNFPU;

#ifdef CONFIG_XENO_OPT_PERVASIVE
	if (flags & T_SHADOW)
		bflags |= XNSHADOW;
#endif /* CONFIG_XENO_OPT_PERVASIVE */

	ustack += sstack;

	if (!(flags & T_SHADOW) && ustack < 1024) {
		xnfree(task);
		return ERR_TINYSTK;
	}

	if (name && *name)
		xnobject_copy_name(task->name, name);
	else
		/* i.e. Anonymous object which must be accessible from
		   user-space. */
		sprintf(task->name, "anon_task%lu", psos_task_ids++);

	attr.tbase = psos_tbase;
	attr.name = task->name;
	attr.flags = bflags;
	attr.ops = &psos_task_ops;
	attr.stacksize = ustack;
	param.rt.prio = prio;

	if (xnpod_init_thread(&task->threadbase,
			      &attr, &xnsched_class_rt, &param) != 0) {
		xnfree(task);
		return ERR_NOSTK;	/* Assume this is the only possible failure */
	}

	xnthread_time_slice(&task->threadbase) = psos_time_slice;

	taskev_init(&task->evgroup);
	inith(&task->link);

	for (n = 0; n < PSOSTASK_NOTEPAD_REGS; n++)
		task->notepad[n] = 0;

	initgq(&task->alarmq,
	       &xnmod_glink_queue,
	       xnmod_alloc_glinks,
	       XNMOD_GHOLDER_THRESHOLD);

	task->magic = PSOS_TASK_MAGIC;

	xnlock_get_irqsave(&nklock, s);
	appendq(&psostaskq, &task->link);
	*tid_r = (u_long)task;
	xnlock_put_irqrestore(&nklock, s);

	err = xnthread_register(&task->threadbase, task->name);
	if (err) {
		t_delete((u_long)task);
		return err;
	}

	xnarch_create_display(&task->threadbase, task->name, psostask);

	return SUCCESS;
}