Module: xenomai-forge Branch: master Commit: 014898add6a697e1a0d69f9e20b910ade74f1940 URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=014898add6a697e1a0d69f9e20b910ade74f1940
Author: Philippe Gerum <r...@xenomai.org> Date: Sun Apr 14 18:59:29 2013 +0200 lib/cobalt: fix atfork handling The TLS-based "current" key must be cleared upon fork in the child context, so that assertion code checking the current mode does not spuriously reuse the parent u_window. In addition, the calling sequence of atfork handlers is fixed, so that such handler installed by the deferred print support does not call into assert_nrt() checks from a freshly forked child before the "current" key is cleared. --- lib/cobalt/assert_context.c | 5 +++-- lib/cobalt/current.c | 35 +++++++++++++++++++++-------------- lib/cobalt/init.c | 4 ++-- lib/cobalt/internal.h | 4 ++++ lib/cobalt/printf.c | 9 ++++++--- lib/cobalt/sem_heap.c | 1 + 6 files changed, 37 insertions(+), 21 deletions(-) diff --git a/lib/cobalt/assert_context.c b/lib/cobalt/assert_context.c index 9a864fc..6125355 100644 --- a/lib/cobalt/assert_context.c +++ b/lib/cobalt/assert_context.c @@ -23,6 +23,7 @@ #include <nucleus/thread.h> #include <asm-generic/syscall.h> #include <asm-generic/current.h> +#include <unistd.h> static void assert_nrt_inner(void) { @@ -32,8 +33,8 @@ static void assert_nrt_inner(void) err = XENOMAI_SYSCALL1(sc_nucleus_current_info, &info); if (err) { - fprintf(stderr, "sc_nucleus_current_info failed: %s\n", - strerror(-err)); + fprintf(stderr, "sc_nucleus_current_info failed: %s, window=%p, state=%lx, pid=%d\n", + strerror(-err), xeno_current_window, xeno_current_window->state, getpid()); return; } diff --git a/lib/cobalt/current.c b/lib/cobalt/current.c index 1822703..5b7ed19 100644 --- a/lib/cobalt/current.c +++ b/lib/cobalt/current.c @@ -12,9 +12,13 @@ extern unsigned long xeno_sem_heap[2]; +static void child_fork_handler(void); + #ifdef HAVE_TLS + __thread __attribute__ ((tls_model (CONFIG_XENO_TLS_MODEL))) xnhandle_t xeno_current = XN_NO_HANDLE; + __thread __attribute__ ((tls_model (CONFIG_XENO_TLS_MODEL))) struct xnthread_user_window *xeno_current_window; @@ -23,8 +27,9 @@ static inline void __xeno_set_current(xnhandle_t current) xeno_current = current; } -void xeno_init_current_keys(void) +static void init_current_keys(void) { + pthread_atfork(NULL, NULL, &child_fork_handler); } void xeno_set_current_window(unsigned long offset) @@ -33,6 +38,7 @@ void xeno_set_current_window(unsigned long offset) (xeno_sem_heap[0] + offset); __cobalt_prefault(xeno_current_window); } + #else /* !HAVE_TLS */ pthread_key_t xeno_current_window_key; @@ -44,19 +50,13 @@ static inline void __xeno_set_current(xnhandle_t current) pthread_setspecific(xeno_current_key, (void *)current); } -static void xeno_current_fork_handler(void) -{ - if (xeno_get_current() != XN_NO_HANDLE) - __xeno_set_current(XN_NO_HANDLE); -} - static void init_current_keys(void) { int err = pthread_key_create(&xeno_current_key, NULL); if (err) goto error_exit; - pthread_atfork(NULL, NULL, &xeno_current_fork_handler); + pthread_atfork(NULL, NULL, &child_fork_handler); err = pthread_key_create(&xeno_current_window_key, NULL); if (err) { @@ -67,12 +67,6 @@ static void init_current_keys(void) } } -void xeno_init_current_keys(void) -{ - static pthread_once_t xeno_init_current_keys_once = PTHREAD_ONCE_INIT; - pthread_once(&xeno_init_current_keys_once, init_current_keys); -} - void xeno_set_current_window(unsigned long offset) { struct xnthread_user_window *window; @@ -81,8 +75,15 @@ void xeno_set_current_window(unsigned long offset) pthread_setspecific(xeno_current_window_key, window); __cobalt_prefault(window); } + #endif /* !HAVE_TLS */ +static void child_fork_handler(void) +{ + if (xeno_get_current() != XN_NO_HANDLE) + __xeno_set_current(XN_NO_HANDLE); +} + xnhandle_t xeno_slow_get_current(void) { xnhandle_t current; @@ -106,3 +107,9 @@ void xeno_set_current(void) } __xeno_set_current(current); } + +void xeno_init_current_keys(void) +{ + static pthread_once_t xeno_init_current_keys_once = PTHREAD_ONCE_INIT; + pthread_once(&xeno_init_current_keys_once, init_current_keys); +} diff --git a/lib/cobalt/init.c b/lib/cobalt/init.c index 6743a06..d3e8e9f 100644 --- a/lib/cobalt/init.c +++ b/lib/cobalt/init.c @@ -154,8 +154,6 @@ void __init_cobalt_interface(void) struct sigaction sa; const char *p; - rt_print_auto_init(1); - muxid = bind_interface(); if (muxid < 0) { report_error("interface unavailable"); @@ -223,4 +221,6 @@ no_shadow: (int) sizeof(struct __shadow_mutex)); exit(EXIT_FAILURE); } + + cobalt_print_init(); } diff --git a/lib/cobalt/internal.h b/lib/cobalt/internal.h index 6324622..a939a2b 100644 --- a/lib/cobalt/internal.h +++ b/lib/cobalt/internal.h @@ -71,4 +71,8 @@ int cobalt_event_inquire(cobalt_event_t *event, int cobalt_event_destroy(cobalt_event_t *event); +void cobalt_print_init(void); + +void cobalt_print_exit(void); + #endif /* XENO_COBALT_INTERNAL_H */ diff --git a/lib/cobalt/printf.c b/lib/cobalt/printf.c index f9f2ecb..c4e524f 100644 --- a/lib/cobalt/printf.c +++ b/lib/cobalt/printf.c @@ -32,6 +32,7 @@ #include <asm/xenomai/atomic.h> /* For atomic_cmpxchg */ #include <asm-generic/stack.h> #include <asm-generic/current.h> +#include "internal.h" #define RT_PRINT_BUFFER_ENV "RT_PRINT_BUFFER" #define RT_PRINT_DEFAULT_BUFFER 16*1024 @@ -666,7 +667,7 @@ static void forked_child_init(void) spawn_printer_thread(); } -static __attribute__ ((constructor)) void __rt_print_init(void) +void cobalt_print_init(void) { const char *value_str; unsigned long long period; @@ -740,7 +741,7 @@ static __attribute__ ((constructor)) void __rt_print_init(void) xnarch_atomic_set(&pool_bitmap[i], ~0UL); if (buffers_count % BITS_PER_LONG) xnarch_atomic_set(&pool_bitmap[i], - (1UL << (buffers_count % BITS_PER_LONG)) - 1); + (1UL << (buffers_count % BITS_PER_LONG)) - 1); for (i = 0; i < buffers_count; i++) { struct print_buffer *buffer = @@ -761,9 +762,11 @@ static __attribute__ ((constructor)) void __rt_print_init(void) spawn_printer_thread(); pthread_atfork(NULL, NULL, forked_child_init); + + rt_print_auto_init(1); } -static __attribute__ ((destructor)) void __rt_print_exit(void) +void cobalt_print_exit(void) { if (buffers) { /* Flush the buffers. Do not call print_buffers here diff --git a/lib/cobalt/sem_heap.c b/lib/cobalt/sem_heap.c index 5916732..3315387 100644 --- a/lib/cobalt/sem_heap.c +++ b/lib/cobalt/sem_heap.c @@ -14,6 +14,7 @@ #include <asm/xenomai/syscall.h> #include <asm-generic/sem_heap.h> #include <asm-generic/current.h> +#include "internal.h" #define PRIVATE 0 #define SHARED 1 _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git