Module: xenomai-forge Branch: next Commit: e502d3c86958d081bb74d96e5e9f63e5d834079a URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=e502d3c86958d081bb74d96e5e9f63e5d834079a
Author: Philippe Gerum <r...@xenomai.org> Date: Fri Feb 28 15:08:32 2014 +0100 copperplate/thread: fix priority inversion with parent/child handshaking This patch addresses the issue described here: http://www.xenomai.org/pipermail/xenomai/2014-February/030117.html --- lib/copperplate/internal.c | 47 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/lib/copperplate/internal.c b/lib/copperplate/internal.c index a7f86e7..86e69af 100644 --- a/lib/copperplate/internal.c +++ b/lib/copperplate/internal.c @@ -68,10 +68,9 @@ int copperplate_probe_node(unsigned int id) int copperplate_create_thread(struct corethread_attributes *cta, pthread_t *tid) { - struct sched_param_ex param_ex; pthread_attr_ex_t attr_ex; size_t stacksize; - int policy, ret; + int ret; ret = thread_spawn_prologue(cta); if (ret) @@ -81,12 +80,8 @@ int copperplate_create_thread(struct corethread_attributes *cta, if (stacksize < PTHREAD_STACK_MIN * 4) stacksize = PTHREAD_STACK_MIN * 4; - param_ex.sched_priority = cta->prio; - policy = cta->prio ? SCHED_RT : SCHED_OTHER; pthread_attr_init_ex(&attr_ex); - pthread_attr_setinheritsched_ex(&attr_ex, PTHREAD_EXPLICIT_SCHED); - pthread_attr_setschedpolicy_ex(&attr_ex, policy); - pthread_attr_setschedparam_ex(&attr_ex, ¶m_ex); + pthread_attr_setinheritsched_ex(&attr_ex, PTHREAD_INHERIT_SCHED); pthread_attr_setstacksize_ex(&attr_ex, stacksize); pthread_attr_setdetachstate_ex(&attr_ex, cta->detachstate); ret = __bt(-pthread_create_ex(tid, &attr_ex, thread_trampoline, cta)); @@ -120,6 +115,11 @@ static inline void prepare_wait_corespec(void) cobalt_thread_harden(); } +static inline int finish_wait_corespec(struct corethread_attributes *cta) +{ + return __bt(copperplate_renice_thread(pthread_self(), cta->prio)); +} + #else /* CONFIG_XENO_MERCURY */ int copperplate_probe_node(unsigned int id) @@ -130,10 +130,9 @@ int copperplate_probe_node(unsigned int id) int copperplate_create_thread(struct corethread_attributes *cta, pthread_t *tid) { - struct sched_param param; pthread_attr_t attr; size_t stacksize; - int policy, ret; + int ret; ret = thread_spawn_prologue(cta); if (ret) @@ -143,12 +142,8 @@ int copperplate_create_thread(struct corethread_attributes *cta, if (stacksize < PTHREAD_STACK_MIN * 4) stacksize = PTHREAD_STACK_MIN * 4; - param.sched_priority = cta->prio; - policy = cta->prio ? SCHED_RT : SCHED_OTHER; pthread_attr_init(&attr); - pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); - pthread_attr_setschedpolicy(&attr, policy); - pthread_attr_setschedparam(&attr, ¶m); + pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); pthread_attr_setstacksize(&attr, stacksize); pthread_attr_setdetachstate(&attr, cta->detachstate); ret = __bt(-pthread_create(tid, &attr, thread_trampoline, cta)); @@ -176,6 +171,11 @@ static inline void prepare_wait_corespec(void) /* empty */ } +static inline int finish_wait_corespec(struct corethread_attributes *cta) +{ + return __bt(copperplate_renice_thread(pthread_self(), cta->prio)); +} + #endif /* CONFIG_XENO_MERCURY */ static int thread_spawn_prologue(struct corethread_attributes *cta) @@ -208,19 +208,17 @@ static void thread_spawn_wait(sem_t *sem) static void *thread_trampoline(void *arg) { - struct corethread_attributes *cta = arg; - void *__arg, *(*__run)(void *arg); + struct corethread_attributes *cta = arg, _cta; sem_t released; int ret; /* * cta may be on the parent's stack, so it may be dandling - * soon after the parent is posted: copy what we need from - * this area early on. + * soon after the parent is posted: copy this argument + * structure early on. */ - __run = cta->run; - __arg = cta->arg; - ret = cta->prologue(__arg); + _cta = *cta; + ret = cta->prologue(cta->arg); cta->__reserved.status = ret; if (ret) { @@ -238,12 +236,13 @@ static void *thread_trampoline(void *arg) */ prepare_wait_corespec(); __RT(sem_post(&cta->__reserved.warm)); - thread_spawn_wait(&released); - __RT(sem_destroy(&released)); + ret = finish_wait_corespec(&_cta); + if (ret) + warning("core thread prologue failed, %s", symerror(ret)); - return __run(__arg); + return _cta.run(_cta.arg); } static int thread_spawn_epilogue(struct corethread_attributes *cta) _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git