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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sat May 11 18:16:12 2013 +0200

copperplate/threadobj: factor out tcb cleanup code

Perform the thread cleanup duties ourselves, directly from the
internal finalizer, after the per-skin finalizer has run.

The latter is then required to perform the needed cleanup only for
the resources it maintains.

---

 include/copperplate/threadobj.h |    5 +++--
 lib/alchemy/task.c              |    8 ++------
 lib/copperplate/threadobj.c     |   30 ++++++++++++++++--------------
 lib/psos/task.c                 |    7 ++-----
 lib/vxworks/taskLib.c           |    3 ---
 5 files changed, 23 insertions(+), 30 deletions(-)

diff --git a/include/copperplate/threadobj.h b/include/copperplate/threadobj.h
index 609826b..8e2c235 100644
--- a/include/copperplate/threadobj.h
+++ b/include/copperplate/threadobj.h
@@ -163,6 +163,7 @@ struct threadobj {
        char name[32];
 
        void (*finalizer)(struct threadobj *thobj);
+       int core_offset;
        int *errno_pointer;
        /* Those members belong exclusively to the syncobj code. */
        struct syncobj *wait_sobj;
@@ -266,9 +267,9 @@ void *__threadobj_alloc(size_t tcb_struct_size,
                        size_t wait_union_size,
                        int thobj_offset);
 
-static inline void threadobj_free(void *p)
+static inline void threadobj_free(struct threadobj *thobj)
 {
-       xnfree(p);
+       xnfree((void *)thobj - thobj->core_offset);
 }
 
 void threadobj_init(struct threadobj *thobj,
diff --git a/lib/alchemy/task.c b/lib/alchemy/task.c
index e5d1e7d..00cf278 100644
--- a/lib/alchemy/task.c
+++ b/lib/alchemy/task.c
@@ -143,10 +143,6 @@ static void task_finalizer(struct threadobj *thobj)
         */
        __bt(syncobj_lock(&tcb->sobj_msg, &syns));
        syncobj_destroy(&tcb->sobj_msg, &syns);
-       threadobj_destroy(&tcb->thobj);
-       backtrace_dump(&thobj->btd);
-
-       threadobj_free(tcb);
 }
 
 static int task_prologue(struct alchemy_task *tcb)
@@ -192,9 +188,9 @@ out:
 
 static void delete_tcb(struct alchemy_task *tcb)
 {
-       threadobj_destroy(&tcb->thobj);
        syncobj_uninit(&tcb->sobj_msg);
-       threadobj_free(tcb);
+       threadobj_destroy(&tcb->thobj);
+       threadobj_free(&tcb->thobj);
 }
 
 static int create_tcb(struct alchemy_task **tcbp, RT_TASK *task,
diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c
index da1c414..4bbf06e 100644
--- a/lib/copperplate/threadobj.c
+++ b/lib/copperplate/threadobj.c
@@ -748,6 +748,7 @@ void *__threadobj_alloc(size_t tcb_struct_size,
                return NULL;
 
        thobj = p + thobj_offset;
+       thobj->core_offset = thobj_offset;
        thobj->wait_union = p + tcb_struct_size;
        thobj->wait_size = wait_union_size;
 
@@ -912,8 +913,6 @@ int threadobj_prologue(struct threadobj *thobj, const char 
*name)
                assert(current->magic == 0);
                sysgroup_remove(thread, &current->memspec);
                finalize_thread(current);
-               threadobj_cleanup_corespec(current);
-               threadobj_free(current);
        } else
                pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
 
@@ -1059,6 +1058,13 @@ int threadobj_cancel(struct threadobj *thobj)
        return 0;
 }
 
+static void destroy_thread(struct threadobj *thobj)
+{
+       __RT(pthread_cond_destroy(&thobj->barrier));
+       __RT(pthread_mutex_destroy(&thobj->lock));
+       threadobj_cleanup_corespec(thobj);
+}
+
 static void finalize_thread(void *p) /* thobj->lock free */
 {
        struct threadobj *thobj = p;
@@ -1081,26 +1087,22 @@ static void finalize_thread(void *p) /* thobj->lock 
free */
        backtrace_dump(&thobj->btd);
        backtrace_destroy_context(&thobj->btd);
 
-       if (thobj->cancel_sem)
-               /* Release the killer from threadobj_cancel(). */
-               sem_post(thobj->cancel_sem);
-
-       /*
-        * Careful: once the user-defined finalizer has run, thobj may
-        * be laid on stale memory. Do not refer to its contents.
-        */
-
        if (thobj->finalizer)
                thobj->finalizer(thobj);
 
+       if (thobj->cancel_sem)
+               /* Release the killer from threadobj_cancel(). */
+               __STD(sem_post)(thobj->cancel_sem);
+
+       destroy_thread(thobj);
+       threadobj_free(thobj);
        threadobj_set_current(NULL);
 }
 
 void threadobj_destroy(struct threadobj *thobj) /* thobj->lock free */
 {
-       __RT(pthread_cond_destroy(&thobj->barrier));
-       __RT(pthread_mutex_destroy(&thobj->lock));
-       threadobj_cleanup_corespec(thobj);
+       assert((thobj->status & (__THREAD_S_STARTED|__THREAD_S_ACTIVE)) == 0);
+       destroy_thread(thobj);
 }
 
 int threadobj_unblock(struct threadobj *thobj) /* thobj->lock held */
diff --git a/lib/psos/task.c b/lib/psos/task.c
index a00cca2..27accef 100644
--- a/lib/psos/task.c
+++ b/lib/psos/task.c
@@ -167,9 +167,6 @@ static void task_finalizer(struct threadobj *thobj)
        /* We have to hold a lock on a syncobj to destroy it. */
        syncobj_lock(&task->sobj, &syns);
        syncobj_destroy(&task->sobj, &syns);
-       threadobj_destroy(&task->thobj);
-
-       threadobj_free(task);
 }
 
 static void *task_trampoline(void *arg)
@@ -278,7 +275,7 @@ u_long t_create(const char *name, u_long prio,
         * value based on the implementation default for such minimum.
         */
        if (ustack > 0 && ustack < 8192) {
-               threadobj_free(task);
+               threadobj_free(&task->thobj);
                ret = ERR_TINYSTK;
                goto out;
        }
@@ -321,7 +318,7 @@ u_long t_create(const char *name, u_long prio,
        fail:
                syncobj_lock(&task->sobj, &syns);
                syncobj_destroy(&task->sobj, &syns);
-               threadobj_free(task);
+               threadobj_free(&task->thobj);
        }
 out:
        COPPERPLATE_UNPROTECT(svc);
diff --git a/lib/vxworks/taskLib.c b/lib/vxworks/taskLib.c
index a212ea2..ffd9ce2 100644
--- a/lib/vxworks/taskLib.c
+++ b/lib/vxworks/taskLib.c
@@ -159,9 +159,6 @@ static void task_finalizer(struct threadobj *thobj)
        cluster_delobj(&wind_task_table, &task->cobj);
        registry_destroy_file(&task->fsobj);
        __RT(pthread_mutex_destroy(&task->safelock));
-       threadobj_destroy(&task->thobj);
-
-       threadobj_free(task);
 }
 
 #ifdef CONFIG_XENO_REGISTRY


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

Reply via email to