[Xenomai-core] RFC: use a pool of pre-allocated buffers in rt_printf
Hi, I would like to better integrate rtdk and the posix skin by forcibly wrapping the calls to malloc/free and also wrap printf to call rt_printf. However, currently, rt_printf can not really be used as a drop-in replacement of printf: - it is necessary to call rt_printf_auto_init, we can do it in the library init code; - the first rt_printf causes a memory allocation, so a potential switch to secondary mode, which is what using rt_printf was trying to avoid in the first place. In order to solve this second issue, and to avoid forcibly creating a buffer for each thread, which would be wasteful, here is a patch, which, following an idea of Philippe, creates a pool of pre-allocated buffers. The pool is handled in a lockless fashion, using xnarch_atomic_cmpxchg (so, will only work with CONFIG_XENO_FASTSYNCH). diff --git a/src/rtdk/rt_print.c b/src/rtdk/rt_print.c index 93b711a..2ed2209 100644 --- a/src/rtdk/rt_print.c +++ b/src/rtdk/rt_print.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #define RT_PRINT_BUFFER_ENV"RT_PRINT_BUFFER" #define RT_PRINT_DEFAULT_BUFFER16*1024 @@ -37,6 +39,9 @@ #define RT_PRINT_PERIOD_ENV"RT_PRINT_PERIOD" #define RT_PRINT_DEFAULT_PERIOD100 /* ms */ +#define RT_PRINT_BUFFERS_COUNT_ENV "RT_PRINT_BUFFERS_COUNT" +#define RT_PRINT_DEFAULT_BUFFERS_COUNT 4 + #define RT_PRINT_LINE_BREAK256 #define RT_PRINT_SYSLOG_STREAM NULL @@ -63,6 +68,9 @@ struct print_buffer { * caching on SMP. */ off_t read_pos; +#ifdef CONFIG_XENO_FASTSYNCH + struct print_buffer *pool_next; +#endif /* CONFIG_XENO_FASTSYNCH */ }; static struct print_buffer *first_buffer; @@ -75,6 +83,17 @@ static pthread_mutex_t buffer_lock; static pthread_cond_t printer_wakeup; static pthread_key_t buffer_key; static pthread_t printer_thread; +#ifdef CONFIG_XENO_FASTSYNCH +static xnarch_atomic_t buffer_pool; +static unsigned pool_capacity; +static xnarch_atomic_t pool_count; + +#define buf_pool_set(buf) xnarch_atomic_set(&buffer_pool, (unsigned long)buf) +#define buf_pool_get() (struct print_buffer *)xnarch_atomic_get(&buffer_pool) +#define buf_pool_cmpxchg(oldval, newval) \ + ((struct print_buffer *)xnarch_atomic_cmpxchg \ +(&buffer_pool, (unsigned long)oldval, (unsigned long)newval)) +#endif /* CONFIG_XENO_FASTSYNCH */ static void cleanup_buffer(struct print_buffer *buffer); static void print_buffers(void); @@ -243,43 +262,28 @@ static void set_buffer_name(struct print_buffer *buffer, const char *name) } } -int rt_print_init(size_t buffer_size, const char *buffer_name) +static struct print_buffer *rt_print_init_inner(size_t size) { - struct print_buffer *buffer = pthread_getspecific(buffer_key); - size_t size = buffer_size; - - if (!size) - size = default_buffer_size; - else if (size < RT_PRINT_LINE_BREAK) - return EINVAL; + struct print_buffer *buffer; - if (buffer) { - /* Only set name if buffer size is unchanged or default */ - if (size == buffer->size || !buffer_size) { - set_buffer_name(buffer, buffer_name); - return 0; - } - cleanup_buffer(buffer); - } + assert_nrt(); buffer = malloc(sizeof(*buffer)); if (!buffer) - return ENOMEM; + return NULL; buffer->ring = malloc(size); if (!buffer->ring) { free(buffer); - return ENOMEM; + return NULL; } + buffer->size = size; + memset(buffer->ring, 0, size); buffer->read_pos = 0; buffer->write_pos = 0; - buffer->size = size; - - set_buffer_name(buffer, buffer_name); - buffer->prev = NULL; pthread_mutex_lock(&buffer_lock); @@ -294,6 +298,52 @@ int rt_print_init(size_t buffer_size, const char *buffer_name) pthread_mutex_unlock(&buffer_lock); + return buffer; +} + +int rt_print_init(size_t buffer_size, const char *buffer_name) +{ + struct print_buffer *buffer = pthread_getspecific(buffer_key); + size_t size = buffer_size; + + if (!size) + size = default_buffer_size; + else if (size < RT_PRINT_LINE_BREAK) + return EINVAL; + + if (buffer) { + /* Only set name if buffer size is unchanged or default */ + if (size == buffer->size || !buffer_size) { + set_buffer_name(buffer, buffer_name); + return 0; + } + cleanup_buffer(buffer); + buffer = NULL; + } + +#ifdef CONFIG_XENO_FASTSYNCH + if (xeno_get_current() != XN_NO_HANDLE && + !(xeno_get_current_mode() & XNRELAX) && buf_pool_get()) { + struct print_buff
Re: [Xenomai-core] [RFC] Getting rid of the NMI latency watchdog
On Wed, 2011-06-22 at 19:16 +0200, Gilles Chanteperdrix wrote: > On 05/19/2011 10:29 PM, Philippe Gerum wrote: > > On Thu, 2011-05-19 at 20:36 +0200, Jan Kiszka wrote: > >> On 2011-05-19 20:15, Gilles Chanteperdrix wrote: > >>> On 05/19/2011 03:58 PM, Philippe Gerum wrote: > For this reason, I'm considering issuing a patch for a complete removal > of the NMI latency watchdog code in Xenomai 2.6.x, disabling the feature > for 2.6.38 kernels and above in 2.5.x. > > Comments welcome. > >>> > >>> I am in the same case as you: I no longer use Xeno's NMI watchdog, so I > >>> agree to get rid of it. > >> > >> Yeah. The last time we wanted to use it get more information about a > >> hard hang, the CPU we used was not supported. > >> > >> Philippe, did you test the Linux watchdog already, if it generate proper > >> results on artificial Xenomai lockups on a single core? > > > > This works provided we tell the pipeline to enter printk-sync mode when > > the watchdog kicks. So I'd say that we could probably do a better job in > > making the pipeline core smarter wrt NMI watchdog context handling than > > asking Xenomai to dup the mainline code for having its own NMI handling. > > If nobody disagrees, I am removing this code from -head. Now. > Ack. -- Philippe. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [RFC] Getting rid of the NMI latency watchdog
On 05/19/2011 10:29 PM, Philippe Gerum wrote: > On Thu, 2011-05-19 at 20:36 +0200, Jan Kiszka wrote: >> On 2011-05-19 20:15, Gilles Chanteperdrix wrote: >>> On 05/19/2011 03:58 PM, Philippe Gerum wrote: For this reason, I'm considering issuing a patch for a complete removal of the NMI latency watchdog code in Xenomai 2.6.x, disabling the feature for 2.6.38 kernels and above in 2.5.x. Comments welcome. >>> >>> I am in the same case as you: I no longer use Xeno's NMI watchdog, so I >>> agree to get rid of it. >> >> Yeah. The last time we wanted to use it get more information about a >> hard hang, the CPU we used was not supported. >> >> Philippe, did you test the Linux watchdog already, if it generate proper >> results on artificial Xenomai lockups on a single core? > > This works provided we tell the pipeline to enter printk-sync mode when > the watchdog kicks. So I'd say that we could probably do a better job in > making the pipeline core smarter wrt NMI watchdog context handling than > asking Xenomai to dup the mainline code for having its own NMI handling. If nobody disagrees, I am removing this code from -head. Now. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] User space stack pre-faulting
On 2011-06-22 12:56, Gilles Chanteperdrix wrote: > On 06/22/2011 12:55 PM, Jan Kiszka wrote: >> On 2011-06-22 12:36, Gilles Chanteperdrix wrote: >>> On 06/22/2011 11:26 AM, Jan Kiszka wrote: Hi Gilles, do you remember reasons for only pre-faulting the main thread's stack? The desire to avoid wasting resources by forcing all stacks into memory? I've the requirement on my table to provide a generic solution of all shadow threads. I think this should be possible using pthread_getattr_np and walking the stack page-wise, but I may miss some pitfall. >>> >>> Last time I checked, only the main thread stack was mapped on demand. >>> Other threads have mmaped stacks, which are made present by mlockall, >>> so, do not need faulting. >> >> That's definitely not the case in general. Customer has just confirmed >> that pre-faulting thread stacks avoids first-access domain switches. > > self-contained test case please. Yes, will check this. Currently distracted again by a higher prio oops :-/. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] User space stack pre-faulting
On 06/22/2011 12:55 PM, Jan Kiszka wrote: > On 2011-06-22 12:36, Gilles Chanteperdrix wrote: >> On 06/22/2011 11:26 AM, Jan Kiszka wrote: >>> Hi Gilles, >>> >>> do you remember reasons for only pre-faulting the main thread's stack? >>> The desire to avoid wasting resources by forcing all stacks into memory? >>> >>> I've the requirement on my table to provide a generic solution of all >>> shadow threads. I think this should be possible using pthread_getattr_np >>> and walking the stack page-wise, but I may miss some pitfall. >> >> Last time I checked, only the main thread stack was mapped on demand. >> Other threads have mmaped stacks, which are made present by mlockall, >> so, do not need faulting. > > That's definitely not the case in general. Customer has just confirmed > that pre-faulting thread stacks avoids first-access domain switches. self-contained test case please. > > Jan > -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] User space stack pre-faulting
On 2011-06-22 12:36, Gilles Chanteperdrix wrote: > On 06/22/2011 11:26 AM, Jan Kiszka wrote: >> Hi Gilles, >> >> do you remember reasons for only pre-faulting the main thread's stack? >> The desire to avoid wasting resources by forcing all stacks into memory? >> >> I've the requirement on my table to provide a generic solution of all >> shadow threads. I think this should be possible using pthread_getattr_np >> and walking the stack page-wise, but I may miss some pitfall. > > Last time I checked, only the main thread stack was mapped on demand. > Other threads have mmaped stacks, which are made present by mlockall, > so, do not need faulting. That's definitely not the case in general. Customer has just confirmed that pre-faulting thread stacks avoids first-access domain switches. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] User space stack pre-faulting
On 06/22/2011 11:26 AM, Jan Kiszka wrote: > Hi Gilles, > > do you remember reasons for only pre-faulting the main thread's stack? > The desire to avoid wasting resources by forcing all stacks into memory? > > I've the requirement on my table to provide a generic solution of all > shadow threads. I think this should be possible using pthread_getattr_np > and walking the stack page-wise, but I may miss some pitfall. Last time I checked, only the main thread stack was mapped on demand. Other threads have mmaped stacks, which are made present by mlockall, so, do not need faulting. -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] User space stack pre-faulting
Hi Gilles, do you remember reasons for only pre-faulting the main thread's stack? The desire to avoid wasting resources by forcing all stacks into memory? I've the requirement on my table to provide a generic solution of all shadow threads. I think this should be possible using pthread_getattr_np and walking the stack page-wise, but I may miss some pitfall. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core