[Xenomai-git] Gilles Chanteperdrix : posix: fix pthread_once
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
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
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) +