Module: xenomai-forge
Branch: next
Commit: 58176a2862a0ab6292df3ad28fba8d0b84e93882
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=58176a2862a0ab6292df3ad28fba8d0b84e93882

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sun May  5 16:55:13 2013 +0200

lib/alchemy: provide rt_task_join()

---

 include/alchemy/task.h |    3 ++
 lib/alchemy/task.c     |   62 ++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/include/alchemy/task.h b/include/alchemy/task.h
index 0dd7d22..88162f1 100644
--- a/include/alchemy/task.h
+++ b/include/alchemy/task.h
@@ -43,6 +43,7 @@
 
 struct RT_TASK {
        uintptr_t handle;
+       pthread_t thread;
 };
 
 typedef struct RT_TASK RT_TASK;
@@ -111,6 +112,8 @@ int rt_task_shadow(RT_TASK *task,
                   int prio,
                   int mode);
 
+int rt_task_join(RT_TASK *task);
+
 int rt_task_set_periodic(RT_TASK *task,
                         RTIME idate, RTIME period);
 
diff --git a/lib/alchemy/task.c b/lib/alchemy/task.c
index 8664efa..2f95d1a 100644
--- a/lib/alchemy/task.c
+++ b/lib/alchemy/task.c
@@ -369,6 +369,8 @@ int rt_task_create(RT_TASK *task, const char *name,
                                             &tcb->thobj.tid));
        if (ret)
                delete_tcb(tcb);
+       else
+               task->thread = tcb->thobj.tid;
 out:
        COPPERPLATE_UNPROTECT(svc);
 
@@ -402,9 +404,6 @@ out:
  *
  * - Regular POSIX threads
  * - Xenomai threads
- *
- * @note rt_task_delete() may block until the deleted task exits a
- * safe section, previously entered by a call to rt_task_safe().
  */
 int rt_task_delete(RT_TASK *task)
 {
@@ -428,7 +427,8 @@ int rt_task_delete(RT_TASK *task)
        threadobj_lock(&tcb->thobj);
        /*
         * Prevent further reference to this zombie, including via
-        * alchemy_task_current().
+        * alchemy_task_current(). Only rt_task_join() will be able to
+        * find it.
         */
        threadobj_set_magic(&tcb->thobj, ~task_magic);
        threadobj_unlock(&tcb->thobj);
@@ -463,6 +463,53 @@ out:
 }
 
 /**
+ * @fn int rt_task_join(RT_TASK *task)
+ * @brief Wait on the termination of a real-time task.
+ *
+ * This service blocks the caller in non-real-time context until @a
+ * task has terminated. All resources are released after successful
+ * completion of this service.
+ *
+ * The specified task must have been created by the same process that
+ * wants to join it, and the T_JOINABLE mode flag must have been set
+ * on creation to rt_task_create().
+ *
+ * Tasks created with the T_JOINABLE flag shall be joined by a
+ * subsequent call to rt_task_join() once successfully deleted, to
+ * reclaim all resources.
+ *
+ * @param task The descriptor address of the task to join.
+ *
+ * @return Zero is returned upon success. Otherwise:
+ *
+ * - -EINVAL is returned if @a task is not a valid task descriptor.
+ *
+ * - -EINVAL is returned if the task was not created with T_JOINABLE
+ * set or some other task is already waiting on the termination.
+ *
+ * - -EDEADLK is returned if @a task refers to the caller.
+ *
+ * - -ESRCH is returned if @a task no longer exists or refers to task
+ * created by a different process.
+ *
+ * Valid calling context:
+ *
+ * - Regular POSIX threads
+ * - Xenomai threads
+ *
+ * @note After successful completion of this service, it is neither
+ * required nor valid to additionally invoke rt_task_delete() on the
+ * same task.
+ */
+int rt_task_join(RT_TASK *task)
+{
+       if (bad_pointer(task))
+               return -EINVAL;
+
+       return -pthread_join(task->thread, NULL);
+}
+
+/**
  * @fn int rt_task_set_affinity(RT_TASK *task, const cpu_set_t *cpus)
  * @brief Set CPU affinity of real-time task.
  *
@@ -635,6 +682,7 @@ int rt_task_shadow(RT_TASK *task, const char *name, int 
prio, int mode)
        struct threadobj *current = threadobj_current();
        struct alchemy_task *tcb;
        struct service svc;
+       pthread_t self;
        int ret;
 
        COPPERPLATE_PROTECT(svc);
@@ -661,7 +709,11 @@ int rt_task_shadow(RT_TASK *task, const char *name, int 
prio, int mode)
                goto out;
        }
 
-       ret = __bt(copperplate_renice_thread(pthread_self(), prio));
+       self = pthread_self();
+       if (task)
+               task->thread = self;
+
+       ret = __bt(copperplate_renice_thread(self, prio));
 out:
        COPPERPLATE_UNPROTECT(svc);
 


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

Reply via email to