Module: xenomai-3
Branch: wip/dovetail
Commit: 9d5c34dbc526f79352dce2c3893b88657a3d3c4f
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=9d5c34dbc526f79352dce2c3893b88657a3d3c4f

Author: Philippe Gerum <r...@xenomai.org>
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 857496b..a6ca477 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, &param_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, &param_ex));
 out:
        CANCEL_RESTORE(svc);
 


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to