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, ¶m)); } -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, ¶m); - threadobj_lock(thobj); - return __bt(-ret); + return pthread_setschedparam(tid, policy, ¶m); } 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