Module: xenomai-forge
Branch: master
Commit: 072601b0d193b86ee50ec7495eed4b91cc6a5357
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=072601b0d193b86ee50ec7495eed4b91cc6a5357

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu Dec 15 10:30:15 2011 +0100

copperplate/threadobj, lib: fix locking rules of threadobj_set_priority()

Since threadobj_set_priority() must receive the thread lock on entry,
prior to dropping it before applying the priority change via a
syscall, it might be unable to lock it back before returning to the
caller, in case the thread has exited in the meantime.

Instead of attempting to re-lock the object eventually - bluntly
ignoring the operation status - we should rather behave fully as a
lock-dropping call and document it accordingly. Callers should grab
that lock again in case more changes are required (which none of them
currently want anyway).

---

 lib/alchemy/task.c          |    1 -
 lib/copperplate/threadobj.c |   31 +++++++++++++++++--------------
 lib/psos/task.c             |    1 -
 lib/vxworks/taskLib.c       |    1 -
 4 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/lib/alchemy/task.c b/lib/alchemy/task.c
index e21122e..e627a33 100644
--- a/lib/alchemy/task.c
+++ b/lib/alchemy/task.c
@@ -592,7 +592,6 @@ int rt_task_set_priority(RT_TASK *task, int prio)
                goto out;
 
        ret = threadobj_set_priority(&tcb->thobj, prio);
-       put_alchemy_task(tcb);
 out:
        COPPERPLATE_UNPROTECT(svc);
 
diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c
index 79db06f..7dac280 100644
--- a/lib/copperplate/threadobj.c
+++ b/lib/copperplate/threadobj.c
@@ -272,11 +272,11 @@ int threadobj_unlock_sched(struct threadobj *thobj) /* 
thobj->lock held */
        return __bt(-ret);
 }
 
-int threadobj_set_priority(struct threadobj *thobj, int prio) /* thobj->lock 
held */
+int threadobj_set_priority(struct threadobj *thobj, int prio) /* thobj->lock 
held, dropped */
 {
        struct sched_param_ex xparam;
        pthread_t tid = thobj->tid;
-       int ret, policy;
+       int policy;
 
        __threadobj_check_locked(thobj);
 
@@ -297,10 +297,8 @@ int threadobj_set_priority(struct threadobj *thobj, int 
prio) /* thobj->lock hel
         * set.
         */
        xparam.sched_priority = prio;
-       ret = pthread_setschedparam_ex(tid, policy, &xparam);
-       threadobj_lock(thobj);
 
-       return __bt(-ret);
+       return pthread_setschedparam_ex(tid, policy, &xparam);
 }
 
 int threadobj_set_mode(struct threadobj *thobj,
@@ -583,12 +581,14 @@ int threadobj_resume(struct threadobj *thobj) /* 
thobj->lock held */
        return __bt(notifier_release(&thobj->core.notifier));
 }
 
-int threadobj_lock_sched(struct threadobj *thobj)
+int threadobj_lock_sched(struct threadobj *thobj) /* thobj->lock held */
 {
        pthread_t tid = thobj->tid;
        struct sched_param param;
        int policy, ret;
 
+       __threadobj_check_locked(thobj);
+
        assert(thobj == threadobj_current());
 
        if (thobj->schedlock_depth++ > 0)
@@ -606,12 +606,14 @@ int threadobj_lock_sched(struct threadobj *thobj)
        return __bt(-pthread_setschedparam(tid, SCHED_RT, &param));
 }
 
-int threadobj_unlock_sched(struct threadobj *thobj)
+int threadobj_unlock_sched(struct threadobj *thobj) /* thobj->lock held */
 {
        pthread_t tid = thobj->tid;
        struct sched_param param;
        int policy, ret;
 
+       __threadobj_check_locked(thobj);
+
        assert(thobj == threadobj_current());
 
        if (thobj->schedlock_depth == 0)
@@ -631,11 +633,13 @@ int threadobj_unlock_sched(struct threadobj *thobj)
        return __bt(-ret);
 }
 
-int threadobj_set_priority(struct threadobj *thobj, int prio)
+int threadobj_set_priority(struct threadobj *thobj, int prio) /* thobj->lock 
held, dropped */
 {
        pthread_t tid = thobj->tid;
        struct sched_param param;
-       int policy, ret;
+       int policy;
+
+       __threadobj_check_locked(thobj);
 
        /*
         * We don't actually change the scheduling priority in case
@@ -647,18 +651,16 @@ int threadobj_set_priority(struct threadobj *thobj, int 
prio)
                return 0;
        }
 
+       thobj->priority = prio;
        threadobj_unlock(thobj);
        /*
         * Since we released the thread container lock, we now rely on
         * the pthread interface to recheck the tid for existence.
         */
-       thobj->priority = prio;
        param.sched_priority = prio;
        policy = prio ? SCHED_RT : SCHED_OTHER;
-       ret = pthread_setschedparam(tid, policy, &param);
-       threadobj_lock(thobj);
 
-       return __bt(-ret);
+       return pthread_setschedparam(tid, policy, &param);
 }
 
 int threadobj_set_mode(struct threadobj *thobj,
@@ -704,8 +706,9 @@ static inline void set_rr(struct threadobj *thobj, struct 
timespec *quantum)
 }
 
 int threadobj_set_rr(struct threadobj *thobj, struct timespec *quantum)
-{
+{                              /* thobj->lock held if valid */
        if (thobj) {
+               __threadobj_check_locked(thobj);
                set_rr(thobj, quantum);
                return 0;
        }
diff --git a/lib/psos/task.c b/lib/psos/task.c
index b790828..ca62c51 100644
--- a/lib/psos/task.c
+++ b/lib/psos/task.c
@@ -425,7 +425,6 @@ u_long t_setpri(u_long tid, u_long newprio, u_long 
*oldprio_r)
        }
 
        ret = threadobj_set_priority(&task->thobj, cprio);
-       put_psos_task(task);
        if (ret)
                return ERR_OBJDEL;
 
diff --git a/lib/vxworks/taskLib.c b/lib/vxworks/taskLib.c
index 91ca450..5f42430 100644
--- a/lib/vxworks/taskLib.c
+++ b/lib/vxworks/taskLib.c
@@ -732,7 +732,6 @@ STATUS taskPrioritySet(TASK_ID tid, int prio)
        COPPERPLATE_PROTECT(svc);
        ret = threadobj_set_priority(&task->thobj, cprio);
        COPPERPLATE_UNPROTECT(svc);
-       put_wind_task(task);
 
        if (ret) {
        objid_error:


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

Reply via email to