[Xenomai-git] Gilles Chanteperdrix : posix: fix pthread_once

2016-06-16 Thread git repository hosting
Module: xenomai-2.6
Branch: master
Commit: 599cc6d45bfa8b935fca80f1001733742819d394
URL:
http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=599cc6d45bfa8b935fca80f1001733742819d394

Author: Gilles Chanteperdrix 
Date:   Thu Jun 16 15:11:29 2016 +0200

posix: fix pthread_once

The pthread_once implementation was broken, fix it. It becomes
restricted to Xenomai threads, but this functionality makes no sense for
modules init functions, as a module init function is guaranteed to be
executed once by definition.

---

 ksrc/skins/posix/module.c |   43 +--
 ksrc/skins/posix/once.c   |  104 +++--
 ksrc/skins/posix/once.h   |8 
 3 files changed, 130 insertions(+), 25 deletions(-)

diff --git a/ksrc/skins/posix/module.c b/ksrc/skins/posix/module.c
index eea6e13..b0c40a2 100644
--- a/ksrc/skins/posix/module.c
+++ b/ksrc/skins/posix/module.c
@@ -63,6 +63,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("POSIX/PSE51 interface");
 MODULE_AUTHOR("gilles.chanteperd...@xenomai.org");
@@ -86,6 +87,7 @@ static void pse51_shutdown(int xtype)
 #endif /* CONFIG_XENO_OPT_POSIX_SHM */
pse51_timer_pkg_cleanup();
pse51_mq_pkg_cleanup();
+   pse51_once_pkg_cleanup();
pse51_cond_pkg_cleanup();
pse51_tsd_pkg_cleanup();
pse51_sem_pkg_cleanup();
@@ -129,19 +131,9 @@ int SKIN_INIT(posix)
 
 #ifdef CONFIG_XENO_OPT_PERVASIVE
err = pse51_syscall_init();
+   if (err != 0)
+   goto fail_apc_cleanup;
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
-   if (err != 0) {
-#ifdef __KERNEL__
-   pse51_apc_pkg_cleanup();
- fail_free_tbase:
-#endif /* __KERNEL__ */
-   xntbase_free(pse51_tbase);
-   fail_shutdown_pod:
-   xnpod_shutdown(err);
- fail:
-   xnlogerr("POSIX skin init failed, code %d.\n", err);
-   return err;
-   }
 
pse51_reg_pkg_init(CONFIG_XENO_OPT_POSIX_REGISTRY_NRSLOTS, 
CONFIG_XENO_OPT_POSIX_REGISTRY_NRDESCS);
@@ -150,6 +142,11 @@ int SKIN_INIT(posix)
pse51_sem_pkg_init();
pse51_tsd_pkg_init();
pse51_cond_pkg_init();
+
+   err = pse51_once_pkg_init();
+   if (err)
+   goto fail_cond_cleanup;
+
pse51_mq_pkg_init();
 #ifdef CONFIG_XENO_OPT_POSIX_INTR
pse51_intr_pkg_init();
@@ -162,6 +159,28 @@ int SKIN_INIT(posix)
pse51_thread_pkg_init(module_param_value(time_slice_arg));
 
return 0;
+
+  fail_cond_cleanup:
+   pse51_cond_pkg_cleanup();
+   pse51_tsd_pkg_cleanup();
+   pse51_sem_pkg_cleanup();
+   pse51_mutex_pkg_cleanup();
+   pse51_signal_pkg_cleanup();
+   pse51_reg_pkg_cleanup();
+#ifdef CONFIG_XENO_OPT_PERVASIVE
+   pse51_syscall_cleanup();
+  fail_apc_cleanup:
+#endif /* CONFIG_XENO_OPT_PERVASIVE */
+#ifdef __KERNEL__
+   pse51_apc_pkg_cleanup();
+  fail_free_tbase:
+#endif /* __KERNEL__ */
+   xntbase_free(pse51_tbase);
+  fail_shutdown_pod:
+   xnpod_shutdown(err);
+  fail:
+   xnlogerr("POSIX skin init failed, code %d.\n", err);
+   return err;
 }
 
 void SKIN_EXIT(posix)
diff --git a/ksrc/skins/posix/once.c b/ksrc/skins/posix/once.c
index 8787c1f..ca8c2dd 100644
--- a/ksrc/skins/posix/once.c
+++ b/ksrc/skins/posix/once.c
@@ -23,6 +23,9 @@
 
 #include 
 
+static pthread_mutex_t mutex;
+static pthread_cond_t cond;
+
 /**
  * Execute an initialization routine.
  *
@@ -35,34 +38,109 @@
  * @return 0 on success;
  * @return an error number if:
  * - EINVAL, the object pointed to by @a once is invalid (it must have been
- *   initialized with PTHREAD_ONCE_INIT).
+ *   initialized with PTHREAD_ONCE_INIT);
+ * - EPERM, the caller context is invalid.
+ *
+ * @par Valid contexts:
+ * - Xenomai kernel-space thread.
  *
  * @see
  * http://www.opengroup.org/onlinepubs/95399/functions/pthread_once.html";>
  * Specification.
  *
  */
-int pthread_once(pthread_once_t * once, void (*init_routine) (void))
+
+static void once_cleanup(void *cookie)
+{
+   pthread_once_t *once = cookie;
+
+   pthread_mutex_lock(&mutex);
+   once->routine_called = 0;
+   pthread_cond_broadcast(&cond);
+   pthread_mutex_unlock(&mutex);
+}
+
+int pthread_once(pthread_once_t *once, void (*init_routine)(void))
 {
-   spl_t s;
+   int err;
 
-   xnlock_get_irqsave(&nklock, s);
+   err = pthread_mutex_lock(&mutex);
+   if (err)
+   return err;
 
if (!pse51_obj_active(once, PSE51_ONCE_MAGIC, pthread_once_t)) {
-   xnlock_put_irqrestore(&nklock, s);
-   return EINVAL;
+   err = EINVAL;
+   goto out;
}
 
-   if (!once->routine_called) {
-   init_routine();
-   /* If the calling thread is canceled while executing 
init_routine,
-  routine_called will not be set to 1. */
-   once->routine_called = 1;
+   whi

[Xenomai-git] Gilles Chanteperdrix : posix: fix pthread_once

2016-06-16 Thread git repository hosting
Module: xenomai-2.6
Branch: master
Commit: cd1c762280126f78c9e8fa3e4118a912dd0e0563
URL:
http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=cd1c762280126f78c9e8fa3e4118a912dd0e0563

Author: Gilles Chanteperdrix 
Date:   Thu Jun 16 15:11:29 2016 +0200

posix: fix pthread_once

The pthread_once implementation was broken, fix it. It becomes
restricted to Xenomai threads, but this functionality makes no sense for
modules init functions, as a module init function is guaranteed to be
executed once by definition.

---

 ksrc/skins/posix/module.c |   43 +--
 ksrc/skins/posix/once.c   |  104 +++--
 ksrc/skins/posix/once.h   |8 
 3 files changed, 130 insertions(+), 25 deletions(-)

diff --git a/ksrc/skins/posix/module.c b/ksrc/skins/posix/module.c
index eea6e13..b0c40a2 100644
--- a/ksrc/skins/posix/module.c
+++ b/ksrc/skins/posix/module.c
@@ -63,6 +63,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("POSIX/PSE51 interface");
 MODULE_AUTHOR("gilles.chanteperd...@xenomai.org");
@@ -86,6 +87,7 @@ static void pse51_shutdown(int xtype)
 #endif /* CONFIG_XENO_OPT_POSIX_SHM */
pse51_timer_pkg_cleanup();
pse51_mq_pkg_cleanup();
+   pse51_once_pkg_cleanup();
pse51_cond_pkg_cleanup();
pse51_tsd_pkg_cleanup();
pse51_sem_pkg_cleanup();
@@ -129,19 +131,9 @@ int SKIN_INIT(posix)
 
 #ifdef CONFIG_XENO_OPT_PERVASIVE
err = pse51_syscall_init();
+   if (err != 0)
+   goto fail_apc_cleanup;
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
-   if (err != 0) {
-#ifdef __KERNEL__
-   pse51_apc_pkg_cleanup();
- fail_free_tbase:
-#endif /* __KERNEL__ */
-   xntbase_free(pse51_tbase);
-   fail_shutdown_pod:
-   xnpod_shutdown(err);
- fail:
-   xnlogerr("POSIX skin init failed, code %d.\n", err);
-   return err;
-   }
 
pse51_reg_pkg_init(CONFIG_XENO_OPT_POSIX_REGISTRY_NRSLOTS, 
CONFIG_XENO_OPT_POSIX_REGISTRY_NRDESCS);
@@ -150,6 +142,11 @@ int SKIN_INIT(posix)
pse51_sem_pkg_init();
pse51_tsd_pkg_init();
pse51_cond_pkg_init();
+
+   err = pse51_once_pkg_init();
+   if (err)
+   goto fail_cond_cleanup;
+
pse51_mq_pkg_init();
 #ifdef CONFIG_XENO_OPT_POSIX_INTR
pse51_intr_pkg_init();
@@ -162,6 +159,28 @@ int SKIN_INIT(posix)
pse51_thread_pkg_init(module_param_value(time_slice_arg));
 
return 0;
+
+  fail_cond_cleanup:
+   pse51_cond_pkg_cleanup();
+   pse51_tsd_pkg_cleanup();
+   pse51_sem_pkg_cleanup();
+   pse51_mutex_pkg_cleanup();
+   pse51_signal_pkg_cleanup();
+   pse51_reg_pkg_cleanup();
+#ifdef CONFIG_XENO_OPT_PERVASIVE
+   pse51_syscall_cleanup();
+  fail_apc_cleanup:
+#endif /* CONFIG_XENO_OPT_PERVASIVE */
+#ifdef __KERNEL__
+   pse51_apc_pkg_cleanup();
+  fail_free_tbase:
+#endif /* __KERNEL__ */
+   xntbase_free(pse51_tbase);
+  fail_shutdown_pod:
+   xnpod_shutdown(err);
+  fail:
+   xnlogerr("POSIX skin init failed, code %d.\n", err);
+   return err;
 }
 
 void SKIN_EXIT(posix)
diff --git a/ksrc/skins/posix/once.c b/ksrc/skins/posix/once.c
index 8787c1f..ca8c2dd 100644
--- a/ksrc/skins/posix/once.c
+++ b/ksrc/skins/posix/once.c
@@ -23,6 +23,9 @@
 
 #include 
 
+static pthread_mutex_t mutex;
+static pthread_cond_t cond;
+
 /**
  * Execute an initialization routine.
  *
@@ -35,34 +38,109 @@
  * @return 0 on success;
  * @return an error number if:
  * - EINVAL, the object pointed to by @a once is invalid (it must have been
- *   initialized with PTHREAD_ONCE_INIT).
+ *   initialized with PTHREAD_ONCE_INIT);
+ * - EPERM, the caller context is invalid.
+ *
+ * @par Valid contexts:
+ * - Xenomai kernel-space thread.
  *
  * @see
  * http://www.opengroup.org/onlinepubs/95399/functions/pthread_once.html";>
  * Specification.
  *
  */
-int pthread_once(pthread_once_t * once, void (*init_routine) (void))
+
+static void once_cleanup(void *cookie)
+{
+   pthread_once_t *once = cookie;
+
+   pthread_mutex_lock(&mutex);
+   once->routine_called = 0;
+   pthread_cond_broadcast(&cond);
+   pthread_mutex_unlock(&mutex);
+}
+
+int pthread_once(pthread_once_t *once, void (*init_routine)(void))
 {
-   spl_t s;
+   int err;
 
-   xnlock_get_irqsave(&nklock, s);
+   err = pthread_mutex_lock(&mutex);
+   if (err)
+   return err;
 
if (!pse51_obj_active(once, PSE51_ONCE_MAGIC, pthread_once_t)) {
-   xnlock_put_irqrestore(&nklock, s);
-   return EINVAL;
+   err = EINVAL;
+   goto out;
}
 
-   if (!once->routine_called) {
-   init_routine();
-   /* If the calling thread is canceled while executing 
init_routine,
-  routine_called will not be set to 1. */
-   once->routine_called = 1;
+   whi

[Xenomai-git] Gilles Chanteperdrix : posix: fix pthread_once

2016-06-16 Thread git repository hosting
Module: xenomai-2.6
Branch: master
Commit: b0a27e766606dc86d5629f9e47e0a4615e8f0285
URL:
http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=b0a27e766606dc86d5629f9e47e0a4615e8f0285

Author: Gilles Chanteperdrix 
Date:   Thu Jun 16 15:11:29 2016 +0200

posix: fix pthread_once

The pthread_once implementation was broken, fix it. It becomes
restricted to Xenomai threads, but this functionality makes no sense for
modules init functions, as a module init function is guaranteed to be
executed once by definition.

---

 ksrc/skins/posix/module.c |   43 +--
 ksrc/skins/posix/once.c   |  104 +++--
 2 files changed, 122 insertions(+), 25 deletions(-)

diff --git a/ksrc/skins/posix/module.c b/ksrc/skins/posix/module.c
index eea6e13..b0c40a2 100644
--- a/ksrc/skins/posix/module.c
+++ b/ksrc/skins/posix/module.c
@@ -63,6 +63,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("POSIX/PSE51 interface");
 MODULE_AUTHOR("gilles.chanteperd...@xenomai.org");
@@ -86,6 +87,7 @@ static void pse51_shutdown(int xtype)
 #endif /* CONFIG_XENO_OPT_POSIX_SHM */
pse51_timer_pkg_cleanup();
pse51_mq_pkg_cleanup();
+   pse51_once_pkg_cleanup();
pse51_cond_pkg_cleanup();
pse51_tsd_pkg_cleanup();
pse51_sem_pkg_cleanup();
@@ -129,19 +131,9 @@ int SKIN_INIT(posix)
 
 #ifdef CONFIG_XENO_OPT_PERVASIVE
err = pse51_syscall_init();
+   if (err != 0)
+   goto fail_apc_cleanup;
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
-   if (err != 0) {
-#ifdef __KERNEL__
-   pse51_apc_pkg_cleanup();
- fail_free_tbase:
-#endif /* __KERNEL__ */
-   xntbase_free(pse51_tbase);
-   fail_shutdown_pod:
-   xnpod_shutdown(err);
- fail:
-   xnlogerr("POSIX skin init failed, code %d.\n", err);
-   return err;
-   }
 
pse51_reg_pkg_init(CONFIG_XENO_OPT_POSIX_REGISTRY_NRSLOTS, 
CONFIG_XENO_OPT_POSIX_REGISTRY_NRDESCS);
@@ -150,6 +142,11 @@ int SKIN_INIT(posix)
pse51_sem_pkg_init();
pse51_tsd_pkg_init();
pse51_cond_pkg_init();
+
+   err = pse51_once_pkg_init();
+   if (err)
+   goto fail_cond_cleanup;
+
pse51_mq_pkg_init();
 #ifdef CONFIG_XENO_OPT_POSIX_INTR
pse51_intr_pkg_init();
@@ -162,6 +159,28 @@ int SKIN_INIT(posix)
pse51_thread_pkg_init(module_param_value(time_slice_arg));
 
return 0;
+
+  fail_cond_cleanup:
+   pse51_cond_pkg_cleanup();
+   pse51_tsd_pkg_cleanup();
+   pse51_sem_pkg_cleanup();
+   pse51_mutex_pkg_cleanup();
+   pse51_signal_pkg_cleanup();
+   pse51_reg_pkg_cleanup();
+#ifdef CONFIG_XENO_OPT_PERVASIVE
+   pse51_syscall_cleanup();
+  fail_apc_cleanup:
+#endif /* CONFIG_XENO_OPT_PERVASIVE */
+#ifdef __KERNEL__
+   pse51_apc_pkg_cleanup();
+  fail_free_tbase:
+#endif /* __KERNEL__ */
+   xntbase_free(pse51_tbase);
+  fail_shutdown_pod:
+   xnpod_shutdown(err);
+  fail:
+   xnlogerr("POSIX skin init failed, code %d.\n", err);
+   return err;
 }
 
 void SKIN_EXIT(posix)
diff --git a/ksrc/skins/posix/once.c b/ksrc/skins/posix/once.c
index 8787c1f..ca8c2dd 100644
--- a/ksrc/skins/posix/once.c
+++ b/ksrc/skins/posix/once.c
@@ -23,6 +23,9 @@
 
 #include 
 
+static pthread_mutex_t mutex;
+static pthread_cond_t cond;
+
 /**
  * Execute an initialization routine.
  *
@@ -35,34 +38,109 @@
  * @return 0 on success;
  * @return an error number if:
  * - EINVAL, the object pointed to by @a once is invalid (it must have been
- *   initialized with PTHREAD_ONCE_INIT).
+ *   initialized with PTHREAD_ONCE_INIT);
+ * - EPERM, the caller context is invalid.
+ *
+ * @par Valid contexts:
+ * - Xenomai kernel-space thread.
  *
  * @see
  * http://www.opengroup.org/onlinepubs/95399/functions/pthread_once.html";>
  * Specification.
  *
  */
-int pthread_once(pthread_once_t * once, void (*init_routine) (void))
+
+static void once_cleanup(void *cookie)
+{
+   pthread_once_t *once = cookie;
+
+   pthread_mutex_lock(&mutex);
+   once->routine_called = 0;
+   pthread_cond_broadcast(&cond);
+   pthread_mutex_unlock(&mutex);
+}
+
+int pthread_once(pthread_once_t *once, void (*init_routine)(void))
 {
-   spl_t s;
+   int err;
 
-   xnlock_get_irqsave(&nklock, s);
+   err = pthread_mutex_lock(&mutex);
+   if (err)
+   return err;
 
if (!pse51_obj_active(once, PSE51_ONCE_MAGIC, pthread_once_t)) {
-   xnlock_put_irqrestore(&nklock, s);
-   return EINVAL;
+   err = EINVAL;
+   goto out;
}
 
-   if (!once->routine_called) {
-   init_routine();
-   /* If the calling thread is canceled while executing 
init_routine,
-  routine_called will not be set to 1. */
-   once->routine_called = 1;
+   while (once->routine_called != 2)
+