[Xenomai-git] Gilles Chanteperdrix : posix/mutex: fix autoinit
Module: xenomai-3 Branch: arm64 Commit: dfa9ad71e481c70069cce539b462806ab2abee6c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=dfa9ad71e481c70069cce539b462806ab2abee6c Author: Gilles ChanteperdrixDate: Fri Oct 2 23:07:16 2015 +0200 posix/mutex: fix autoinit If several threads call simultaneously pthread_mutex_lock() on a mutex initialized with PTHREAD_MUTEX_INITIALIZER, the current automatic intialization may result in several initializations of the mutex. Serialize the automatic initialization with a global mutex to avoid that. This can be done only for automatic initialization, as pthread_mutex_init() may be called from a non Xenomai thread, which could not sleep on a cobalt mutex, and serializing with a plain Linux mutex would cause a switch to secondary mode for pthread_mutex_lock() in case of automatic initialization. Using a condition variable would create a cancellation point, whereas pthread_mutex_lock() and pthread_mutex_unlock() can not be cancellation points. --- lib/cobalt/init.c |2 +- lib/cobalt/internal.h |2 +- lib/cobalt/mutex.c| 26 +++--- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/cobalt/init.c b/lib/cobalt/init.c index 2910f6e..9d1674d 100644 --- a/lib/cobalt/init.c +++ b/lib/cobalt/init.c @@ -172,6 +172,7 @@ static void __cobalt_init(void) sizeof(sem_t), sizeof(struct cobalt_sem_shadow)); + cobalt_mutex_init(); cobalt_thread_init(); cobalt_print_init(); } @@ -189,7 +190,6 @@ int cobalt_init(void) int policy, ret; commit_stack_memory(); /* We only need this for the main thread */ - cobalt_default_mutexattr_init(); cobalt_default_condattr_init(); __cobalt_init(); diff --git a/lib/cobalt/internal.h b/lib/cobalt/internal.h index 540c286..4f03cf0 100644 --- a/lib/cobalt/internal.h +++ b/lib/cobalt/internal.h @@ -51,7 +51,7 @@ void cobalt_print_init_atfork(void); void cobalt_ticks_init(unsigned long long freq); -void cobalt_default_mutexattr_init(void); +void cobalt_mutex_init(void); void cobalt_default_condattr_init(void); diff --git a/lib/cobalt/mutex.c b/lib/cobalt/mutex.c index e4024e3..f613478 100644 --- a/lib/cobalt/mutex.c +++ b/lib/cobalt/mutex.c @@ -56,10 +56,21 @@ */ static pthread_mutexattr_t cobalt_default_mutexattr; +static pthread_mutex_t cobalt_autoinit_mutex; -void cobalt_default_mutexattr_init(void) +void cobalt_mutex_init(void) { + pthread_mutexattr_t rt_init_mattr; + int err __attribute__((unused)); + pthread_mutexattr_init(_default_mutexattr); + + pthread_mutexattr_init(_init_mattr); + pthread_mutexattr_setprotocol(_init_mattr, PTHREAD_PRIO_INHERIT); + err = __COBALT(pthread_mutex_init(_autoinit_mutex, + _init_mattr)); + assert(err == 0); + pthread_mutexattr_destroy(_init_mattr); } /** @@ -176,12 +187,15 @@ COBALT_IMPL(int, pthread_mutex_destroy, (pthread_mutex_t *mutex)) static int __attribute__((cold)) cobalt_mutex_autoinit(pthread_mutex_t *mutex) { static pthread_mutex_t uninit_normal_mutex = PTHREAD_MUTEX_INITIALIZER; + struct cobalt_mutex_shadow *_mutex = + &((union cobalt_mutex_union *)mutex)->shadow_mutex; static pthread_mutex_t uninit_recursive_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; static pthread_mutex_t uninit_errorcheck_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; + int err __attribute__((unused)); pthread_mutexattr_t mattr; - int ret, type; + int ret = 0, type; if (memcmp(mutex, _normal_mutex, sizeof(*mutex)) == 0) type = PTHREAD_MUTEX_DEFAULT; @@ -194,7 +208,13 @@ static int __attribute__((cold)) cobalt_mutex_autoinit(pthread_mutex_t *mutex) pthread_mutexattr_init(); pthread_mutexattr_settype(, type); - ret = __COBALT(pthread_mutex_init(mutex, )); + err = __COBALT(pthread_mutex_lock(_autoinit_mutex)); + assert(err = 0); + if (_mutex->magic != COBALT_MUTEX_MAGIC) + ret = __COBALT(pthread_mutex_init(mutex, )); + err = __COBALT(pthread_mutex_unlock(_autoinit_mutex)); + assert(err == 0); + pthread_mutexattr_destroy(); return ret; ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : posix/mutex: fix autoinit
Module: xenomai-3 Branch: master Commit: dfa9ad71e481c70069cce539b462806ab2abee6c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=dfa9ad71e481c70069cce539b462806ab2abee6c Author: Gilles ChanteperdrixDate: Fri Oct 2 23:07:16 2015 +0200 posix/mutex: fix autoinit If several threads call simultaneously pthread_mutex_lock() on a mutex initialized with PTHREAD_MUTEX_INITIALIZER, the current automatic intialization may result in several initializations of the mutex. Serialize the automatic initialization with a global mutex to avoid that. This can be done only for automatic initialization, as pthread_mutex_init() may be called from a non Xenomai thread, which could not sleep on a cobalt mutex, and serializing with a plain Linux mutex would cause a switch to secondary mode for pthread_mutex_lock() in case of automatic initialization. Using a condition variable would create a cancellation point, whereas pthread_mutex_lock() and pthread_mutex_unlock() can not be cancellation points. --- lib/cobalt/init.c |2 +- lib/cobalt/internal.h |2 +- lib/cobalt/mutex.c| 26 +++--- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/cobalt/init.c b/lib/cobalt/init.c index 2910f6e..9d1674d 100644 --- a/lib/cobalt/init.c +++ b/lib/cobalt/init.c @@ -172,6 +172,7 @@ static void __cobalt_init(void) sizeof(sem_t), sizeof(struct cobalt_sem_shadow)); + cobalt_mutex_init(); cobalt_thread_init(); cobalt_print_init(); } @@ -189,7 +190,6 @@ int cobalt_init(void) int policy, ret; commit_stack_memory(); /* We only need this for the main thread */ - cobalt_default_mutexattr_init(); cobalt_default_condattr_init(); __cobalt_init(); diff --git a/lib/cobalt/internal.h b/lib/cobalt/internal.h index 540c286..4f03cf0 100644 --- a/lib/cobalt/internal.h +++ b/lib/cobalt/internal.h @@ -51,7 +51,7 @@ void cobalt_print_init_atfork(void); void cobalt_ticks_init(unsigned long long freq); -void cobalt_default_mutexattr_init(void); +void cobalt_mutex_init(void); void cobalt_default_condattr_init(void); diff --git a/lib/cobalt/mutex.c b/lib/cobalt/mutex.c index e4024e3..f613478 100644 --- a/lib/cobalt/mutex.c +++ b/lib/cobalt/mutex.c @@ -56,10 +56,21 @@ */ static pthread_mutexattr_t cobalt_default_mutexattr; +static pthread_mutex_t cobalt_autoinit_mutex; -void cobalt_default_mutexattr_init(void) +void cobalt_mutex_init(void) { + pthread_mutexattr_t rt_init_mattr; + int err __attribute__((unused)); + pthread_mutexattr_init(_default_mutexattr); + + pthread_mutexattr_init(_init_mattr); + pthread_mutexattr_setprotocol(_init_mattr, PTHREAD_PRIO_INHERIT); + err = __COBALT(pthread_mutex_init(_autoinit_mutex, + _init_mattr)); + assert(err == 0); + pthread_mutexattr_destroy(_init_mattr); } /** @@ -176,12 +187,15 @@ COBALT_IMPL(int, pthread_mutex_destroy, (pthread_mutex_t *mutex)) static int __attribute__((cold)) cobalt_mutex_autoinit(pthread_mutex_t *mutex) { static pthread_mutex_t uninit_normal_mutex = PTHREAD_MUTEX_INITIALIZER; + struct cobalt_mutex_shadow *_mutex = + &((union cobalt_mutex_union *)mutex)->shadow_mutex; static pthread_mutex_t uninit_recursive_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; static pthread_mutex_t uninit_errorcheck_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; + int err __attribute__((unused)); pthread_mutexattr_t mattr; - int ret, type; + int ret = 0, type; if (memcmp(mutex, _normal_mutex, sizeof(*mutex)) == 0) type = PTHREAD_MUTEX_DEFAULT; @@ -194,7 +208,13 @@ static int __attribute__((cold)) cobalt_mutex_autoinit(pthread_mutex_t *mutex) pthread_mutexattr_init(); pthread_mutexattr_settype(, type); - ret = __COBALT(pthread_mutex_init(mutex, )); + err = __COBALT(pthread_mutex_lock(_autoinit_mutex)); + assert(err = 0); + if (_mutex->magic != COBALT_MUTEX_MAGIC) + ret = __COBALT(pthread_mutex_init(mutex, )); + err = __COBALT(pthread_mutex_unlock(_autoinit_mutex)); + assert(err == 0); + pthread_mutexattr_destroy(); return ret; ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : posix/mutex: fix autoinit
Module: xenomai-gch Branch: for-forge Commit: dfa9ad71e481c70069cce539b462806ab2abee6c URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=dfa9ad71e481c70069cce539b462806ab2abee6c Author: Gilles ChanteperdrixDate: Fri Oct 2 23:07:16 2015 +0200 posix/mutex: fix autoinit If several threads call simultaneously pthread_mutex_lock() on a mutex initialized with PTHREAD_MUTEX_INITIALIZER, the current automatic intialization may result in several initializations of the mutex. Serialize the automatic initialization with a global mutex to avoid that. This can be done only for automatic initialization, as pthread_mutex_init() may be called from a non Xenomai thread, which could not sleep on a cobalt mutex, and serializing with a plain Linux mutex would cause a switch to secondary mode for pthread_mutex_lock() in case of automatic initialization. Using a condition variable would create a cancellation point, whereas pthread_mutex_lock() and pthread_mutex_unlock() can not be cancellation points. --- lib/cobalt/init.c |2 +- lib/cobalt/internal.h |2 +- lib/cobalt/mutex.c| 26 +++--- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/cobalt/init.c b/lib/cobalt/init.c index 2910f6e..9d1674d 100644 --- a/lib/cobalt/init.c +++ b/lib/cobalt/init.c @@ -172,6 +172,7 @@ static void __cobalt_init(void) sizeof(sem_t), sizeof(struct cobalt_sem_shadow)); + cobalt_mutex_init(); cobalt_thread_init(); cobalt_print_init(); } @@ -189,7 +190,6 @@ int cobalt_init(void) int policy, ret; commit_stack_memory(); /* We only need this for the main thread */ - cobalt_default_mutexattr_init(); cobalt_default_condattr_init(); __cobalt_init(); diff --git a/lib/cobalt/internal.h b/lib/cobalt/internal.h index 540c286..4f03cf0 100644 --- a/lib/cobalt/internal.h +++ b/lib/cobalt/internal.h @@ -51,7 +51,7 @@ void cobalt_print_init_atfork(void); void cobalt_ticks_init(unsigned long long freq); -void cobalt_default_mutexattr_init(void); +void cobalt_mutex_init(void); void cobalt_default_condattr_init(void); diff --git a/lib/cobalt/mutex.c b/lib/cobalt/mutex.c index e4024e3..f613478 100644 --- a/lib/cobalt/mutex.c +++ b/lib/cobalt/mutex.c @@ -56,10 +56,21 @@ */ static pthread_mutexattr_t cobalt_default_mutexattr; +static pthread_mutex_t cobalt_autoinit_mutex; -void cobalt_default_mutexattr_init(void) +void cobalt_mutex_init(void) { + pthread_mutexattr_t rt_init_mattr; + int err __attribute__((unused)); + pthread_mutexattr_init(_default_mutexattr); + + pthread_mutexattr_init(_init_mattr); + pthread_mutexattr_setprotocol(_init_mattr, PTHREAD_PRIO_INHERIT); + err = __COBALT(pthread_mutex_init(_autoinit_mutex, + _init_mattr)); + assert(err == 0); + pthread_mutexattr_destroy(_init_mattr); } /** @@ -176,12 +187,15 @@ COBALT_IMPL(int, pthread_mutex_destroy, (pthread_mutex_t *mutex)) static int __attribute__((cold)) cobalt_mutex_autoinit(pthread_mutex_t *mutex) { static pthread_mutex_t uninit_normal_mutex = PTHREAD_MUTEX_INITIALIZER; + struct cobalt_mutex_shadow *_mutex = + &((union cobalt_mutex_union *)mutex)->shadow_mutex; static pthread_mutex_t uninit_recursive_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; static pthread_mutex_t uninit_errorcheck_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; + int err __attribute__((unused)); pthread_mutexattr_t mattr; - int ret, type; + int ret = 0, type; if (memcmp(mutex, _normal_mutex, sizeof(*mutex)) == 0) type = PTHREAD_MUTEX_DEFAULT; @@ -194,7 +208,13 @@ static int __attribute__((cold)) cobalt_mutex_autoinit(pthread_mutex_t *mutex) pthread_mutexattr_init(); pthread_mutexattr_settype(, type); - ret = __COBALT(pthread_mutex_init(mutex, )); + err = __COBALT(pthread_mutex_lock(_autoinit_mutex)); + assert(err = 0); + if (_mutex->magic != COBALT_MUTEX_MAGIC) + ret = __COBALT(pthread_mutex_init(mutex, )); + err = __COBALT(pthread_mutex_unlock(_autoinit_mutex)); + assert(err == 0); + pthread_mutexattr_destroy(); return ret; ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : posix/mutex: fix autoinit
Module: xenomai-3 Branch: next Commit: dfa9ad71e481c70069cce539b462806ab2abee6c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=dfa9ad71e481c70069cce539b462806ab2abee6c Author: Gilles ChanteperdrixDate: Fri Oct 2 23:07:16 2015 +0200 posix/mutex: fix autoinit If several threads call simultaneously pthread_mutex_lock() on a mutex initialized with PTHREAD_MUTEX_INITIALIZER, the current automatic intialization may result in several initializations of the mutex. Serialize the automatic initialization with a global mutex to avoid that. This can be done only for automatic initialization, as pthread_mutex_init() may be called from a non Xenomai thread, which could not sleep on a cobalt mutex, and serializing with a plain Linux mutex would cause a switch to secondary mode for pthread_mutex_lock() in case of automatic initialization. Using a condition variable would create a cancellation point, whereas pthread_mutex_lock() and pthread_mutex_unlock() can not be cancellation points. --- lib/cobalt/init.c |2 +- lib/cobalt/internal.h |2 +- lib/cobalt/mutex.c| 26 +++--- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/cobalt/init.c b/lib/cobalt/init.c index 2910f6e..9d1674d 100644 --- a/lib/cobalt/init.c +++ b/lib/cobalt/init.c @@ -172,6 +172,7 @@ static void __cobalt_init(void) sizeof(sem_t), sizeof(struct cobalt_sem_shadow)); + cobalt_mutex_init(); cobalt_thread_init(); cobalt_print_init(); } @@ -189,7 +190,6 @@ int cobalt_init(void) int policy, ret; commit_stack_memory(); /* We only need this for the main thread */ - cobalt_default_mutexattr_init(); cobalt_default_condattr_init(); __cobalt_init(); diff --git a/lib/cobalt/internal.h b/lib/cobalt/internal.h index 540c286..4f03cf0 100644 --- a/lib/cobalt/internal.h +++ b/lib/cobalt/internal.h @@ -51,7 +51,7 @@ void cobalt_print_init_atfork(void); void cobalt_ticks_init(unsigned long long freq); -void cobalt_default_mutexattr_init(void); +void cobalt_mutex_init(void); void cobalt_default_condattr_init(void); diff --git a/lib/cobalt/mutex.c b/lib/cobalt/mutex.c index e4024e3..f613478 100644 --- a/lib/cobalt/mutex.c +++ b/lib/cobalt/mutex.c @@ -56,10 +56,21 @@ */ static pthread_mutexattr_t cobalt_default_mutexattr; +static pthread_mutex_t cobalt_autoinit_mutex; -void cobalt_default_mutexattr_init(void) +void cobalt_mutex_init(void) { + pthread_mutexattr_t rt_init_mattr; + int err __attribute__((unused)); + pthread_mutexattr_init(_default_mutexattr); + + pthread_mutexattr_init(_init_mattr); + pthread_mutexattr_setprotocol(_init_mattr, PTHREAD_PRIO_INHERIT); + err = __COBALT(pthread_mutex_init(_autoinit_mutex, + _init_mattr)); + assert(err == 0); + pthread_mutexattr_destroy(_init_mattr); } /** @@ -176,12 +187,15 @@ COBALT_IMPL(int, pthread_mutex_destroy, (pthread_mutex_t *mutex)) static int __attribute__((cold)) cobalt_mutex_autoinit(pthread_mutex_t *mutex) { static pthread_mutex_t uninit_normal_mutex = PTHREAD_MUTEX_INITIALIZER; + struct cobalt_mutex_shadow *_mutex = + &((union cobalt_mutex_union *)mutex)->shadow_mutex; static pthread_mutex_t uninit_recursive_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; static pthread_mutex_t uninit_errorcheck_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; + int err __attribute__((unused)); pthread_mutexattr_t mattr; - int ret, type; + int ret = 0, type; if (memcmp(mutex, _normal_mutex, sizeof(*mutex)) == 0) type = PTHREAD_MUTEX_DEFAULT; @@ -194,7 +208,13 @@ static int __attribute__((cold)) cobalt_mutex_autoinit(pthread_mutex_t *mutex) pthread_mutexattr_init(); pthread_mutexattr_settype(, type); - ret = __COBALT(pthread_mutex_init(mutex, )); + err = __COBALT(pthread_mutex_lock(_autoinit_mutex)); + assert(err = 0); + if (_mutex->magic != COBALT_MUTEX_MAGIC) + ret = __COBALT(pthread_mutex_init(mutex, )); + err = __COBALT(pthread_mutex_unlock(_autoinit_mutex)); + assert(err == 0); + pthread_mutexattr_destroy(); return ret; ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git