Module: xenomai-3 Branch: stable-3.0.x Commit: eacdc5df1fbf8be7585c935009b3fa5b5f90805e URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=eacdc5df1fbf8be7585c935009b3fa5b5f90805e
Author: Philippe Gerum <[email protected]> Date: Thu Apr 21 10:01:56 2016 +0200 alchemy/task: allow calling rt_task_shadow() from a plain POSIX thread The inline documentation was misleading, rt_task_shadow() could not be called from regular pthreads until this change, but only from Xenomai threads (i.e. mode-unrestricted vs thread-unrestricted). --- lib/alchemy/task.c | 59 +++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/lib/alchemy/task.c b/lib/alchemy/task.c index b04b356..045500f 100644 --- a/lib/alchemy/task.c +++ b/lib/alchemy/task.c @@ -326,12 +326,12 @@ fail_syncinit: /** * @fn int rt_task_create(RT_TASK *task, const char *name, int stksize, int prio, int mode) - * @brief Create a real-time task. + * @brief Create a task with Alchemy personality. * - * This service creates a task with access to the full set of Xenomai - * real-time services. If @a prio is non-zero, the new task belongs to - * Xenomai's real-time FIFO scheduling class, aka SCHED_FIFO. If @a - * prio is zero, the task belongs to the regular SCHED_OTHER class. + * This service creates a task with access to the full set of Alchemy + * services. If @a prio is non-zero, the new task belongs to Xenomai's + * real-time FIFO scheduling class, aka SCHED_FIFO. If @a prio is + * zero, the task belongs to the regular SCHED_OTHER class. * * Creating tasks with zero priority is useful for running non * real-time processes which may invoke blocking real-time services, @@ -650,10 +650,9 @@ out: * @fn int rt_task_shadow(RT_TASK *task, const char *name, int prio, int mode) * @brief Turn caller into a real-time task. * - * Extends the calling Linux task with Xenomai capabilities, with - * access to the full set of Xenomai real-time services. This service - * is typically used for turning the main() thread of an application - * process into a Xenomai-enabled task. + * Set the calling thread personality to the Alchemy API, enabling the + * full set of Alchemy services. Upon success, the caller is no more a + * regular POSIX thread, but a Xenomai-extended thread. * * If @a prio is non-zero, the new task moves to Xenomai's real-time * FIFO scheduling class, aka SCHED_FIFO. If @a prio is zero, the task @@ -664,9 +663,6 @@ out: * such as pending on a semaphore, reading from a message queue or a * buffer, and so on. * - * Once shadowed with the Xenomai extension, the calling task returns - * and resumes execution normally from the call site. - * * @param task If non-NULL, the address of a task descriptor which can * be later used to identify uniquely the task, upon success of this * call. If NULL, no descriptor is returned. @@ -702,16 +698,14 @@ out: * - -EEXIST is returned if the @a name is conflicting with an already * registered task. * - * - -EBUSY is returned if the caller is already mapped to a Xenomai - * task context. - * - * - -EPERM is returned if this service was called from an invalid - * context. + * - -EBUSY is returned if the caller is not a regular POSIX thread. * - * @apitags{pthread-only, switch-secondary} + * @apitags{pthread-only, switch-secondary, switch-primary} * - * @sideeffect Over the Cobalt core, the caller always returns from - * this service in primary mode. + * @sideeffect Over Cobalt, if the caller is a plain POSIX thread, it + * is turned into a Xenomai _shadow_ thread, with full access to all + * Cobalt services. The caller always returns from this service in + * primary mode. * * @note Tasks can be referred to from multiple processes which all * belong to the same Xenomai session. @@ -739,12 +733,29 @@ int rt_task_shadow(RT_TASK *task, const char *name, int prio, int mode) if (current && threadobj_get_magic(current)) return -EBUSY; + /* + * Over Cobalt, the following call turns the current context + * into a dual-kernel thread. Do this early, since this will + * be required next for creating the TCB and running the + * prologue code (i.e. real-time mutexes and monitors are + * locked there). + */ + self = pthread_self(); + policy = prio ? SCHED_FIFO : SCHED_OTHER; + param_ex.sched_priority = prio; + ret = __bt(copperplate_renice_local_thread(self, policy, ¶m_ex)); + if (ret) + goto out; + ret = create_tcb(&tcb, task, name, prio, mode); if (ret) goto out; CANCEL_RESTORE(svc); + if (task) + task->thread = self; + ret = threadobj_shadow(&tcb->thobj, tcb->name); if (ret) goto undo; @@ -754,14 +765,6 @@ int rt_task_shadow(RT_TASK *task, const char *name, int prio, int mode) ret = task_prologue_2(tcb); if (ret) goto undo; - - self = pthread_self(); - if (task) - task->thread = self; - - policy = prio ? SCHED_FIFO : SCHED_OTHER; - param_ex.sched_priority = prio; - ret = __bt(copperplate_renice_local_thread(self, policy, ¶m_ex)); out: CANCEL_RESTORE(svc); _______________________________________________ Xenomai-git mailing list [email protected] https://xenomai.org/mailman/listinfo/xenomai-git
