[Xenomai-git] Gilles Chanteperdrix : posix/mutex: fix autoinit

2015-10-17 Thread git repository hosting
Module: xenomai-3
Branch: arm64
Commit: dfa9ad71e481c70069cce539b462806ab2abee6c
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=dfa9ad71e481c70069cce539b462806ab2abee6c

Author: Gilles Chanteperdrix 
Date:   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

2015-10-06 Thread git repository hosting
Module: xenomai-3
Branch: master
Commit: dfa9ad71e481c70069cce539b462806ab2abee6c
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=dfa9ad71e481c70069cce539b462806ab2abee6c

Author: Gilles Chanteperdrix 
Date:   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

2015-10-03 Thread git repository hosting
Module: xenomai-gch
Branch: for-forge
Commit: dfa9ad71e481c70069cce539b462806ab2abee6c
URL:
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=dfa9ad71e481c70069cce539b462806ab2abee6c

Author: Gilles Chanteperdrix 
Date:   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

2015-10-03 Thread git repository hosting
Module: xenomai-3
Branch: next
Commit: dfa9ad71e481c70069cce539b462806ab2abee6c
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=dfa9ad71e481c70069cce539b462806ab2abee6c

Author: Gilles Chanteperdrix 
Date:   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