* [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ?
@ 2007-11-19 13:43 Roderik.Wildenburg
2007-11-19 14:35 ` Philippe Gerum
0 siblings, 1 reply; 13+ messages in thread
From: Roderik.Wildenburg @ 2007-11-19 13:43 UTC (permalink / raw)
To: xenomai
[-- Attachment #1: Type: text/plain, Size: 1078 bytes --]
When running the attached programm for a while I get an "Cannot allocate memory" error with the function rt_queue_write.
I can´t see any obvious mistake in my code, so I don´t have an simple explanation for this behavior but just a suspicion (see below). Could somebody be so kind to try to reproduce this problem, so I can determine whether this is a problem of my context or of xenomai.
I use Xenomai 2.3.2 with an 2.4.25 kernel on PPC.
Or, even better, could somebody explain to me the functionality of heap allocation of native queues. I have the impression the problem of my program results from some kind of heap fragmentation, as I write very differnt buffersizes to a quite small queue (see code line 59-62).
Thank you in advance and best regards
Roderik
MAN Roland Druckmaschinen AG
Vorsitzender des Aufsichtsrates: Hanno C. Fiedler
Vorstand: Gerd Finkbeiner (Vorsitzender), Dr. Ingo Koch, Dr. Markus Rall, Paul Steidle
Sitz der Gesellschaft: Offenbach am Main, Registergericht: Amtsgericht Offenbach HRB-Nr. 42592
USt-Ident-Nr. DE 250200933
[-- Attachment #2: qtest.c --]
[-- Type: application/octet-stream, Size: 2836 bytes --]
#include <stdio.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <errno.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <native/task.h>
#include <native/queue.h>
#define MAXLEN 1024 /* größer maximale Nachrichtenlänge */
#define CONTROLLER_WAIT 1500000000
RT_QUEUE qtest1q;
RT_TASK qtest1, qtest2;
void qtest1t(void)
{
ssize_t len;
static char buf[MAXLEN];
for (;;)
{
if ((len = rt_queue_read(&qtest1q, &buf, sizeof (buf), TM_INFINITE)) < 0)
{
printf("qtest1t: rt_queue_read failed with %d\n",len);
perror("perror qtest1t: rt_queue_read");
errno = -len, perror("perror2 qtest1t: rt_queue_read");
}
}
}
void qtest2t(void)
{
int ret, len;
RT_QUEUE_INFO qinfo;
static char buf[MAXLEN];
int zuf;
for (;;)
{
zuf=rand();
len= (int) ((float)((float)zuf/(float)RAND_MAX) * (float)(MAXLEN-10) + 2.0 );
printf("WriteQueue %d %d\n",len,zuf);
if ((ret = rt_queue_write(&qtest1q, &buf, len , Q_NORMAL)) < 0)
{
errno = -ret, perror("qtest2t: rt_queue_write error");
printf("Message size :%d return : %d\n",len, ret);
if( (ret=rt_queue_inquire(&qtest1q,&qinfo))<0)
{
printf("queue_inquire : %d\n",ret);
}
else
{
printf("---- %s NMsg:%d Size:%d used:%d\n",qinfo.name, qinfo.nmessages,qinfo.poolsize,qinfo.usedmem);
}
}
rt_task_sleep(CONTROLLER_WAIT);
}
}
int startqtest(void)
{
int err;
srand (time (0));
if(!rt_queue_bind(&qtest1q,"qtest1q",TM_NONBLOCK))
rt_queue_delete(&qtest1q);
if( (err = rt_queue_create(&qtest1q, "qtest1q", MAXLEN*10, 10, Q_FIFO)) != 0 )
printf("q_create qtest1q failed with %d\n",err);
err = rt_task_create(&qtest1, "qtest1t", 0, 50, 0); /* TCP/UDP-Sendeprozess */
if (!err)
rt_task_start(&qtest1, (void(*)(void *))qtest1t, NULL);
err = rt_task_create(&qtest2, "qtest2t", 0, 30, 0); /* TCP-Empfangsprozess */
if (!err)
rt_task_start(&qtest2, (void(*)(void *))qtest2t, NULL);
return(0);
}
int main (int ac, char *av[])
{
sigset_t mask;
int sig;
printf("qtest start !\n");
sleep(2);
sigemptyset(&mask);
sigaddset(&mask,SIGINT);
sigaddset(&mask,SIGTERM);
sigaddset(&mask,SIGHUP);
sigaddset(&mask,SIGALRM);
pthread_sigmask(SIG_BLOCK, &mask, NULL);
mlockall(MCL_CURRENT|MCL_FUTURE);
startqtest();
sigwait(&mask, &sig);
return 0;
}
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? 2007-11-19 13:43 [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? Roderik.Wildenburg @ 2007-11-19 14:35 ` Philippe Gerum 2007-11-19 15:11 ` Roderik.Wildenburg 0 siblings, 1 reply; 13+ messages in thread From: Philippe Gerum @ 2007-11-19 14:35 UTC (permalink / raw) To: Roderik.Wildenburg; +Cc: xenomai Roderik.Wildenburg@domain.hid wrote: > When running the attached programm for a while I get an "Cannot allocate memory" error with the function rt_queue_write. What is the exact size of the message rt_queue_write() fails to send, as displayed by your trace? > I can´t see any obvious mistake in my code, so I don´t have an simple explanation for this behavior but just a suspicion (see below). Could somebody be so kind to try to reproduce this problem, so I can determine whether this is a problem of my context or of xenomai. > I use Xenomai 2.3.2 with an 2.4.25 kernel on PPC. > > Or, even better, could somebody explain to me the functionality of heap allocation of native queues. Message buffers are simply obtained from a memory pool managed as a nucleus heap. rt_queue_write() allocates a message block from the pool to hold the emitted data, and pushes it to the pending message queue, rt_queue_read() then pops the next available message from this queue, copies the payload data to the user-space buffer, and frees the message block. I have the impression the problem of my program results from some kind of heap fragmentation, as I write very differnt buffersizes to a quite small queue (see code line 59-62). > It's unlikely, since the consumer thread has absolute priority (50) over the producer in your code (30); in such a case, the buffer pool should only have a single busy message block at any given time. You may want to display /proc/xenomai/registry/native/queues/qtest1q periodically, while your test program is running, and check the usedmem field. If it indeed decreases over time, then there is a memory leak somewhere. -- Philippe. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? 2007-11-19 14:35 ` Philippe Gerum @ 2007-11-19 15:11 ` Roderik.Wildenburg 2007-11-19 18:06 ` Philippe Gerum 0 siblings, 1 reply; 13+ messages in thread From: Roderik.Wildenburg @ 2007-11-19 15:11 UTC (permalink / raw) To: rpm; +Cc: xenomai > > When running the attached programm for a while I get an > "Cannot allocate memory" error with the function rt_queue_write. > > What is the exact size of the message rt_queue_write() fails > to send, as > displayed by your trace? Here is the output of my programm : WriteQueue 529 1116951692 WriteQueue 282 594405035 qtest2t: rt_queue_write error: Cannot allocate memory Message size :282 return : -12 ---- qtest1q NMsg:0 Size:12288 used:0 WriteQueue 612 1291961188 WriteQueue 765 1617804041 WriteQueue 842 1781076386 WriteQueue 263 553963391 qtest2t: rt_queue_write error: Cannot allocate memory Message size :263 return : -12 ---- qtest1q NMsg:0 Size:12288 used:0 WriteQueue 308 648658497 qtest2t: rt_queue_write error: Cannot allocate memory Message size :308 return : -12 ---- qtest1q NMsg:0 Size:12288 used:0 WriteQueue 394 830909457 qtest2t: rt_queue_write error: Cannot allocate memory Message size :394 return : -12 ---- qtest1q NMsg:0 Size:12288 used:0 WriteQueue 965 2040427517 WriteQueue 304 641396835 qtest2t: rt_queue_write error: Cannot allocate memory Message size :304 return : -12 ---- qtest1q NMsg:0 Size:12288 used:0 WriteQueue 697 1472466673 WriteQueue 543 1146244746 WriteQueue 253 531620889 qtest2t: rt_queue_write error: Cannot allocate memory Message size :253 return : -12 ---- qtest1q NMsg:0 Size:12288 used:0 WriteQueue 66 136664073 qtest2t: rt_queue_write error: Cannot allocate memory Message size :66 return : -12 ---- qtest1q NMsg:0 Size:12288 used:0 WriteQueue 456 962746131 qtest2t: rt_queue_write error: Cannot allocate memory Message size :456 return : -12 ---- qtest1q NMsg:0 Size:12288 used:0 As you can see I make a queue_inquire after the write fails and it allways says "No Messages" "No Used Memory". > > Message buffers are simply obtained from a memory pool managed as a > nucleus heap. rt_queue_write() allocates a message block from the pool > to hold the emitted data, and pushes it to the pending message queue, > rt_queue_read() then pops the next available message from this queue, > copies the payload data to the user-space buffer, and frees > the message > block. But the allocated block keeps bounded to a spezial block size and if some other blocksize is needed an other block is alloctated ? > > I have the impression the problem of my program results from some kind > of heap fragmentation, > as I write very differnt buffersizes to a quite small queue (see code > line 59-62). > > > > It's unlikely, since the consumer thread has absolute > priority (50) over > the producer in your code (30); in such a case, the buffer pool should > only have a single busy message block at any given time. As you can see by the queue_inquire output no messages is in the queue > > You may want to display /proc/xenomai/registry/native/queues/qtest1q > periodically, while your test program is running, and check > the usedmem > field. If it indeed decreases over time, then there is a memory leak > somewhere. > Again, the output from queue_inquire shows, there is no leak. MAN Roland Druckmaschinen AG Vorsitzender des Aufsichtsrates: Hanno C. Fiedler Vorstand: Gerd Finkbeiner (Vorsitzender), Dr. Ingo Koch, Dr. Markus Rall, Paul Steidle Sitz der Gesellschaft: Offenbach am Main, Registergericht: Amtsgericht Offenbach HRB-Nr. 42592 USt-Ident-Nr. DE 250200933 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? 2007-11-19 15:11 ` Roderik.Wildenburg @ 2007-11-19 18:06 ` Philippe Gerum 2007-11-20 8:51 ` Roderik.Wildenburg 0 siblings, 1 reply; 13+ messages in thread From: Philippe Gerum @ 2007-11-19 18:06 UTC (permalink / raw) To: Roderik.Wildenburg; +Cc: xenomai Roderik.Wildenburg@domain.hid wrote: > > But the allocated block keeps bounded to a spezial block size and if > some other > blocksize is needed an other block is alloctated ? > No more than one block is allocated at any given time in your example. This is expected due to the priority scheme your test undergoes. In any case, 282 bytes (+ a few bytes message header) should grab one 512-byte buffer here. For anything below the size of a logical page (4k in 2.3.x), the allocator picks the next power of 2 greater or equal to the requested size. 2.3.x is known to suffer a sub-optimal setting for the page size used in various internal heaps which has been fixed in v2.4, sometimes leading to a useless overhead caused by the heap's internal header. Still, in your case, and even with a 10k setting, you should have two 4k pages available, one being split in 8 x 512 byte blocks due to rt_queue_write() queuing a 282-byte block. And no more than one block among the eight available should be busy at any given time. What if you don't set any limit to the queue elements, i.e. passing Q_UNLIMITED instead of 10. Does this change the behaviour? -- Philippe. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? 2007-11-19 18:06 ` Philippe Gerum @ 2007-11-20 8:51 ` Roderik.Wildenburg 2007-11-20 13:59 ` Philippe Gerum 0 siblings, 1 reply; 13+ messages in thread From: Roderik.Wildenburg @ 2007-11-20 8:51 UTC (permalink / raw) To: rpm; +Cc: xenomai > > No more than one block is allocated at any given time in your example. > This is expected due to the priority scheme your test > undergoes. In any > case, 282 bytes (+ a few bytes message header) should grab > one 512-byte > buffer here. For anything below the size of a logical page (4k in > 2.3.x), the allocator picks the next power of 2 greater or > equal to the > requested size. Is it possible that a allocated block remembers the size he is allocated for and that the block is just usable for this size even after the block is freed ? > > What if you don't set any limit to the queue elements, i.e. passing > Q_UNLIMITED instead of 10. Does this change the behaviour? > This does not help. What helps is increasing the queue size to e.g. MAXLEN*100 = 200000 (rt_queue_create(&qtest1q, "qtest1q", MAXLEN*100, Q_UNLIMITED, Q_FIFO)) Could you please try to run my example on your machine, or are you shure, that this problem is specific to our platform ? Thank you for your help ! Best regards Roderik MAN Roland Druckmaschinen AG Vorsitzender des Aufsichtsrates: Hanno C. Fiedler Vorstand: Gerd Finkbeiner (Vorsitzender), Dr. Ingo Koch, Dr. Markus Rall, Paul Steidle Sitz der Gesellschaft: Offenbach am Main, Registergericht: Amtsgericht Offenbach HRB-Nr. 42592 USt-Ident-Nr. DE 250200933 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? 2007-11-20 8:51 ` Roderik.Wildenburg @ 2007-11-20 13:59 ` Philippe Gerum 2007-11-21 14:07 ` Roderik.Wildenburg 2007-11-23 17:08 ` Philippe Gerum 0 siblings, 2 replies; 13+ messages in thread From: Philippe Gerum @ 2007-11-20 13:59 UTC (permalink / raw) To: Roderik.Wildenburg; +Cc: xenomai Roderik.Wildenburg@domain.hid wrote: >> No more than one block is allocated at any given time in your example. >> This is expected due to the priority scheme your test >> undergoes. In any >> case, 282 bytes (+ a few bytes message header) should grab >> one 512-byte >> buffer here. For anything below the size of a logical page (4k in >> 2.3.x), the allocator picks the next power of 2 greater or >> equal to the >> requested size. > > Is it possible that a allocated block remembers the size he is allocated > for > and that the block is just usable for this size even after the block is > freed ? > The block will belong to a 512-byte pool until all the blocks from the same pool are free, in which case the entire page the pool sits on will be moved to a free page list, and recycled for blocks of any size. >> What if you don't set any limit to the queue elements, i.e. passing >> Q_UNLIMITED instead of 10. Does this change the behaviour? >> > > This does not help. What helps is increasing the queue size to e.g. > MAXLEN*100 = 200000 > (rt_queue_create(&qtest1q, "qtest1q", MAXLEN*100, Q_UNLIMITED, Q_FIFO)) > > Could you please try to run my example on your machine, or are you > shure, that this > problem is specific to our platform ? Thank you for your help ! This is likely not a platform specific issue. You may want to run your small test on v2.4-rc6 on your side. > > Best regards > Roderik > > MAN Roland Druckmaschinen AG > Vorsitzender des Aufsichtsrates: Hanno C. Fiedler > Vorstand: Gerd Finkbeiner (Vorsitzender), Dr. Ingo Koch, Dr. Markus Rall, Paul Steidle > Sitz der Gesellschaft: Offenbach am Main, Registergericht: Amtsgericht Offenbach HRB-Nr. 42592 > USt-Ident-Nr. DE 250200933 > -- Philippe. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? 2007-11-20 13:59 ` Philippe Gerum @ 2007-11-21 14:07 ` Roderik.Wildenburg 2007-11-23 17:08 ` Philippe Gerum 1 sibling, 0 replies; 13+ messages in thread From: Roderik.Wildenburg @ 2007-11-21 14:07 UTC (permalink / raw) To: rpm; +Cc: xenomai > > > > Could you please try to run my example on your machine, or are you > > shure, that this > > problem is specific to our platform ? Thank you for your help ! > > This is likely not a platform specific issue. You may want to run your > small test on v2.4-rc6 on your side. > If you think so, have you been able do reproduce the problem ? Xenomai 2.4.-rc6 did not make any differenece as you can see from the following output : (/proc/xenomai/version says 2.4-rc6) WriteQueue 716 1512231002 WriteQueue 1007 2129556885 WriteQueue 227 476645315 WriteQueue 615 1299758337 WriteQueue 582 1228925036 WriteQueue 449 947777523 WriteQueue 270 567867246 WriteQueue 752 1589385927 WriteQueue 958 2026690827 WriteQueue 64 131957776 qtest2t: rt_queue_write error: Cannot allocate memory Message size :64 return : -12 ---- qtest1q NMsg:0 Size:12288 used:0 WriteQueue 849 1795696479 WriteQueue 939 1985770412 WriteQueue 234 491648752 WriteQueue 307 646407494 WriteQueue 1012 2140941003 qtest2t: rt_queue_write error: Cannot allocate memory Message size :1012 return : -12 ---- qtest1q NMsg:0 Size:12288 used:0 WriteQueue 610 1289683840 WriteQueue 313 660303794 WriteQueue 472 996746841 So, what can we do now ? Best regards Roderik MAN Roland Druckmaschinen AG Vorsitzender des Aufsichtsrates: Hanno C. Fiedler Vorstand: Gerd Finkbeiner (Vorsitzender), Dr. Ingo Koch, Dr. Markus Rall, Paul Steidle Sitz der Gesellschaft: Offenbach am Main, Registergericht: Amtsgericht Offenbach HRB-Nr. 42592 USt-Ident-Nr. DE 250200933 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? 2007-11-20 13:59 ` Philippe Gerum 2007-11-21 14:07 ` Roderik.Wildenburg @ 2007-11-23 17:08 ` Philippe Gerum 2007-11-28 9:21 ` Roderik.Wildenburg 1 sibling, 1 reply; 13+ messages in thread From: Philippe Gerum @ 2007-11-23 17:08 UTC (permalink / raw) To: Roderik.Wildenburg; +Cc: xenomai [-- Attachment #1: Type: text/plain, Size: 2623 bytes --] Philippe Gerum wrote: > Roderik.Wildenburg@domain.hid wrote: >>> No more than one block is allocated at any given time in your example. >>> This is expected due to the priority scheme your test >>> undergoes. In any >>> case, 282 bytes (+ a few bytes message header) should grab >>> one 512-byte >>> buffer here. For anything below the size of a logical page (4k in >>> 2.3.x), the allocator picks the next power of 2 greater or >>> equal to the >>> requested size. >> Is it possible that a allocated block remembers the size he is allocated >> for >> and that the block is just usable for this size even after the block is >> freed ? >> > > The block will belong to a 512-byte pool until all the blocks from the > same pool are free, in which case the entire page the pool sits on will > be moved to a free page list, and recycled for blocks of any size. > Did I say that? Mmff..., I lied, then. As a matter of fact, the issue you face is due to pages holding blocks of size <= pagesize * 2 (i.e. 8k in our case), lingering in the free bucket queues, instead of being moved to the global free page list. Now, the human readable form of the explanation: - you ask for a 10kb heap, which is silently rounded to 12k in order to cope with the 4k alignment constraint we have on shareable heaps (userland heaps are always shareable). - 12kb heap means 3 * 4k pages available in the global free list. - your application allocates randomly-sized blocks, each new size rounded to the next power of 2 grabs one page from the global pool to hold blocks of the same size, but unfortunately, the heap manager does _not_ release it back to the free list when the last block laid on the page is freed. - after more than 3 different allocation sizes (e.g. 2^3, 2^5 and 2^8) have been requested to the heap manager, it fails honoring a fourth one. I would rather consider this as a bug, since putting a lot of pressure on a single block size would beget the same problem (i.e. no need for a funky randomized allocation pattern here), with a global free page list being emptied over time, and all pages lingering inside some private (per-block size) bucket queue. The attached patch fixed the issue (against v2.4-rc6). I'm still pondering whether v2.3.x should get this update too, due to the variations this patch introduces wrt memory consumption for the heap meta-data. Still, it also fixes a miscalculated overhead value for such meta-data in all previous releases, so merging it would make sense. You can give it a try on v2.3.x, you would just have to fix a trivial hunk manually on include/nucleus/heap.h. -- Philippe. [-- Attachment #2: heap-fix-bucket-page-recycling.patch --] [-- Type: text/x-patch, Size: 14995 bytes --] Index: include/nucleus/heap.h =================================================================== --- include/nucleus/heap.h (revision 3204) +++ include/nucleus/heap.h (working copy) @@ -47,7 +47,7 @@ #if defined(__KERNEL__) || defined(__XENO_SIM__) #define XNHEAP_MINLOG2 3 -#define XNHEAP_MAXLOG2 22 +#define XNHEAP_MAXLOG2 22 /* Must hold pagemap::bcount objects */ #define XNHEAP_MINALLOCSZ (1 << XNHEAP_MINLOG2) #define XNHEAP_MINALIGNSZ (1 << 4) /* i.e. 16 bytes */ #define XNHEAP_NBUCKETS (XNHEAP_MAXLOG2 - XNHEAP_MINLOG2 + 2) @@ -67,7 +67,10 @@ memlim, /* Memory limit of page array */ freelist; /* Head of the free page list */ - u_char pagemap[1]; /* Beginning of page map */ + struct xnpagemap { /* Beginning of page map */ + unsigned int type : 8; /* PFREE, PCONT, PLIST or log2 */ + unsigned int bcount : 24; /* Number of active blocks. */ + } pagemap[1]; } xnextent_t; @@ -101,18 +104,26 @@ extern xnheap_t kheap; -#define xnheap_extentsize(heap) ((heap)->extentsize) -#define xnheap_page_size(heap) ((heap)->pagesize) -#define xnheap_page_count(heap) ((heap)->npages) -#define xnheap_usable_mem(heap) ((heap)->maxcont * countq(&(heap)->extents)) -#define xnheap_used_mem(heap) ((heap)->ubytes) -#define xnheap_max_contiguous(heap) ((heap)->maxcont) -#define xnheap_overhead(hsize,psize) \ -((sizeof(xnextent_t) + (((hsize) - sizeof(xnextent_t)) / (psize)) + \ - XNHEAP_MINALIGNSZ - 1) & ~(XNHEAP_MINALIGNSZ - 1)) -/* The alignment value must be a power of 2 */ -#define xnheap_align(size,al) (((size)+(al)-1)&(~((al)-1))) +#define xnheap_extentsize(heap) ((heap)->extentsize) +#define xnheap_page_size(heap) ((heap)->pagesize) +#define xnheap_page_count(heap) ((heap)->npages) +#define xnheap_usable_mem(heap) ((heap)->maxcont * countq(&(heap)->extents)) +#define xnheap_used_mem(heap) ((heap)->ubytes) +#define xnheap_max_contiguous(heap) ((heap)->maxcont) +static inline size_t xnheap_align(size_t size, size_t al) +{ + /* The alignment value must be a power of 2 */ + return ((size+al-1)&(~(al-1))); +} + +static inline size_t xnheap_overhead(size_t hsize, size_t psize) +{ + size_t m = psize / sizeof(struct xnpagemap); + size_t q = ((hsize - sizeof(xnextent_t)) * m) / (m + 1); + return xnheap_align(hsize - q, XNHEAP_MINALIGNSZ); +} + #define xnmalloc(size) xnheap_alloc(&kheap,size) #define xnfree(ptr) xnheap_free(&kheap,ptr) #define xnfreesync() xnheap_finalize_free(&kheap) @@ -132,12 +143,14 @@ * match the requested size. Using a small page size for large * single-block heaps might reserve a lot of useless page map * memory, but this should never get pathological anyway, - * since we are only consuming 1 byte per page. + * since we only consume 4 bytes per page. */ if (hsize < 2 * psize) hsize = 2 * psize; - hsize = xnheap_align(hsize,psize) + xnheap_overhead(hsize,psize); - return xnheap_align(hsize,psize); + else + hsize = xnheap_align(hsize, psize); + hsize += xnheap_overhead(hsize, psize); + return xnheap_align(hsize, psize); } #ifdef __cplusplus Index: ksrc/nucleus/heap.c =================================================================== --- ksrc/nucleus/heap.c (revision 3204) +++ ksrc/nucleus/heap.c (working copy) @@ -66,6 +66,7 @@ #include <nucleus/pod.h> #include <nucleus/thread.h> #include <nucleus/heap.h> +#include <nucleus/assert.h> #include <asm/xenomai/bits/heap.h> xnheap_t kheap; /* System heap */ @@ -85,11 +86,13 @@ for (n = 0, freepage = extent->membase; n < lastpgnum; n++, freepage += heap->pagesize) { *((caddr_t *) freepage) = freepage + heap->pagesize; - extent->pagemap[n] = XNHEAP_PFREE; + extent->pagemap[n].type = XNHEAP_PFREE; + extent->pagemap[n].bcount = 0; } *((caddr_t *) freepage) = NULL; - extent->pagemap[lastpgnum] = XNHEAP_PFREE; + extent->pagemap[lastpgnum].type = XNHEAP_PFREE; + extent->pagemap[lastpgnum].bcount = 0; extent->memlim = freepage + heap->pagesize; /* The first page starts the free list of a new extent. */ @@ -118,12 +121,17 @@ * * @param heapsize The size in bytes of the initial extent pointed at * by @a heapaddr. @a heapsize must be a multiple of pagesize and - * lower than 16 Mbytes. @a heapsize must be large enough to contain - * an internal header. The following formula gives the size of this - * header:\n - * hdrsize = (sizeof(xnextent_t) + ((heapsize - - * sizeof(xnextent_t))) / (pagesize + 1) + 15) & ~15.\n + * lower than 16 Mbytes. @a heapsize must be large enough to contain a + * dynamically-sized internal header. The following formula gives the + * size of this header:\n * + * H = heapsize, P=pagesize, M=sizeof(struct pagemap), E=sizeof(xnextent_t)\n + * hdrsize = ((H - E) * M) / (M + 1)\n + * + * This value is then aligned on the next 16-byte boundary. The + * routine xnheap_overhead() computes the corrected heap size + * according to the previous formula. + * * @param pagesize The size in bytes of the fundamental memory page * which will be used to subdivide the heap internally. Choosing the * right page size is important regarding performance and memory @@ -174,30 +182,37 @@ heapsize > XNHEAP_MAXEXTSZ || (heapsize & (pagesize - 1)) != 0) return -EINVAL; - /* Determine the page map overhead inside the given extent - size. We need to reserve a byte in a page map for each page - which is addressable into this extent. The page map is itself - stored in the extent space, right after the static part of its - header, and before the first allocatable page. - pmapsize = (heapsize - sizeof(xnextent_t)) / pagesize; */ - - /* The overall header size is: static_part + page_map rounded to - the minimum alignment size. */ + /* + * Determine the page map overhead inside the given extent + * size. We need to reserve 4 bytes in a page map for each + * page which is addressable into this extent. The page map is + * itself stored in the extent space, right after the static + * part of its header, and before the first allocatable page. + * pmapsize = (heapsize - sizeof(xnextent_t)) / pagesize * + * sizeof(struct xnpagemap). The overall header size is: + * static_part + pmapsize rounded to the minimum alignment + * size. + */ hdrsize = xnheap_overhead(heapsize, pagesize); - /* An extent must contain at least two addressable pages to cope - with allocation sizes between pagesize and 2 * pagesize. */ - if (hdrsize + 2 * pagesize > heapsize) - return -EINVAL; - /* Compute the page shiftmask from the page size (i.e. log2 value). */ - for (pageshift = 0, shiftsize = pagesize; shiftsize > 1; shiftsize >>= 1, pageshift++) ; /* Loop */ + for (pageshift = 0, shiftsize = pagesize; + shiftsize > 1; shiftsize >>= 1, pageshift++) + ; /* Loop */ heap->pagesize = pagesize; heap->pageshift = pageshift; heap->extentsize = heapsize; heap->hdrsize = hdrsize; heap->npages = (heapsize - hdrsize) >> pageshift; + + /* + * An extent must contain at least two addressable pages to cope + * with allocation sizes between pagesize and 2 * pagesize. + */ + if (heap->npages < 2) + return -EINVAL; + heap->ubytes = 0; heap->maxcont = heap->npages * pagesize; heap->idleq = NULL; @@ -291,16 +306,17 @@ while (holder != NULL) { extent = link2extent(holder); - freepage = extent->freelist; while (freepage != NULL) { headpage = freepage; freecont = 0; - /* Search for a range of contiguous pages in the free page - list of the current extent. The range must be 'bsize' - long. */ + /* + * Search for a range of contiguous pages in + * the free page list of the current + * extent. The range must be 'bsize' long. + */ do { lastpage = freepage; freepage = *((caddr_t *) freepage); @@ -310,9 +326,11 @@ && freecont < bsize); if (freecont >= bsize) { - /* Ok, got it. Just update the extent's free page - list, then proceed to the next step. */ - + /* + * Ok, got it. Just update the free + * page list, then proceed to the next + * step. + */ if (headpage == extent->freelist) extent->freelist = *((caddr_t *) lastpage); @@ -325,7 +343,6 @@ freehead = lastpage; } - holder = nextq(&heap->extents, holder); } @@ -353,19 +370,24 @@ pagenum = (headpage - extent->membase) >> heap->pageshift; - /* Update the extent's page map. If log2size is non-zero - (i.e. bsize <= 2 * pagesize), store it in the first page's slot - to record the exact block size (which is a power of - two). Otherwise, store the special marker XNHEAP_PLIST, - indicating the start of a block whose size is a multiple of the - standard page size, but not necessarily a power of two. In any - case, the following pages slots are marked as 'continued' - (PCONT). */ + /* + * Update the page map. If log2size is non-zero (i.e. bsize + * <= 2 * pagesize), store it in the first page's slot to + * record the exact block size (which is a power of + * two). Otherwise, store the special marker XNHEAP_PLIST, + * indicating the start of a block whose size is a multiple of + * the standard page size, but not necessarily a power of two. + * In any case, the following pages slots are marked as + * 'continued' (PCONT). + */ - extent->pagemap[pagenum] = log2size ? : XNHEAP_PLIST; + extent->pagemap[pagenum].type = log2size ? : XNHEAP_PLIST; + extent->pagemap[pagenum].bcount = 1; - for (pagecont = bsize >> heap->pageshift; pagecont > 1; pagecont--) - extent->pagemap[pagenum + pagecont - 1] = XNHEAP_PCONT; + for (pagecont = bsize >> heap->pageshift; pagecont > 1; pagecont--) { + extent->pagemap[pagenum + pagecont - 1].type = XNHEAP_PCONT; + extent->pagemap[pagenum + pagecont - 1].bcount = 0; + } return headpage; } @@ -404,6 +426,9 @@ void *xnheap_alloc(xnheap_t *heap, u_long size) { + xnholder_t *holder; + xnextent_t *extent; + u_long pagenum; caddr_t block; u_long bsize; int log2size; @@ -442,7 +467,9 @@ /* Find the first power of two greater or equal to the rounded size. The log2 value of this size is also computed. */ - for (bsize = (1 << XNHEAP_MINLOG2), log2size = XNHEAP_MINLOG2; bsize < size; bsize <<= 1, log2size++) ; /* Loop */ + for (bsize = (1 << XNHEAP_MINLOG2), log2size = XNHEAP_MINLOG2; + bsize < size; bsize <<= 1, log2size++) + ; /* Loop */ xnlock_get_irqsave(&heap->lock, s); @@ -450,9 +477,29 @@ if (block == NULL) { block = get_free_range(heap, bsize, log2size); - if (block == NULL) goto release_and_exit; + } else { + /* + * If only we had all pages sitting on + * pagesize boundaries, we could use a trivial + * address masking to compute the address of + * the containing page, but we can't assume + * that for now. Oh, well... + */ + for (holder = getheadq(&heap->extents), extent = NULL; + holder != NULL; holder = nextq(&heap->extents, holder)) { + extent = link2extent(holder); + if ((caddr_t) block >= extent->membase && + (caddr_t) block < extent->memlim) + break; + } + XENO_ASSERT(NUCLEUS, extent != NULL, + xnpod_fatal("Cannot determine source extent for block %p (heap %p)?!", + block, heap); + ); + pagenum = ((caddr_t) block - extent->membase) >> heap->pageshift; + ++extent->pagemap[pagenum].bcount; } heap->buckets[log2size - XNHEAP_MINLOG2] = *((caddr_t *) block); @@ -534,7 +581,6 @@ for (holder = getheadq(&heap->extents); holder != NULL; holder = nextq(&heap->extents, holder)) { extent = link2extent(holder); - if ((caddr_t) block >= extent->membase && (caddr_t) block < extent->memlim) break; @@ -551,7 +597,7 @@ ((caddr_t) block - (extent->membase + (pagenum << heap->pageshift))); - switch (extent->pagemap[pagenum]) { + switch (extent->pagemap[pagenum].type) { case XNHEAP_PFREE: /* Unallocated page? */ case XNHEAP_PCONT: /* Not a range heading page? */ @@ -571,11 +617,13 @@ npages = 1; while (npages < heap->npages && - extent->pagemap[pagenum + npages] == XNHEAP_PCONT) + extent->pagemap[pagenum + npages].type == XNHEAP_PCONT) npages++; bsize = npages * heap->pagesize; + free_page_list: + /* Link all freed pages in a single sub-list. */ for (freepage = (caddr_t) block, @@ -583,15 +631,20 @@ freepage < tailpage; freepage += heap->pagesize) *((caddr_t *) freepage) = freepage + heap->pagesize; + free_pages: + /* Mark the released pages as free in the extent's page map. */ for (pagecont = 0; pagecont < npages; pagecont++) - extent->pagemap[pagenum + pagecont] = XNHEAP_PFREE; + extent->pagemap[pagenum + pagecont].type = XNHEAP_PFREE; /* Return the sub-list to the free page list, keeping an increasing address order to favor coalescence. */ - for (nextpage = extent->freelist, lastpage = NULL; nextpage != NULL && nextpage < (caddr_t) block; lastpage = nextpage, nextpage = *((caddr_t *) nextpage)) ; /* Loop */ + for (nextpage = extent->freelist, lastpage = NULL; + nextpage != NULL && nextpage < (caddr_t) block; + lastpage = nextpage, nextpage = *((caddr_t *) nextpage)) + ; /* Loop */ *((caddr_t *) tailpage) = nextpage; @@ -599,12 +652,11 @@ *((caddr_t *) lastpage) = (caddr_t) block; else extent->freelist = (caddr_t) block; - break; default: - log2size = extent->pagemap[pagenum]; + log2size = extent->pagemap[pagenum].type; bsize = (1 << log2size); if ((boffset & (bsize - 1)) != 0) /* Not a block start? */ @@ -613,6 +665,23 @@ if (ckfn && (err = ckfn(block)) != 0) goto unlock_and_fail; + /* + * Return the page to the free list if we've just + * freed its last busy block. Pages from multi-page + * blocks are always pushed to the free list (bcount + * value for the heading page is always 1). + */ + + if (unlikely(--extent->pagemap[pagenum].bcount == 0)) { + heap->buckets[log2size - XNHEAP_MINLOG2] = NULL; + npages = bsize >> heap->pageshift; + if (likely(npages <= 1)) { + tailpage = block; + goto free_pages; + } + goto free_page_list; + } + /* Return the block to the bucketed memory space. */ *((caddr_t *) block) = heap->buckets[log2size - XNHEAP_MINLOG2]; @@ -790,7 +859,6 @@ for (holder = getheadq(&heap->extents); holder != NULL; holder = nextq(&heap->extents, holder)) { extent = link2extent(holder); - if ((caddr_t) block >= extent->membase && (caddr_t) block < extent->memlim) break; @@ -804,11 +872,11 @@ boffset = ((caddr_t) block - (extent->membase + (pagenum << heap->pageshift))); - ptype = extent->pagemap[pagenum]; + ptype = extent->pagemap[pagenum].type; if (ptype == XNHEAP_PFREE || /* Unallocated page? */ ptype == XNHEAP_PCONT) /* Not a range heading page? */ - bad_block: + bad_block: err = -EINVAL; xnlock_put_irqrestore(&heap->lock, s); ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? 2007-11-23 17:08 ` Philippe Gerum @ 2007-11-28 9:21 ` Roderik.Wildenburg 2007-11-28 9:43 ` Philippe Gerum 0 siblings, 1 reply; 13+ messages in thread From: Roderik.Wildenburg @ 2007-11-28 9:21 UTC (permalink / raw) To: rpm; +Cc: xenomai Thank you. Good work ! I applied your patch to 2.3.2 and, as far as I can see, the allocation problem does not accur anymore. (please se my insertions below) > Now, the human readable form of the explanation: > - you ask for a 10kb heap, which is silently rounded to 12k > in order to > cope with the 4k alignment constraint we have on shareable heaps > (userland heaps are always shareable). > - 12kb heap means 3 * 4k pages available in the global free list. > - your application allocates randomly-sized blocks, each new size > rounded to the next power of 2 grabs one page from the global pool to > hold blocks of the same size, but unfortunately, the heap manager does > _not_ release it back to the free list when the last block laid on the > page is freed. Thank you for your explanation, I thought it must be something like this (block remembers what size ist as been allocated for) > - after more than 3 different allocation sizes (e.g. 2^3, 2^5 and 2^8) > have been requested to the heap manager, it fails honoring a > fourth one. > I would rather consider this as a bug, since putting a lot of pressure > on a single block size would beget the same problem (i.e. no > need for a > funky randomized allocation pattern here), with a global free I think the test case isn´t very funky. Of course we did not write random buffer sizes (this was just implemted to get a simple test case), but we simple wrote some messages of different size to a queue and faced the allocation problem. Therefore, form our point of view, this is a bug. > page list > being emptied over time, and all pages lingering inside some private > (per-block size) bucket queue. > > The attached patch fixed the issue (against v2.4-rc6). I'm still > pondering whether v2.3.x should get this update too, due to the > variations this patch introduces wrt memory consumption for the heap I would appreciate it, if 2.3.x could be updated too, as we could carry on using 2.3.x (vendor libraries don´t need to be updated) Many thanks and best regards Roderik MAN Roland Druckmaschinen AG Vorsitzender des Aufsichtsrates: Hanno C. Fiedler Vorstand: Gerd Finkbeiner (Vorsitzender), Dr. Ingo Koch, Dr. Markus Rall, Paul Steidle Sitz der Gesellschaft: Offenbach am Main, Registergericht: Amtsgericht Offenbach HRB-Nr. 42592 USt-Ident-Nr. DE 250200933 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? 2007-11-28 9:21 ` Roderik.Wildenburg @ 2007-11-28 9:43 ` Philippe Gerum 2007-11-28 10:05 ` Roderik.Wildenburg 0 siblings, 1 reply; 13+ messages in thread From: Philippe Gerum @ 2007-11-28 9:43 UTC (permalink / raw) To: Roderik.Wildenburg; +Cc: xenomai [-- Attachment #1: Type: text/plain, Size: 3125 bytes --] Roderik.Wildenburg@domain.hid wrote: > Thank you. Good work ! > > I applied your patch to 2.3.2 and, as far as I can see, > the allocation problem does not accur anymore. > You will need this attached patch on top of the previous one to get the complete fix. > (please se my insertions below) > >> Now, the human readable form of the explanation: >> - you ask for a 10kb heap, which is silently rounded to 12k >> in order to >> cope with the 4k alignment constraint we have on shareable heaps >> (userland heaps are always shareable). >> - 12kb heap means 3 * 4k pages available in the global free list. >> - your application allocates randomly-sized blocks, each new size >> rounded to the next power of 2 grabs one page from the global pool to >> hold blocks of the same size, but unfortunately, the heap manager does >> _not_ release it back to the free list when the last block laid on the >> page is freed. > > Thank you for your explanation, > I thought it must be something like this > (block remembers what size ist as been allocated for) > >> - after more than 3 different allocation sizes (e.g. 2^3, 2^5 and 2^8) >> have been requested to the heap manager, it fails honoring a >> fourth one. >> I would rather consider this as a bug, since putting a lot of pressure >> on a single block size would beget the same problem (i.e. no >> need for a >> funky randomized allocation pattern here), with a global free > > I think the test case isn´t very funky. Of course we did not write > random buffer sizes (this was just implemted to get a simple test case), > but we simple wrote some messages of different size to a queue and faced > the allocation problem. > Therefore, form our point of view, this is a bug. > Funky in the sense that real-time applications usually have a well-defined allocation pattern, with sizes known in advance, which reduces the odds for fragmentation, and helps keeping the allocation/deallocation cheap. This does not prevent from considering the failure to cope with the opposite situation as a bug, though. >> page list >> being emptied over time, and all pages lingering inside some private >> (per-block size) bucket queue. >> >> The attached patch fixed the issue (against v2.4-rc6). I'm still >> pondering whether v2.3.x should get this update too, due to the >> variations this patch introduces wrt memory consumption for the heap > > I would appreciate it, if 2.3.x could be updated too, > as we could carry on using 2.3.x (vendor libraries don´t need to be updated) > It's not a feature change/addition, but can be considered as a maintenance issue, so it's likely to make it into the ultimate v2.3.x release. > Many thanks and best regards > Roderik > > MAN Roland Druckmaschinen AG > Vorsitzender des Aufsichtsrates: Hanno C. Fiedler > Vorstand: Gerd Finkbeiner (Vorsitzender), Dr. Ingo Koch, Dr. Markus Rall, Paul Steidle > Sitz der Gesellschaft: Offenbach am Main, Registergericht: Amtsgericht Offenbach HRB-Nr. 42592 > USt-Ident-Nr. DE 250200933 > -- Philippe. [-- Attachment #2: heap-fix-single-page-release.patch --] [-- Type: text/x-patch, Size: 5857 bytes --] Index: include/nucleus/heap.h =================================================================== --- include/nucleus/heap.h (revision 3216) +++ include/nucleus/heap.h (revision 3217) @@ -92,7 +92,10 @@ DECLARE_XNLOCK(lock); - caddr_t buckets[XNHEAP_NBUCKETS]; + struct xnbucket { + caddr_t freelist; + int fcount; + } buckets[XNHEAP_NBUCKETS]; xnholder_t *idleq; Index: ksrc/nucleus/heap.c =================================================================== --- ksrc/nucleus/heap.c (revision 3216) +++ ksrc/nucleus/heap.c (revision 3217) @@ -161,7 +161,6 @@ { u_long hdrsize, shiftsize, pageshift; xnextent_t *extent; - int n; /* * Perform some parametrical checks first. @@ -219,14 +218,9 @@ inith(&heap->link); initq(&heap->extents); xnlock_init(&heap->lock); - xnarch_init_heapcb(&heap->archdep); - - for (n = 0; n < XNHEAP_NBUCKETS; n++) - heap->buckets[n] = NULL; - + memset(heap->buckets, 0, sizeof(heap->buckets)); extent = (xnextent_t *)heapaddr; - init_extent(heap, extent); appendq(&heap->extents, &extent->link); @@ -428,10 +422,10 @@ { xnholder_t *holder; xnextent_t *extent; + int log2size, ilog; u_long pagenum; caddr_t block; u_long bsize; - int log2size; spl_t s; if (size == 0) @@ -463,7 +457,7 @@ 2 times the page size. Otherwise, use the bucketed memory blocks. */ - if (size <= heap->pagesize * 2) { + if (likely(size <= heap->pagesize * 2)) { /* Find the first power of two greater or equal to the rounded size. The log2 value of this size is also computed. */ @@ -471,22 +465,22 @@ bsize < size; bsize <<= 1, log2size++) ; /* Loop */ + ilog = log2size - XNHEAP_MINLOG2; + xnlock_get_irqsave(&heap->lock, s); - block = heap->buckets[log2size - XNHEAP_MINLOG2]; + block = heap->buckets[ilog].freelist; if (block == NULL) { block = get_free_range(heap, bsize, log2size); if (block == NULL) goto release_and_exit; + if (bsize <= heap->pagesize) + heap->buckets[ilog].fcount += (heap->pagesize >> log2size) - 1; } else { - /* - * If only we had all pages sitting on - * pagesize boundaries, we could use a trivial - * address masking to compute the address of - * the containing page, but we can't assume - * that for now. Oh, well... - */ + if (bsize <= heap->pagesize) + --heap->buckets[ilog].fcount; + for (holder = getheadq(&heap->extents), extent = NULL; holder != NULL; holder = nextq(&heap->extents, holder)) { extent = link2extent(holder); @@ -502,7 +496,7 @@ ++extent->pagemap[pagenum].bcount; } - heap->buckets[log2size - XNHEAP_MINLOG2] = *((caddr_t *) block); + heap->buckets[ilog].freelist = *((caddr_t *) block); heap->ubytes += bsize; } else { if (size > heap->maxcont) @@ -566,10 +560,10 @@ int xnheap_test_and_free(xnheap_t *heap, void *block, int (*ckfn) (void *block)) { - caddr_t freepage, lastpage, nextpage, tailpage; + caddr_t freepage, lastpage, nextpage, tailpage, freeptr, *tailptr; + int log2size, npages, err, nblocks, xpage, ilog; u_long pagenum, pagecont, boffset, bsize; xnextent_t *extent = NULL; - int log2size, npages, err; xnholder_t *holder; spl_t s; @@ -672,22 +666,75 @@ * value for the heading page is always 1). */ - if (unlikely(--extent->pagemap[pagenum].bcount == 0)) { - heap->buckets[log2size - XNHEAP_MINLOG2] = NULL; - npages = bsize >> heap->pageshift; - if (likely(npages <= 1)) { - tailpage = block; - goto free_pages; - } + ilog = log2size - XNHEAP_MINLOG2; + + if (likely(--extent->pagemap[pagenum].bcount > 0)) { + /* Return the block to the bucketed memory space. */ + *((caddr_t *) block) = heap->buckets[ilog].freelist; + heap->buckets[ilog].freelist = block; + ++heap->buckets[ilog].fcount; + break; + } + + npages = bsize >> heap->pageshift; + + if (unlikely(npages > 1)) + /* + * The simplest case: we only have a single + * block to deal with, which spans multiple + * pages. We just need to release it as a list + * of pages, without caring about the + * consistency of the bucket. + */ goto free_page_list; + + freepage = extent->membase + (pagenum << heap->pageshift); + block = freepage; + tailpage = freepage; + nextpage = freepage + heap->pagesize; + nblocks = heap->pagesize >> log2size; + heap->buckets[ilog].fcount -= (nblocks - 1); + + XENO_ASSERT(NUCLEUS, heap->buckets[ilog].fcount >= 0, + xnpod_fatal("free block count became negative (heap %p, log2=%d, fcount=%d)?!", + heap, log2size, heap->buckets[ilog].fcount); + ); + /* + * Easy case: all free blocks are laid on a single + * page we are now releasing. Just clear the bucket + * and bail out. + */ + + if (likely(heap->buckets[ilog].fcount == 0)) { + heap->buckets[ilog].freelist = NULL; + goto free_pages; } - /* Return the block to the bucketed memory space. */ + /* + * Worst case: multiple pages are traversed by the + * bucket list. Scan the list to remove all blocks + * belonging to the freed page. We are done whenever + * all possible blocks from the freed page have been + * traversed, or we hit the end of list, whichever + * comes first. + */ - *((caddr_t *) block) = heap->buckets[log2size - XNHEAP_MINLOG2]; - heap->buckets[log2size - XNHEAP_MINLOG2] = block; + for (tailptr = &heap->buckets[ilog].freelist, freeptr = *tailptr, xpage = 1; + freeptr != NULL && nblocks > 0; freeptr = *((caddr_t *) freeptr)) { + if (unlikely(freeptr < freepage || freeptr >= nextpage)) { + if (unlikely(xpage)) { /* Limit random writes */ + *tailptr = freeptr; + xpage = 0; + } + tailptr = (caddr_t *)freeptr; + } else { + --nblocks; + xpage = 1; + } + } - break; + *tailptr = freeptr; + goto free_pages; } heap->ubytes -= bsize; ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? 2007-11-28 9:43 ` Philippe Gerum @ 2007-11-28 10:05 ` Roderik.Wildenburg 2007-11-28 10:22 ` Philippe Gerum 0 siblings, 1 reply; 13+ messages in thread From: Roderik.Wildenburg @ 2007-11-28 10:05 UTC (permalink / raw) To: rpm; +Cc: xenomai > > It's not a feature change/addition, but can be considered as a > maintenance issue, so it's likely to make it into the ultimate v2.3.x > release. > Do you have an idea when this will happen ? Best regards Roderik MAN Roland Druckmaschinen AG Vorsitzender des Aufsichtsrates: Hanno C. Fiedler Vorstand: Gerd Finkbeiner (Vorsitzender), Dr. Ingo Koch, Dr. Markus Rall, Paul Steidle Sitz der Gesellschaft: Offenbach am Main, Registergericht: Amtsgericht Offenbach HRB-Nr. 42592 USt-Ident-Nr. DE 250200933 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? 2007-11-28 10:05 ` Roderik.Wildenburg @ 2007-11-28 10:22 ` Philippe Gerum 0 siblings, 0 replies; 13+ messages in thread From: Philippe Gerum @ 2007-11-28 10:22 UTC (permalink / raw) To: Roderik.Wildenburg; +Cc: xenomai Roderik.Wildenburg@domain.hid wrote: >> It's not a feature change/addition, but can be considered as a >> maintenance issue, so it's likely to make it into the ultimate v2.3.x >> release. >> > > Do you have an idea when this will happen ? Yes. When time allows. > > Best regards > Roderik > > MAN Roland Druckmaschinen AG > Vorsitzender des Aufsichtsrates: Hanno C. Fiedler > Vorstand: Gerd Finkbeiner (Vorsitzender), Dr. Ingo Koch, Dr. Markus Rall, Paul Steidle > Sitz der Gesellschaft: Offenbach am Main, Registergericht: Amtsgericht Offenbach HRB-Nr. 42592 > USt-Ident-Nr. DE 250200933 > -- Philippe. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ?
@ 2007-11-28 13:03 Roderik.Wildenburg
0 siblings, 0 replies; 13+ messages in thread
From: Roderik.Wildenburg @ 2007-11-28 13:03 UTC (permalink / raw)
To: rpm; +Cc: xenomai
>
> You will need this attached patch on top of the previous one
> to get the complete fix.
I applied your second patch. Works fine. Thank you.
As allready your first patch did not produce
the problem any more I unfortunatelly can´t report
an obvious improvement from the 2. patch.
Nevertheless we will use both of your patches as
long as 2.3.x ultimate isn´t out.
(Did your 2. patch solve some rare situations,
or why else did allready your 1. patch solve my
problem ?)
Roderik
MAN Roland Druckmaschinen AG
Vorsitzender des Aufsichtsrates: Hanno C. Fiedler
Vorstand: Gerd Finkbeiner (Vorsitzender), Dr. Ingo Koch, Dr. Markus Rall, Paul Steidle
Sitz der Gesellschaft: Offenbach am Main, Registergericht: Amtsgericht Offenbach HRB-Nr. 42592
USt-Ident-Nr. DE 250200933
^ permalink raw reply [flat|nested] 13+ messages in threadend of thread, other threads:[~2007-11-28 13:03 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-11-19 13:43 [Xenomai-help] rt_queue_write error: "Cannot allocate memory "; bug or feature ? Roderik.Wildenburg 2007-11-19 14:35 ` Philippe Gerum 2007-11-19 15:11 ` Roderik.Wildenburg 2007-11-19 18:06 ` Philippe Gerum 2007-11-20 8:51 ` Roderik.Wildenburg 2007-11-20 13:59 ` Philippe Gerum 2007-11-21 14:07 ` Roderik.Wildenburg 2007-11-23 17:08 ` Philippe Gerum 2007-11-28 9:21 ` Roderik.Wildenburg 2007-11-28 9:43 ` Philippe Gerum 2007-11-28 10:05 ` Roderik.Wildenburg 2007-11-28 10:22 ` Philippe Gerum -- strict thread matches above, loose matches on Subject: below -- 2007-11-28 13:03 Roderik.Wildenburg
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.