[Xenomai-core] RFC: use a pool of pre-allocated buffers in rt_printf

2011-06-22 Thread Gilles Chanteperdrix

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

2011-06-22 Thread Philippe Gerum
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

2011-06-22 Thread Gilles Chanteperdrix
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

2011-06-22 Thread Jan Kiszka
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

2011-06-22 Thread Gilles Chanteperdrix
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

2011-06-22 Thread Jan Kiszka
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

2011-06-22 Thread Gilles Chanteperdrix
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

2011-06-22 Thread Jan Kiszka
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