* [Xenomai-help] Creation of a rt-queue from the user space
@ 2005-11-10 21:05 ROSSIER Daniel
2005-11-11 9:30 ` [Xenomai-help] printk Ignacio García Pérez
2005-11-11 14:08 ` [Xenomai-help] Creation of a rt-queue from the user space Jan Kiszka
0 siblings, 2 replies; 53+ messages in thread
From: ROSSIER Daniel @ 2005-11-10 21:05 UTC (permalink / raw)
To: xenomai
Hello everyone,
I've recently posted a message in this mailing list about an issue regarding the use of realtime queue in xenomai from the user space.
I didn't make any significant progress regarding this issue. I've upgraded to linux 2.6.12; everything works in the user/kernel space except the queue. If I correctly understood, it's necessary to have a /dev/rtheap in order to set up a shared memory segment between user and kernel space.
If this entry does not exist, we get an error at the queue creation time.
I've observed that if I'm creating manually the entry in /dev, I get the same error and the entry disappears from /dev. Then, I've transfered the udev/rtheap.rules located in the xenomai/nucleus directory into /etc/udev/rules.d. But the system totally freezes after xeno-load.
I've put the segment of code (very simple) for the creation of a simple rt-queue.
----------------
int main(int argc, char *argv[]) {
printf("Now starting: %s\n", argv[0]);
/* Timer initialization */
err = rt_timer_start(1000000); /* So, one tick will be equal to 1 ms */
if (err != 0) {
printf("Error timer: %d\n", err);
clean_exit(0);
}
/* Create the mailbox */
err = rt_queue_create(&mailbox, "MAILBOX", 80, 1, Q_FIFO);
if (err != 0) {
printf("mbox creation failed: %d\n", err);
clean_exit(0);
}
------------
Thanks for any support.
Regards
Daniel
^ permalink raw reply [flat|nested] 53+ messages in thread* [Xenomai-help] printk 2005-11-10 21:05 [Xenomai-help] Creation of a rt-queue from the user space ROSSIER Daniel @ 2005-11-11 9:30 ` Ignacio García Pérez 2005-11-11 11:07 ` Dmitry Adamushko ` (2 more replies) 2005-11-11 14:08 ` [Xenomai-help] Creation of a rt-queue from the user space Jan Kiszka 1 sibling, 3 replies; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-11 9:30 UTC (permalink / raw) To: xenomai Hi, I'm porting an app from RTAI to Xenomai, and when it came to the rt_printk function, I had to replace it with plain printk (the xnarch_log* functions all use printk). What I want to know if: 1- Is totally safe to call the standard kernel printk function from a real time task? 2- Even if it's safe, can it affect the performance of a real time task? (or can it block under *any* conceivable condition?) Thanks. Nacho. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] printk 2005-11-11 9:30 ` [Xenomai-help] printk Ignacio García Pérez @ 2005-11-11 11:07 ` Dmitry Adamushko 2005-11-14 10:52 ` Ignacio García Pérez 2005-11-12 19:45 ` [Xenomai-help] printk Philippe Gerum 2005-11-14 10:47 ` [Xenomai-help] Invalid characters in task's names Ignacio García Pérez 2 siblings, 1 reply; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-11 11:07 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai [-- Attachment #1: Type: text/plain, Size: 1654 bytes --] xenomai-help-bounces@domain.hid wrote on 11.11.2005 10:30:26: > Hi, > > I'm porting an app from RTAI to Xenomai, and when it came to the > rt_printk function, I had to replace it with plain printk (the > xnarch_log* functions all use printk). > > What I want to know if: > > 1- Is totally safe to call the standard kernel printk function from a > real time task? Actually, the adeos/ipipe patches make some changes to the vanilla kernel's printk() mechanism. There are 2 possible modes of printk() being issued from the primary domain. 1) asynchronous: all data is written into the protected buffer and the __ipipe_printk_virq virq is risen for the secondary domain. So the data will be printed out when the linux gets control next time. Although, here is, well, a tiny race because of the fact that the virq handler doesn't lock a buffer-related data (like __ipipe_printk_fill) so a loss of data may occur under some circumstances. 2) synchronous (IPIPE_SPRINTK_FLAG) in this case, a normal linux vprintk() call is issued. Oops, this one, in turn, calls spin_lock_irqsave(&logbuf_lock, flags); in real-time context and that lock may be already held by a preempted non-rt task on the same CPU. Houston? :o) > > 2- Even if it's safe, can it affect the performance of a real time task? > (or can it block under *any* conceivable condition?) It gives some overhead since data must be copied to the buffer and at that time the interrupts are off. Blocked? No, if not taking into account a possible "hang up" with the synchronous mode (ok, as always there is still a hope that I can be wrong ):) > > Thanks. > > Nacho. > --- Best regards, Dmitry [-- Attachment #2: Type: text/html, Size: 2159 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] printk 2005-11-11 11:07 ` Dmitry Adamushko @ 2005-11-14 10:52 ` Ignacio García Pérez 2005-11-14 11:26 ` Philippe Gerum 2005-11-14 12:15 ` [Xenomai-help] xn_pipe_create [minor] Ignacio García Pérez 0 siblings, 2 replies; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-14 10:52 UTC (permalink / raw) To: Dmitry Adamushko; +Cc: xenomai Dmitry Adamushko wrote: > > xenomai-help-bounces@domain.hid wrote on 11.11.2005 10:30:26: > > > Hi, > > > > I'm porting an app from RTAI to Xenomai, and when it came to the > > rt_printk function, I had to replace it with plain printk (the > > xnarch_log* functions all use printk). > > > > What I want to know if: > > > > 1- Is totally safe to call the standard kernel printk function from a > > real time task? > > Actually, the adeos/ipipe patches make some changes to the vanilla > kernel's printk() mechanism. > > There are 2 possible modes of printk() being issued from the primary > domain. > > 1) asynchronous: > > all data is written into the protected buffer and the > __ipipe_printk_virq virq is risen for the secondary domain. So the > data will be printed out when the linux gets control next time. > > Although, here is, well, a tiny race because of the fact that the virq > handler doesn't lock a buffer-related data (like __ipipe_printk_fill) > so a loss of data may occur under some circumstances. > > 2) synchronous (IPIPE_SPRINTK_FLAG) > > in this case, a normal linux vprintk() call is issued. Oops, this one, > in turn, calls spin_lock_irqsave(&logbuf_lock, flags); in real-time > context and that lock may be already held by a preempted non-rt task > on the same CPU. > > Houston? :o) > (2) is unacceptable. Losing some data would be acceptable if it is caused by too much printk output, but not because of a race condition. This should be fixed. I guess a simple FIFO with proper locking should be in place. printk would discard data only if there is no space left. > > > > > 2- Even if it's safe, can it affect the performance of a real time task? > > (or can it block under *any* conceivable condition?) > > It gives some overhead since data must be copied to the buffer and at > that time the interrupts are off. > Blocked? No, if not taking into account a possible "hang up" with the > synchronous mode (ok, as always there is still a hope that I can be > wrong ):) > If you are right, then it's unacceptable. An RT task would be blocked by a non-RT task. > > > > > Thanks. > > > > Nacho. > > > > --- > Best regards, > Dmitry > >------------------------------------------------------------------------ > >No virus found in this incoming message. >Checked by AVG Free Edition. >Version: 7.1.362 / Virus Database: 267.13.0/167 - Release Date: 11/11/2005 > > ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] printk 2005-11-14 10:52 ` Ignacio García Pérez @ 2005-11-14 11:26 ` Philippe Gerum 2005-11-14 12:03 ` Dmitry Adamushko 2005-11-14 12:15 ` [Xenomai-help] xn_pipe_create [minor] Ignacio García Pérez 1 sibling, 1 reply; 53+ messages in thread From: Philippe Gerum @ 2005-11-14 11:26 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai Ignacio García Pérez wrote: > Dmitry Adamushko wrote: > > >>xenomai-help-bounces@domain.hid wrote on 11.11.2005 10:30:26: >> >> >>>Hi, >>> >>>I'm porting an app from RTAI to Xenomai, and when it came to the >>>rt_printk function, I had to replace it with plain printk (the >>>xnarch_log* functions all use printk). >>> >>>What I want to know if: >>> >>>1- Is totally safe to call the standard kernel printk function from a >>>real time task? >> >>Actually, the adeos/ipipe patches make some changes to the vanilla >>kernel's printk() mechanism. >> >>There are 2 possible modes of printk() being issued from the primary >>domain. >> >>1) asynchronous: >> >>all data is written into the protected buffer and the >>__ipipe_printk_virq virq is risen for the secondary domain. So the >>data will be printed out when the linux gets control next time. >> >>Although, here is, well, a tiny race because of the fact that the virq >>handler doesn't lock a buffer-related data (like __ipipe_printk_fill) >>so a loss of data may occur under some circumstances. >> Nope. __ipipe_printk_fill and friends are manipulated under hw irq spinlocking in printk(), and under Linux domain stalling protection in __ipipe_flush_printk since it's a virq handler, and finally, printk() cannot preempt __ipipe_flush_printk under normal operation mode (i.e. async mode). AFAICS, there's no race here. >>2) synchronous (IPIPE_SPRINTK_FLAG) >> >>in this case, a normal linux vprintk() call is issued. Oops, this one, >>in turn, calls spin_lock_irqsave(&logbuf_lock, flags); in real-time >>context and that lock may be already held by a preempted non-rt task >>on the same CPU. >> >>Houston? :o) >> > > (2) is unacceptable. Losing some data would be acceptable if it is > caused by too much printk output, but not because of a race condition. > This should be fixed. I guess a simple FIFO with proper locking should > be in place. printk would discard data only if there is no space left. > > >>>2- Even if it's safe, can it affect the performance of a real time task? >>>(or can it block under *any* conceivable condition?) >> >>It gives some overhead since data must be copied to the buffer and at >>that time the interrupts are off. >>Blocked? No, if not taking into account a possible "hang up" with the >>synchronous mode (ok, as always there is still a hope that I can be >>wrong ):) >> > > If you are right, then it's unacceptable. An RT task would be blocked by > a non-RT task. > Please people, keep things simple and easy: synchronous printk mode is an _emergency_ configuration which is of no use under normal runtime conditions. It is only there as a desperate debugging help for Adeos/Xeno core development in order to force the printk output regardless of the current domain, so it might work, but it it doesn't and hits any of the obvious races that the asynchronous mode solves, well, nobody is going to complain because it's just a last resort bypass in order to get some ultimate traces before the box jumps out of the window anyway. IOW, if one keeps using the default and normal async printk mode which prevents domain clashes, everything will be fine. Regarding the overhead induced by a temporary copy of the printk data, if one starts having problem with this, then the issue is first caused by spamming the kernel log with such amount of information. IOW, cure the real bug, not its consequences. -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] printk 2005-11-14 11:26 ` Philippe Gerum @ 2005-11-14 12:03 ` Dmitry Adamushko 2005-11-14 13:22 ` Philippe Gerum 0 siblings, 1 reply; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-14 12:03 UTC (permalink / raw) To: Philippe Gerum; +Cc: xenomai [-- Attachment #1: Type: text/plain, Size: 1577 bytes --] Philippe Gerum <rpm@xenomai.org> wrote on 14.11.2005 12:26:08: > >> > >>Although, here is, well, a tiny race because of the fact that the virq > >>handler doesn't lock a buffer-related data (like __ipipe_printk_fill) > >>so a loss of data may occur under some circumstances. > >> > > Nope. __ipipe_printk_fill and friends are manipulated under hw irq > spinlocking > in printk(), and under Linux domain stalling protection in > __ipipe_flush_printk > since it's a virq handler, So what prevents some activity from the primary domain from preempting __ipipe_flush_printk() and calling printk() when _only_ the Linux domain is stalled? let's say at the (*) point void __ipipe_flush_printk (unsigned virq) { char *p = __ipipe_printk_buf; int out = 0, len; clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); while (out < __ipipe_printk_fill) { len = strlen(p) + 1; printk("%s",p); p += len; out += len; } (*) <---------------------------- preempted __ipipe_printk_fill = 0; } When linux gets controll back the virq continues its execution and sets __ipipe_printk_fill up to 0. This cannot happen only if virqs are manipulated with the primary domain being stalled as well. But you told "and under __Linux domain___ stalling protection in __ipipe_flush_printk since it's a virq handler". > and finally, printk() cannot preempt > __ipipe_flush_printk under normal operation mode (i.e. async mode). AFAICS, > there's no race here. --- Best regards, Dmitry [-- Attachment #2: Type: text/html, Size: 2348 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] printk 2005-11-14 12:03 ` Dmitry Adamushko @ 2005-11-14 13:22 ` Philippe Gerum 2005-11-14 13:47 ` Philippe Gerum 0 siblings, 1 reply; 53+ messages in thread From: Philippe Gerum @ 2005-11-14 13:22 UTC (permalink / raw) To: Dmitry Adamushko; +Cc: xenomai Dmitry Adamushko wrote: > Philippe Gerum <rpm@xenomai.org> wrote on 14.11.2005 12:26:08: > > > >> > > >>Although, here is, well, a tiny race because of the fact that the virq > > >>handler doesn't lock a buffer-related data (like __ipipe_printk_fill) > > >>so a loss of data may occur under some circumstances. > > >> > > > > Nope. __ipipe_printk_fill and friends are manipulated under hw irq > > spinlocking > > in printk(), and under Linux domain stalling protection in > > __ipipe_flush_printk > > since it's a virq handler, > > So what prevents some activity from the primary domain from preempting > __ipipe_flush_printk() and calling printk() when _only_ the Linux domain > is stalled? This cannot happen in async mode, since the output would be buffered and printk() never called on behalf of the preempted handler. > > let's say at the (*) point > > void __ipipe_flush_printk (unsigned virq) > { > char *p = __ipipe_printk_buf; > int out = 0, len; > > clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); > > while (out < __ipipe_printk_fill) { > len = strlen(p) + 1; > printk("%s",p); > p += len; > out += len; > } > (*) <---------------------------- preempted > __ipipe_printk_fill = 0; > } > > When linux gets controll back the virq continues its execution and sets > __ipipe_printk_fill up to 0. > > This cannot happen only if virqs are manipulated with the primary domain > being stalled as well. But you told "and under __Linux domain___ > stalling protection in __ipipe_flush_printk since it's a virq handler". > > > > and finally, printk() cannot preempt > > __ipipe_flush_printk under normal operation mode (i.e. async mode). > AFAICS, > > there's no race here. > > > --- > Best regards, > Dmitry > -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] printk 2005-11-14 13:22 ` Philippe Gerum @ 2005-11-14 13:47 ` Philippe Gerum 2005-11-14 14:50 ` [Xenomai-core] " Dmitry Adamushko 0 siblings, 1 reply; 53+ messages in thread From: Philippe Gerum @ 2005-11-14 13:47 UTC (permalink / raw) To: Philippe Gerum; +Cc: xenomai Philippe Gerum wrote: > Dmitry Adamushko wrote: > >> Philippe Gerum <rpm@xenomai.org> wrote on 14.11.2005 12:26:08: >> >> > >> >> > >>Although, here is, well, a tiny race because of the fact that the >> virq >> > >>handler doesn't lock a buffer-related data (like >> __ipipe_printk_fill) >> > >>so a loss of data may occur under some circumstances. >> > >> >> > >> > Nope. __ipipe_printk_fill and friends are manipulated under hw irq >> > spinlocking >> > in printk(), and under Linux domain stalling protection in >> > __ipipe_flush_printk >> > since it's a virq handler, >> >> So what prevents some activity from the primary domain from preempting >> __ipipe_flush_printk() and calling printk() when _only_ the Linux >> domain is stalled? > > > This cannot happen in async mode, since the output would be buffered and > printk() never called on behalf of the preempted handler. > >> >> let's say at the (*) point >> >> void __ipipe_flush_printk (unsigned virq) >> { >> char *p = __ipipe_printk_buf; >> int out = 0, len; >> >> clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); >> >> while (out < __ipipe_printk_fill) { >> len = strlen(p) + 1; >> printk("%s",p); >> p += len; >> out += len; >> } >> (*) <---------------------------- preempted >> __ipipe_printk_fill = 0; >> } >> >> When linux gets controll back the virq continues its execution and >> sets __ipipe_printk_fill up to 0. >> >> This cannot happen only if virqs are manipulated with the primary >> domain being stalled as well. But you told "and under __Linux >> domain___ stalling protection in __ipipe_flush_printk since it's a >> virq handler". >> >> >> > and finally, printk() cannot preempt >> > __ipipe_flush_printk under normal operation mode (i.e. async mode). >> AFAICS, >> > there's no race here. Mea culpa, Dmitry is right, in the above situation he depicted, we could drop a portion of the output buffer. A way to fix this would be to hw lock a test and decrement section of __ipipe_printk_fill in the flush handler. -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] Re: [Xenomai-help] printk 2005-11-14 13:47 ` Philippe Gerum @ 2005-11-14 14:50 ` Dmitry Adamushko 2005-11-14 15:56 ` [Xenomai-core] rt_pipe_* usage Ignacio García Pérez 2005-11-15 9:38 ` [Xenomai-core] Re: [Xenomai-help] printk Philippe Gerum 0 siblings, 2 replies; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-14 14:50 UTC (permalink / raw) To: Philippe Gerum; +Cc: xenomai, xenomai [-- Attachment #1: Type: text/plain, Size: 3426 bytes --] > > ... > > > > This cannot happen in async mode, since the output would be buffered and > > printk() never called on behalf of the preempted handler. > > > >> > >> let's say at the (*) point > >> > >> void __ipipe_flush_printk (unsigned virq) > >> { > >> char *p = __ipipe_printk_buf; > >> int out = 0, len; > >> > >> clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); > >> > >> while (out < __ipipe_printk_fill) { > >> len = strlen(p) + 1; > >> printk("%s",p); > >> p += len; > >> out += len; > >> } > >> (*) <---------------------------- preempted > >> __ipipe_printk_fill = 0; > >> } > >> > >> When linux gets controll back the virq continues its execution and > >> sets __ipipe_printk_fill up to 0. > >> > >> This cannot happen only if virqs are manipulated with the primary > >> domain being stalled as well. But you told "and under __Linux > >> domain___ stalling protection in __ipipe_flush_printk since it's a > >> virq handler". > >> > >> > >> > and finally, printk() cannot preempt > >> > __ipipe_flush_printk under normal operation mode (i.e. async mode). > >> AFAICS, > >> > there's no race here. > > Mea culpa, Dmitry is right, in the above situation he depicted, we > could drop a > portion of the output buffer. A way to fix this would be to hw lock > a test and > decrement section of __ipipe_printk_fill in the flush handler. > Something like that (just a draft) would work probably but I suppose something a bit more graceful would be implemented. Actually, with a small optimization of IPIPE_PRINTK_FLAG. void __ipipe_flush_printk (unsigned virq) { char *p = __ipipe_printk_buf; - int out = 0, len; + int out = 0, len, used; ... - clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); ... + spin_lock_irqsave_hw(&__ipipe_printk_lock,flags); + used = __ipipe_printk_fill; + spin_unlock_irqrestore_hw(&__ipipe_printk_lock,flags); + oncemore: while (out < used) { len = strlen(p) + 1; printk("%s",p); p += len; out += len; } + spin_lock_irqsave_hw(&__ipipe_printk_lock,flags); + if (__ipipe_printk_fill == used) + { - __ipipe_printk_fill = 0; + used = __ipipe_printk_fill = 0; + // when everything is done + clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); + } + else + used = __ipipe_printk_fill; + spin_unlock_irqrestore_hw(&__ipipe_printk_lock,flags); + if (used) + goto oncemore; ... } and asmlinkage int printk(const char *fmt, ...) { + int virq_is_active; ... spin_lock_irqsave_hw(&__ipipe_printk_lock,flags); fbytes = __LOG_BUF_LEN - __ipipe_printk_fill; if (fbytes > 1) { r = vscnprintf(__ipipe_printk_buf + __ipipe_printk_fill, fbytes, fmt, args) + 1; /* account for the null byte */ __ipipe_printk_fill += r; } else r = 0; + virq_is_active = test_and_set_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); spin_unlock_irqrestore_hw(&__ipipe_printk_lock,flags); - if (!test_and_set_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags)) + if (!virq_is_active) ipipe_trigger_irq(__ipipe_printk_virq); out: va_end(args); return r; } > -- > > Philippe. --- Best regards, Dmitry [-- Attachment #2: Type: text/html, Size: 5816 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] rt_pipe_* usage 2005-11-14 14:50 ` [Xenomai-core] " Dmitry Adamushko @ 2005-11-14 15:56 ` Ignacio García Pérez 2005-11-14 16:15 ` [Xenomai-core] More on rt pipes usage Ignacio García Pérez 2005-11-14 16:23 ` [Xenomai-core] rt_pipe_* usage Dmitry Adamushko 2005-11-15 9:38 ` [Xenomai-core] Re: [Xenomai-help] printk Philippe Gerum 1 sibling, 2 replies; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-14 15:56 UTC (permalink / raw) To: xenomai Hi, I'm having now my first contact with the pipe framework, an have some comments about it that might be of interest to the core developers: While the documentation is overall *great*, I fould it a bit lacking regarding the pipes. Would be good to have some examples of general usage. As far as I can tell, there is no mention of the usage of P_MSGPTR and P_MSGSIZE. I had to learn about them in the headers. At first sight, the rt_pipe_send call is confusing: why should I pass the data size since it is supposed to be embedded in the RT_PIPE_MSG structure?. This is what I first did: RT_PIPE_MSG *m = rt_pipe_alloc(sizeof(mystruct)); P_MSGPTR(m) = &mystruct; P_MSGSIZE(m) = sizeof(mystruct) rt_pipe_send(&mypipe, m, sizeof(mystruct), P_NORMAL); Which is obviously wrong. Please correct me if I'm wrong: P_MSGPTR and P_MSGSIZE are intended not to be used as an lvalue (is there a way to define these macros to generate a compile error if they are?). So, the correct way would be something like this (again, correct me if I'm wrong):: RT_PIPE_MSG *m = rt_pipe_alloc(sizeof(mystruct_t)); mystruct_t *p = (mystruct_t *)P_MSGPTR(m); p->whatever1 = X; p->whatever2 = X; rt_pipe_send(&mypipe, m, sizeof(mystruct_t), P_NORMAL); If this is correct, why do I have to specify the size of mystruct_t *twice*. Can't it be initialized by rt_pipe_alloc ?. Nacho. ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] More on rt pipes usage 2005-11-14 15:56 ` [Xenomai-core] rt_pipe_* usage Ignacio García Pérez @ 2005-11-14 16:15 ` Ignacio García Pérez 2005-11-15 13:24 ` Philippe Gerum 2005-11-14 16:23 ` [Xenomai-core] rt_pipe_* usage Dmitry Adamushko 1 sibling, 1 reply; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-14 16:15 UTC (permalink / raw) To: xenomai Hi, Suppose I have a kernel rt task that samples data at a certain rate and writes it as messages into a rt pipe, from which it is read by a user space non rt program. I want to limit the number of messages that are put into the pipe, because otherwise if the user space program dies, it will grow endlessly till it exausts the rt heap. What I want to do is to have a pipe that can hold a limited number of messages such that rt_pipe_write will fail if it is full. Is there a way to know how many messages are there in the pipe? Even if there is a way, to prevent a (harmless) race condition, I would need to lock the pipe between checking the number of messages and calling rt_pipe_write. As far as I know, pipe locking belongs to the nucleus and I'd like to stay in the native skin as much as possible. Another method would be to count how many messages I write, but then I'd need some hook that notifies me when the user space program reads a message so I can decrement the count. Any ideas? Nacho. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-core] More on rt pipes usage 2005-11-14 16:15 ` [Xenomai-core] More on rt pipes usage Ignacio García Pérez @ 2005-11-15 13:24 ` Philippe Gerum 2005-11-15 16:41 ` [Xenomai-help] " Ignacio García Pérez 0 siblings, 1 reply; 53+ messages in thread From: Philippe Gerum @ 2005-11-15 13:24 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai Ignacio García Pérez wrote: > Hi, > > Suppose I have a kernel rt task that samples data at a certain rate and > writes it as messages into a rt pipe, from which it is read by a user > space non rt program. > > I want to limit the number of messages that are put into the pipe, > because otherwise if the user space program dies, it will grow endlessly > till it exausts the rt heap. > > What I want to do is to have a pipe that can hold a limited number of > messages such that rt_pipe_write will fail if it is full. > > Is there a way to know how many messages are there in the pipe? > > Even if there is a way, to prevent a (harmless) race condition, I would > need to lock the pipe between checking the number of messages and > calling rt_pipe_write. As far as I know, pipe locking belongs to the > nucleus and I'd like to stay in the native skin as much as possible. > > Another method would be to count how many messages I write, but then I'd > need some hook that notifies me when the user space program reads a > message so I can decrement the count. > > Any ideas? The plan is to be able to tell the pipe manager to use a user-provided heap instead of the system one; this way, exhausting the local heap (*) in RT space would be a clear sign that non-RT must be allowed to consume the pending data first. A simple interface to do that is missing, but the pipe manager already works with a variable heap pointer. (*) Using the overall available memory seems a better metric than the number of pending messages, since it may often happen that messages have different sizes. -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-help] Re: [Xenomai-core] More on rt pipes usage 2005-11-15 13:24 ` Philippe Gerum @ 2005-11-15 16:41 ` Ignacio García Pérez 0 siblings, 0 replies; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-15 16:41 UTC (permalink / raw) To: Philippe Gerum, xenomai Philippe Gerum wrote: > Ignacio García Pérez wrote: > >> Hi, >> >> Suppose I have a kernel rt task that samples data at a certain rate and >> writes it as messages into a rt pipe, from which it is read by a user >> space non rt program. >> >> I want to limit the number of messages that are put into the pipe, >> because otherwise if the user space program dies, it will grow endlessly >> till it exausts the rt heap. >> >> What I want to do is to have a pipe that can hold a limited number of >> messages such that rt_pipe_write will fail if it is full. >> >> Is there a way to know how many messages are there in the pipe? >> >> Even if there is a way, to prevent a (harmless) race condition, I would >> need to lock the pipe between checking the number of messages and >> calling rt_pipe_write. As far as I know, pipe locking belongs to the >> nucleus and I'd like to stay in the native skin as much as possible. >> >> Another method would be to count how many messages I write, but then I'd >> need some hook that notifies me when the user space program reads a >> message so I can decrement the count. >> >> Any ideas? > > > The plan is to be able to tell the pipe manager to use a user-provided > heap instead of the system one; this way, exhausting the local heap > (*) in RT space would be a clear sign that non-RT must be allowed to > consume the pending data first. A simple interface to do that is > missing, but the pipe manager already works with a variable heap pointer. That mechanism would work only if you allow a local heap for *each* pipe (otherwise one abused pipe may clobber others). Personally, I need this feature to manage extreme error cases (the user process dying). There is no point in knowing when the non-RT processing is overwhelmed, because if that happens there is nothing you can do. If you are producing more RT data that your non-RT processes can consume, then you'll exhaust storage sooner or later. If you have RT data production peaks, it's your responsibility to allocate enough storage to provide for the worst case. In other words. RT processes may *never* have to wait for non-RT processes, because then they would become also non-RT. So, the only use I can think of for limited pipe storage (be it in message count or used memory) is to detect fatal error conditions, such as the case of no one consuming data. And at least in my case, I absolutely need this feature (if the non-RT process dies for any reason, the system must not collapse). > > (*) Using the overall available memory seems a better metric than the > number of pending messages, since it may often happen that messages > have different sizes. > Mmm... yeah, you are probably right. I mentioned the number of messages because I noticed the elems field in the queue structure and though it would be easier to implement using it. However, being this limitation just an "electric fence" for out of hand scenarios, the way you express the limit is not critial. If no one is consuming data from non-RT space, the limit will be reached no matter if you express it as messages or as memory. Nacho. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-core] rt_pipe_* usage 2005-11-14 15:56 ` [Xenomai-core] rt_pipe_* usage Ignacio García Pérez 2005-11-14 16:15 ` [Xenomai-core] More on rt pipes usage Ignacio García Pérez @ 2005-11-14 16:23 ` Dmitry Adamushko 2005-11-14 16:36 ` Ignacio García Pérez 1 sibling, 1 reply; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-14 16:23 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai [-- Attachment #1: Type: text/plain, Size: 2425 bytes --] xenomai-core-bounces@domain.hid wrote on 14.11.2005 16:56:01: > Hi, > > I'm having now my first contact with the pipe framework, an have some > comments about it that might be of interest to the core developers: > > While the documentation is overall *great*, I fould it a bit lacking > regarding the pipes. Would be good to have some examples of general usage. You may take a look at testsuite/klatency example that uses a pipe for rt kernel-mode task ---> normal linux task communication. > > As far as I can tell, there is no mention of the usage of P_MSGPTR and > P_MSGSIZE. I had to learn about them in the headers. > > At first sight, the rt_pipe_send call is confusing: why should I pass > the data size since it is supposed to be embedded in the RT_PIPE_MSG > structure?. > > This is what I first did: > > RT_PIPE_MSG *m = rt_pipe_alloc(sizeof(mystruct)); > P_MSGPTR(m) = &mystruct; > P_MSGSIZE(m) = sizeof(mystruct) > rt_pipe_send(&mypipe, m, sizeof(mystruct), P_NORMAL); rt_pipe_write() { ... msg = rt_pipe_alloc(size); if (!msg) return -ENOMEM; memcpy(P_MSGPTR(msg),buf,size); <---- copying, not storing a pointer like you did nbytes = rt_pipe_send(pipe,msg,size,mode); ... Actually, if you have already a buffer filled with data, you may directly use a rt_pipe_write() call. > > Which is obviously wrong. Please correct me if I'm wrong: > > P_MSGPTR and P_MSGSIZE are intended not to be used as an lvalue (is > there a way to define these macros to generate a compile error if they > are?). > > So, the correct way would be something like this (again, correct me if > I'm wrong):: > > RT_PIPE_MSG *m = rt_pipe_alloc(sizeof(mystruct_t)); > mystruct_t *p = (mystruct_t *)P_MSGPTR(m); > p->whatever1 = X; > p->whatever2 = X; > rt_pipe_send(&mypipe, m, sizeof(mystruct_t), P_NORMAL); > > If this is correct, why do I have to specify the size of mystruct_t > *twice*. Can't it be initialized by rt_pipe_alloc ?. It's initialized actually (*). RT_PIPE_MSG *rt_pipe_alloc (size_t size) { RT_PIPE_MSG *msg = (RT_PIPE_MSG *)xnheap_alloc(__pipe_heap,size + sizeof(RT_PIPE_MSG)); if (msg) { inith(&msg->link); msg->size = size; <--- (*) } return msg; } Please take a look at testsuite/klatency/latency_module.c : latency() for a correct use of the rt_pipe_alloc/send() calls. > > Nacho. > --- Best regards, Dmitry [-- Attachment #2: Type: text/html, Size: 3405 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-core] rt_pipe_* usage 2005-11-14 16:23 ` [Xenomai-core] rt_pipe_* usage Dmitry Adamushko @ 2005-11-14 16:36 ` Ignacio García Pérez 2005-11-15 12:41 ` [Xenomai-core] Web site error (API doc search) Ignacio García Pérez 2005-11-15 13:16 ` [Xenomai-core] rt_pipe_* usage Philippe Gerum 0 siblings, 2 replies; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-14 16:36 UTC (permalink / raw) To: Dmitry Adamushko; +Cc: xenomai > > > > RT_PIPE_MSG *m = rt_pipe_alloc(sizeof(mystruct_t)); > > mystruct_t *p = (mystruct_t *)P_MSGPTR(m); > > p->whatever1 = X; > > p->whatever2 = X; > > rt_pipe_send(&mypipe, m, sizeof(mystruct_t), P_NORMAL); > > > > If this is correct, why do I have to specify the size of mystruct_t > > *twice*. Can't it be initialized by rt_pipe_alloc ?. > > It's initialized actually (*). > So, what's the sense of having to specify it again whet calling rt_pipe_send ? ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] Web site error (API doc search) 2005-11-14 16:36 ` Ignacio García Pérez @ 2005-11-15 12:41 ` Ignacio García Pérez 2005-11-15 13:16 ` [Xenomai-core] rt_pipe_* usage Philippe Gerum 1 sibling, 0 replies; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-15 12:41 UTC (permalink / raw) To: xenomai Hi, When I use the search function in the online API documentation, firefox (1.0.7) downloads search.php. I guess something is fouled up. Nacho. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-core] rt_pipe_* usage 2005-11-14 16:36 ` Ignacio García Pérez 2005-11-15 12:41 ` [Xenomai-core] Web site error (API doc search) Ignacio García Pérez @ 2005-11-15 13:16 ` Philippe Gerum 2005-11-15 16:22 ` Ignacio García Pérez 1 sibling, 1 reply; 53+ messages in thread From: Philippe Gerum @ 2005-11-15 13:16 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai Ignacio García Pérez wrote: >>>RT_PIPE_MSG *m = rt_pipe_alloc(sizeof(mystruct_t)); >>>mystruct_t *p = (mystruct_t *)P_MSGPTR(m); >>>p->whatever1 = X; >>>p->whatever2 = X; >>>rt_pipe_send(&mypipe, m, sizeof(mystruct_t), P_NORMAL); >>> >>>If this is correct, why do I have to specify the size of mystruct_t >>>*twice*. Can't it be initialized by rt_pipe_alloc ?. >> >>It's initialized actually (*). >> > > So, what's the sense of having to specify it again whet calling > rt_pipe_send ? > Because you may (pre-)allocate more than you really need to send afterwards. -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-core] rt_pipe_* usage 2005-11-15 13:16 ` [Xenomai-core] rt_pipe_* usage Philippe Gerum @ 2005-11-15 16:22 ` Ignacio García Pérez 2005-11-16 5:38 ` Philippe Gerum 0 siblings, 1 reply; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-15 16:22 UTC (permalink / raw) To: Philippe Gerum; +Cc: xenomai [-- Attachment #1: Type: text/plain, Size: 750 bytes --] Philippe Gerum wrote: > Ignacio García Pérez wrote: > >>>> RT_PIPE_MSG *m = rt_pipe_alloc(sizeof(mystruct_t)); >>>> mystruct_t *p = (mystruct_t *)P_MSGPTR(m); >>>> p->whatever1 = X; >>>> p->whatever2 = X; >>>> rt_pipe_send(&mypipe, m, sizeof(mystruct_t), P_NORMAL); >>>> >>>> If this is correct, why do I have to specify the size of mystruct_t >>>> *twice*. Can't it be initialized by rt_pipe_alloc ?. >>> >>> >>> It's initialized actually (*). >>> >> >> So, what's the sense of having to specify it again whet calling >> rt_pipe_send ? >> > > Because you may (pre-)allocate more than you really need to send > afterwards. > I guess this should be explained in the docs. Please consider the small patch I attach. Nacho. [-- Attachment #2: patch.diff --] [-- Type: text/plain, Size: 844 bytes --] Index: skins/native/pipe.c =================================================================== --- skins/native/pipe.c (revision 143) +++ skins/native/pipe.c (working copy) @@ -598,7 +598,11 @@ * * @param size The size in bytes of the message (payload data * only). Zero is a valid value, in which case the service returns - * immediately without sending any message. + * immediately without sending any message. This parameter allows + * you to actually send less data than you reserved using the + * rt_pipe_alloc() service, which may be the case if you did not + * know how much space you needed at the time of allocation. In all + * other cases it may be more convenient to just pass P_MSGSIZE(msg). * * Additionally, rt_pipe_send() causes any data buffered by * rt_pipe_stream() to be flushed prior to sending the message. For ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-core] rt_pipe_* usage 2005-11-15 16:22 ` Ignacio García Pérez @ 2005-11-16 5:38 ` Philippe Gerum 0 siblings, 0 replies; 53+ messages in thread From: Philippe Gerum @ 2005-11-16 5:38 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai Ignacio García Pérez wrote: > Philippe Gerum wrote: > > >>Ignacio García Pérez wrote: >> >> >>>>>RT_PIPE_MSG *m = rt_pipe_alloc(sizeof(mystruct_t)); >>>>>mystruct_t *p = (mystruct_t *)P_MSGPTR(m); >>>>>p->whatever1 = X; >>>>>p->whatever2 = X; >>>>>rt_pipe_send(&mypipe, m, sizeof(mystruct_t), P_NORMAL); >>>>> >>>>>If this is correct, why do I have to specify the size of mystruct_t >>>>>*twice*. Can't it be initialized by rt_pipe_alloc ?. >>>> >>>> >>>>It's initialized actually (*). >>>> >>> >>>So, what's the sense of having to specify it again whet calling >>>rt_pipe_send ? >>> >> >>Because you may (pre-)allocate more than you really need to send >>afterwards. >> > > I guess this should be explained in the docs. Please consider the small > patch I attach. > Ok, applied. Thanks. > Nacho. > > > ------------------------------------------------------------------------ > > Index: skins/native/pipe.c > =================================================================== > --- skins/native/pipe.c (revision 143) > +++ skins/native/pipe.c (working copy) > @@ -598,7 +598,11 @@ > * > * @param size The size in bytes of the message (payload data > * only). Zero is a valid value, in which case the service returns > - * immediately without sending any message. > + * immediately without sending any message. This parameter allows > + * you to actually send less data than you reserved using the > + * rt_pipe_alloc() service, which may be the case if you did not > + * know how much space you needed at the time of allocation. In all > + * other cases it may be more convenient to just pass P_MSGSIZE(msg). > * > * Additionally, rt_pipe_send() causes any data buffered by > * rt_pipe_stream() to be flushed prior to sending the message. For -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] Re: [Xenomai-help] printk 2005-11-14 14:50 ` [Xenomai-core] " Dmitry Adamushko 2005-11-14 15:56 ` [Xenomai-core] rt_pipe_* usage Ignacio García Pérez @ 2005-11-15 9:38 ` Philippe Gerum 2005-11-15 10:00 ` Dmitry Adamushko 1 sibling, 1 reply; 53+ messages in thread From: Philippe Gerum @ 2005-11-15 9:38 UTC (permalink / raw) To: Dmitry Adamushko; +Cc: xenomai, xenomai Dmitry Adamushko wrote: > > > ... > > > > > > This cannot happen in async mode, since the output would be > buffered and > > > printk() never called on behalf of the preempted handler. > > > > > >> > > >> let's say at the (*) point > > >> > > >> void __ipipe_flush_printk (unsigned virq) > > >> { > > >> char *p = __ipipe_printk_buf; > > >> int out = 0, len; > > >> > > >> clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); > > >> > > >> while (out < __ipipe_printk_fill) { > > >> len = strlen(p) + 1; > > >> printk("%s",p); > > >> p += len; > > >> out += len; > > >> } > > >> (*) <---------------------------- preempted > > >> __ipipe_printk_fill = 0; > > >> } > > >> > > >> When linux gets controll back the virq continues its execution and > > >> sets __ipipe_printk_fill up to 0. > > >> > > >> This cannot happen only if virqs are manipulated with the primary > > >> domain being stalled as well. But you told "and under __Linux > > >> domain___ stalling protection in __ipipe_flush_printk since it's a > > >> virq handler". > > >> > > >> > > >> > and finally, printk() cannot preempt > > >> > __ipipe_flush_printk under normal operation mode (i.e. async > mode). > > >> AFAICS, > > >> > there's no race here. > > > > Mea culpa, Dmitry is right, in the above situation he depicted, we > > could drop a > > portion of the output buffer. A way to fix this would be to hw lock > > a test and > > decrement section of __ipipe_printk_fill in the flush handler. > > > > Something like that (just a draft) would work probably but I suppose > something a bit more graceful would be implemented. Actually, with a > small optimization of IPIPE_PRINTK_FLAG. > > void __ipipe_flush_printk (unsigned virq) > { > char *p = __ipipe_printk_buf; > - int out = 0, len; > + int out = 0, len, used; > > ... > - clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); > ... > > + spin_lock_irqsave_hw(&__ipipe_printk_lock,flags); > + used = __ipipe_printk_fill; > + spin_unlock_irqrestore_hw(&__ipipe_printk_lock,flags); > > + oncemore: > > while (out < used) { > len = strlen(p) + 1; > printk("%s",p); > p += len; > out += len; > } > > + spin_lock_irqsave_hw(&__ipipe_printk_lock,flags); > + if (__ipipe_printk_fill == used) > + { > - __ipipe_printk_fill = 0; > > + used = __ipipe_printk_fill = 0; > > + // when everything is done > + clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); > > + } > + else > + used = __ipipe_printk_fill; > + spin_unlock_irqrestore_hw(&__ipipe_printk_lock,flags); > > + if (used) > + goto oncemore; > > ... > } > > and > > asmlinkage int printk(const char *fmt, ...) > { > + int virq_is_active; > ... > > spin_lock_irqsave_hw(&__ipipe_printk_lock,flags); > > fbytes = __LOG_BUF_LEN - __ipipe_printk_fill; > > if (fbytes > 1) { > r = vscnprintf(__ipipe_printk_buf + __ipipe_printk_fill, > fbytes, fmt, args) + 1; /* account for the > null byte */ > __ipipe_printk_fill += r; > } else > r = 0; > > + virq_is_active = > test_and_set_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); > > spin_unlock_irqrestore_hw(&__ipipe_printk_lock,flags); > > - if (!test_and_set_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags)) > + if (!virq_is_active) > ipipe_trigger_irq(__ipipe_printk_virq); > out: > va_end(args); > > return r; > } > Another approach is about dropping the non-atomic update sequence that hurts, tolerating null runs of the virq when the seldom preemption case is seen, but without requiring hw interrupt masking to protect the shared stuff. Livelocking Linux inside the virq handler would still be possible whenever the RT side spams the kernel log, but this would not be an issue for us, since there is no such thing as a fair real-time system anyway. --- kernel/printk.c 2 Nov 2005 16:29:34 -0000 1.2 +++ kernel/printk.c 15 Nov 2005 09:11:33 -0000 @@ -511,24 +511,23 @@ static ipipe_spinlock_t __ipipe_printk_lock = IPIPE_SPIN_LOCK_UNLOCKED; -static int __ipipe_printk_fill; +static atomic_t __ipipe_printk_fill; static char __ipipe_printk_buf[__LOG_BUF_LEN]; void __ipipe_flush_printk (unsigned virq) { char *p = __ipipe_printk_buf; - int out = 0, len; + int len; - clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); - - while (out < __ipipe_printk_fill) { - len = strlen(p) + 1; - printk("%s",p); - p += len; - out += len; + while (test_and_clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags)) { + while (atomic_read(&__ipipe_printk_fill) > 0) { + len = strlen(p) + 1; + printk("%s",p); + p += len; + atomic_sub(len,&__ipipe_printk_fill); + } } - __ipipe_printk_fill = 0; } asmlinkage int printk(const char *fmt, ...) @@ -548,12 +547,12 @@ spin_lock_irqsave_hw(&__ipipe_printk_lock,flags); - fbytes = __LOG_BUF_LEN - __ipipe_printk_fill; + fbytes = __LOG_BUF_LEN - atomic_read(&__ipipe_printk_fill); if (fbytes > 1) { - r = vscnprintf(__ipipe_printk_buf + __ipipe_printk_fill, + r = vscnprintf(__ipipe_printk_buf + atomic_read(&__ipipe_printk_fill), fbytes, fmt, args) + 1; /* account for the null byte */ - __ipipe_printk_fill += r; + atomic_add(r,&__ipipe_printk_fill); } else r = 0; -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] Re: [Xenomai-help] printk 2005-11-15 9:38 ` [Xenomai-core] Re: [Xenomai-help] printk Philippe Gerum @ 2005-11-15 10:00 ` Dmitry Adamushko 2005-11-16 12:58 ` Philippe Gerum 0 siblings, 1 reply; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-15 10:00 UTC (permalink / raw) To: Philippe Gerum; +Cc: xenomai, xenomai [-- Attachment #1: Type: text/plain, Size: 3079 bytes --] please see comments below... > > Another approach is about dropping the non-atomic update sequence > that hurts, tolerating > null runs of the virq when the seldom preemption case is seen, but > without requiring hw > interrupt masking to protect the shared stuff. Livelocking Linux > inside the virq handler > would still be possible whenever the RT side spams the kernel log, > but this would not be > an issue for us, since there is no such thing as a fair real-time > system anyway. > > --- kernel/printk.c 2 Nov 2005 16:29:34 -0000 1.2 > +++ kernel/printk.c 15 Nov 2005 09:11:33 -0000 > @@ -511,24 +511,23 @@ > > static ipipe_spinlock_t __ipipe_printk_lock = IPIPE_SPIN_LOCK_UNLOCKED; > > -static int __ipipe_printk_fill; > +static atomic_t __ipipe_printk_fill; > > static char __ipipe_printk_buf[__LOG_BUF_LEN]; > > void __ipipe_flush_printk (unsigned virq) > { > char *p = __ipipe_printk_buf; > - int out = 0, len; > + int len; > > - clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); > - > - while (out < __ipipe_printk_fill) { > - len = strlen(p) + 1; > - printk("%s",p); > - p += len; > - out += len; > + while (test_and_clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags)) { > + while (atomic_read(&__ipipe_printk_fill) > 0) { > + len = strlen(p) + 1; > + printk("%s",p); > + p += len; > + atomic_sub(len,&__ipipe_printk_fill); But that's wrong. __ipipe_printk_fill is used as an index in printk() and here you use it as a number of bytes still need to be printed. let's suppose: p = __ipipe_printk_buf = [ 5 bytes \0] [10 bytes \0] __ipipe_printk_fill == 17; 1) first iteration of __ipipe_flush_printk 5-byte string is printed out p = __ipipe_printk_buf + 6 ---> [10 bytes \0] __ipipe_printk_fill == 11; ... In the mean time, on another CPU: 2) printk() does > + r = vscnprintf(__ipipe_printk_buf + atomic_read(&__ipipe_printk_fill), > fbytes, fmt, args) + 1; /* account for the null byte */ __ipipe_printk_buf + atomic_read(&__ipipe_printk_fill) == __ipipe_printk_buf + 11 and that points right in the middle of the still non-printed 10-bytes long string [5 bytes \0] [10 bytes (*** this will be broken ***) \0] So we are loosing data again. is something wrong? anyway, there must be a small correction somewhere around :) > + } > } > - __ipipe_printk_fill = 0; > } > > asmlinkage int printk(const char *fmt, ...) > @@ -548,12 +547,12 @@ > > spin_lock_irqsave_hw(&__ipipe_printk_lock,flags); > > - fbytes = __LOG_BUF_LEN - __ipipe_printk_fill; > + fbytes = __LOG_BUF_LEN - atomic_read(&__ipipe_printk_fill); > > if (fbytes > 1) { > - r = vscnprintf(__ipipe_printk_buf + __ipipe_printk_fill, > + r = vscnprintf(__ipipe_printk_buf + atomic_read(&__ipipe_printk_fill), > fbytes, fmt, args) + 1; /* account for the null byte */ > - __ipipe_printk_fill += r; > + atomic_add(r,&__ipipe_printk_fill); > } else > r = 0; > > -- > > Philippe. --- Dmitry [-- Attachment #2: Type: text/html, Size: 4572 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] Re: [Xenomai-help] printk 2005-11-15 10:00 ` Dmitry Adamushko @ 2005-11-16 12:58 ` Philippe Gerum 2005-11-16 14:44 ` Dmitry Adamushko 2005-11-17 9:44 ` [Xenomai-help] Blocking reads from pipes Ignacio García Pérez 0 siblings, 2 replies; 53+ messages in thread From: Philippe Gerum @ 2005-11-16 12:58 UTC (permalink / raw) To: Dmitry Adamushko; +Cc: xenomai, xenomai Dmitry Adamushko wrote: > please see comments below... > > > > > Another approach is about dropping the non-atomic update sequence > > that hurts, tolerating > > null runs of the virq when the seldom preemption case is seen, but > > without requiring hw > > interrupt masking to protect the shared stuff. Livelocking Linux > > inside the virq handler > > would still be possible whenever the RT side spams the kernel log, > > but this would not be > > an issue for us, since there is no such thing as a fair real-time > > system anyway. > > > > --- kernel/printk.c 2 Nov 2005 16:29:34 -0000 1.2 > > +++ kernel/printk.c 15 Nov 2005 09:11:33 -0000 > > @@ -511,24 +511,23 @@ > > > > static ipipe_spinlock_t __ipipe_printk_lock = IPIPE_SPIN_LOCK_UNLOCKED; > > > > -static int __ipipe_printk_fill; > > +static atomic_t __ipipe_printk_fill; > > > > static char __ipipe_printk_buf[__LOG_BUF_LEN]; > > > > void __ipipe_flush_printk (unsigned virq) > > { > > char *p = __ipipe_printk_buf; > > - int out = 0, len; > > + int len; > > > > - clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); > > - > > - while (out < __ipipe_printk_fill) { > > - len = strlen(p) + 1; > > - printk("%s",p); > > - p += len; > > - out += len; > > + while > (test_and_clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags)) { > > + while (atomic_read(&__ipipe_printk_fill) > 0) { > > + len = strlen(p) + 1; > > + printk("%s",p); > > + p += len; > > > + atomic_sub(len,&__ipipe_printk_fill); > > But that's wrong. __ipipe_printk_fill is used as an index in printk() > and here you use it as a number of bytes still need to be printed. > Ok, this kind of stuff should always be designed with the brain turned on. Now that I have eventually found the power switch, I'm going to fix the printk issue in the Adeos core along the following lines. The code below basically reworks your proposal. The construct is still a bit hairy, but unfortunately, we cannot just go for using a plain atomic compare-and-exchange op in the virq handler, since we need to serialize its activation among all CPUs - sigh... We also get rid of PPRINTK - which is redundant - in the same move. --- ipipe/v2.6/2.6.14/kernel/printk.c 2 Nov 2005 16:29:34 -0000 1.2 +++ ipipe/v2.6/2.6.14/kernel/printk.c 16 Nov 2005 12:18:09 -0000 @@ -518,23 +518,34 @@ void __ipipe_flush_printk (unsigned virq) { char *p = __ipipe_printk_buf; - int out = 0, len; + int len, lmax, out = 0; + unsigned long flags; - clear_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags); + goto start; - while (out < __ipipe_printk_fill) { - len = strlen(p) + 1; - printk("%s",p); - p += len; - out += len; + do { + spin_unlock_irqrestore_hw(&__ipipe_printk_lock,flags); + start: + lmax = __ipipe_printk_fill; + while (out < lmax) { + len = strlen(p) + 1; + printk("%s",p); + p += len; + out += len; + } + spin_lock_irqsave_hw(&__ipipe_printk_lock,flags); } + while (__ipipe_printk_fill != lmax); + __ipipe_printk_fill = 0; + + spin_unlock_irqrestore_hw(&__ipipe_printk_lock,flags); } asmlinkage int printk(const char *fmt, ...) { - unsigned long flags; - int r, fbytes; + int r, fbytes, oldcount; + unsigned long flags; va_list args; va_start(args, fmt); @@ -548,7 +559,8 @@ spin_lock_irqsave_hw(&__ipipe_printk_lock,flags); - fbytes = __LOG_BUF_LEN - __ipipe_printk_fill; + oldcount = __ipipe_printk_fill; + fbytes = __LOG_BUF_LEN - oldcount; if (fbytes > 1) { r = vscnprintf(__ipipe_printk_buf + __ipipe_printk_fill, @@ -559,7 +571,7 @@ spin_unlock_irqrestore_hw(&__ipipe_printk_lock,flags); - if (!test_and_set_bit(IPIPE_PPRINTK_FLAG,&ipipe_root_domain->flags)) + if (oldcount == 0) ipipe_trigger_irq(__ipipe_printk_virq); out: va_end(args); -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] Re: [Xenomai-help] printk 2005-11-16 12:58 ` Philippe Gerum @ 2005-11-16 14:44 ` Dmitry Adamushko 2005-11-17 9:44 ` [Xenomai-help] Blocking reads from pipes Ignacio García Pérez 1 sibling, 0 replies; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-16 14:44 UTC (permalink / raw) To: Philippe Gerum; +Cc: xenomai, xenomai [-- Attachment #1: Type: text/plain, Size: 723 bytes --] Philippe Gerum <rpm@xenomai.org> wrote on 16.11.2005 13:58:45: > ... > > Ok, this kind of stuff should always be designed with the brain turned on. Now > that I have eventually found the power switch, I'm going to fix the > printk issue > in the Adeos core along the following lines. The code below basically reworks > your proposal. The construct is still a bit hairy, but > unfortunately, we cannot > just go for using a plain atomic compare-and-exchange op in the virq handler, > since we need to serialize its activation among all CPUs - sigh... > We also get rid > of PPRINTK - which is redundant - in the same move. Yep, this implementation looks at least sane to me now. > ... > -- > > Philippe. > --- Dmitry [-- Attachment #2: Type: text/html, Size: 1015 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-help] Blocking reads from pipes 2005-11-16 12:58 ` Philippe Gerum 2005-11-16 14:44 ` Dmitry Adamushko @ 2005-11-17 9:44 ` Ignacio García Pérez 2005-11-17 10:21 ` Romain Lenglet 2005-11-17 10:46 ` Dmitry Adamushko 1 sibling, 2 replies; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-17 9:44 UTC (permalink / raw) To: xenomai Hi, My application consists of a real time module and a non-realtime user mode program. They communicate through several pipes. The user mode program creates a thread (pthread) that opens a pipe and blocks in a read call, waiting for data. Under certain conditions, the user mode program must do an orderly exit, and thus I need a way to unblock that thread. I've done that in the past with sockets. If you have one thread blocked reading from a socket handle, and you close it from another thread, the read call will immediately return with an error code. However, that doesn't seem to work with xenomai pipes. One posix thread blocked reading from a pipe (using posix open/read) won't unblock when you close the file handle from another thread. Any suggestions? Thanks. Nacho. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] Blocking reads from pipes 2005-11-17 9:44 ` [Xenomai-help] Blocking reads from pipes Ignacio García Pérez @ 2005-11-17 10:21 ` Romain Lenglet 2005-11-17 13:16 ` Ignacio García Pérez 2005-11-17 10:46 ` Dmitry Adamushko 1 sibling, 1 reply; 53+ messages in thread From: Romain Lenglet @ 2005-11-17 10:21 UTC (permalink / raw) To: xenomai [-- Attachment #1: Type: text/plain, Size: 705 bytes --] > One posix thread blocked reading from a pipe (using posix > open/read) won't unblock when you close the file handle from > another thread. Yes, it does! Compile the two attached source files: $ gcc -o read read.c $ gcc -o close close.c Create the named pipe: $ mkfifo testfifo In two different terminals, run "read", which will block in read(), then "close". You will remark that the blocking read call is unblocked when the other process closes its descriptor. As a conclusion, the behaviour that you observed with Xenomai pipes seems consistent with that of Linux' named pipes, except that in Linux read() returns 0, and not an error code as you observed with Xenomai. -- Romain Lenglet [-- Attachment #2: close.c --] [-- Type: text/x-csrc, Size: 276 bytes --] #include <stdio.h> #include <fcntl.h> #define SIZE 1024 int main (int argc, char **argv) { int desc; int nread; char buf[SIZE]; desc = open ("./testfifo", O_WRONLY); if (desc == -1) { perror (argv[0]); return 1; } close (desc); return 0; } [-- Attachment #3: read.c --] [-- Type: text/x-csrc, Size: 517 bytes --] #include <stdio.h> #include <fcntl.h> #define SIZE 1024 int main (int argc, char **argv) { int desc; int nread; char buf[SIZE]; desc = open ("./testfifo", O_RDONLY); if (desc == -1) { perror (argv[0]); return 1; } while ((nread = read (desc, buf, SIZE)) > 0) { buf[nread] = 0; printf ("child received \"%s\" (%d)\n", buf, nread); } if (nread == 0) printf ("child received 0 bytes!\n"); if (nread == -1) perror (argv[0]); close (desc); return 0; } ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] Blocking reads from pipes 2005-11-17 10:21 ` Romain Lenglet @ 2005-11-17 13:16 ` Ignacio García Pérez 2005-11-17 15:11 ` Dmitry Adamushko 0 siblings, 1 reply; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-17 13:16 UTC (permalink / raw) To: Romain Lenglet; +Cc: xenomai >As a conclusion, the behaviour that you observed with Xenomai >pipes seems consistent with that of Linux' named pipes, except >that in Linux read() returns 0, and not an error code as you >observed with Xenomai. > > The read() call does *not* return when you close the *same* file handle from another pthread in the same process. Is that the expected posix behaviour? Nacho. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] Blocking reads from pipes 2005-11-17 13:16 ` Ignacio García Pérez @ 2005-11-17 15:11 ` Dmitry Adamushko 2005-11-17 17:24 ` Gilles Chanteperdrix 0 siblings, 1 reply; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-17 15:11 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai [-- Attachment #1: Type: text/plain, Size: 512 bytes --] > > >As a conclusion, the behaviour that you observed with Xenomai > >pipes seems consistent with that of Linux' named pipes, except > >that in Linux read() returns 0, and not an error code as you > >observed with Xenomai. > > > > > The read() call does *not* return when you close the *same* file handle > from another pthread in the same process. I confirm that and as I pointed it out in my previous mail - this is not how it's supposed to be. I'm currently on it. More news later. > Nacho. > --- Dmitry [-- Attachment #2: Type: text/html, Size: 748 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] Blocking reads from pipes 2005-11-17 15:11 ` Dmitry Adamushko @ 2005-11-17 17:24 ` Gilles Chanteperdrix 2005-11-17 17:55 ` [Xenomai-core] " Dmitry Adamushko 2005-11-17 19:40 ` Dmitry Adamushko 0 siblings, 2 replies; 53+ messages in thread From: Gilles Chanteperdrix @ 2005-11-17 17:24 UTC (permalink / raw) To: Dmitry Adamushko; +Cc: xenomai Dmitry Adamushko wrote: > > > > > >As a conclusion, the behaviour that you observed with Xenomai > > >pipes seems consistent with that of Linux' named pipes, except > > >that in Linux read() returns 0, and not an error code as you > > >observed with Xenomai. > > > > > > > > The read() call does *not* return when you close the *same* file handle > > from another pthread in the same process. > > I confirm that and as I pointed it out in my previous mail - this is not > how it's supposed to be. > I'm currently on it. More news later. I am not sure about that: Linux regular pipes follow the same behaviour (the real destruction of the file descriptor is delayed until read() really returns). -- Gilles Chanteperdrix. ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] Re: [Xenomai-help] Blocking reads from pipes 2005-11-17 17:24 ` Gilles Chanteperdrix @ 2005-11-17 17:55 ` Dmitry Adamushko 2005-11-17 19:17 ` Gilles Chanteperdrix 2005-11-17 19:40 ` Dmitry Adamushko 1 sibling, 1 reply; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-17 17:55 UTC (permalink / raw) To: Gilles Chanteperdrix; +Cc: xenomai, xenomai-core On Thursday 17 November 2005 18:24, Gilles Chanteperdrix wrote: > Dmitry Adamushko wrote: > > > >As a conclusion, the behaviour that you observed with Xenomai > > > >pipes seems consistent with that of Linux' named pipes, except > > > >that in Linux read() returns 0, and not an error code as you > > > >observed with Xenomai. > > > > > > The read() call does *not* return when you close the *same* file > > > handle from another pthread in the same process. > > > > I confirm that and as I pointed it out in my previous mail - this is not > > how it's supposed to be. > > I'm currently on it. More news later. > > I am not sure about that: Linux regular pipes follow the same behaviour > (the real destruction of the file descriptor is delayed until read() > really returns). My assertion was only based on the idea that nucleus::xnpipe_release() must be called as a result of any close() from the user space. And it, in turn, wakes up all the blocked readers. So the current implementation at least should have worked in sych a case. But, well, below is what I have observed. Maybe your assertion may explain that. The reason is actually not because of some problem in the xenomai codebase but because of the fact that nucleus::xnpipe_release() is _not_ called as I expected it to be :o) The experiment was as follows (a slightly changed klatency test): latency_module.ko uses a 10-second wait-interval for sending data int fd; // pipe thread#2 { sleep(3); close(fd); // closing a pipe. Here I expected that nucleus::xnpipe_release() would be // called as a result (== file_operations::release ). } thread#1 { fd = open(/dev/rtpN); pthread_create(thread#2); read(fd, ...); // blocked at least for 10 seconds so thread#2 closes a pipe //earlier ... if (error) break; ... close(fd); } So xnpipe_release() is _not_ called as a result of the close() call in thread#2. close() returns 0 indeed. 10 seconds after its starting, thread#1 :: read() returns a valid block of data from the latency module and right after that - an error code is returned that the pipe is no longer valid. I have taken a very brief look at the linux sources but it was not enough to get an explanation. So I'll take a closer look now :o) --- Dmitry ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] Re: [Xenomai-help] Blocking reads from pipes 2005-11-17 17:55 ` [Xenomai-core] " Dmitry Adamushko @ 2005-11-17 19:17 ` Gilles Chanteperdrix 2005-11-17 19:45 ` Dmitry Adamushko 0 siblings, 1 reply; 53+ messages in thread From: Gilles Chanteperdrix @ 2005-11-17 19:17 UTC (permalink / raw) To: Dmitry Adamushko; +Cc: xenomai, xenomai-core Dmitry Adamushko wrote: > On Thursday 17 November 2005 18:24, Gilles Chanteperdrix wrote: > > Dmitry Adamushko wrote: > > > > >As a conclusion, the behaviour that you observed with Xenomai > > > > >pipes seems consistent with that of Linux' named pipes, except > > > > >that in Linux read() returns 0, and not an error code as you > > > > >observed with Xenomai. > > > > > > > > The read() call does *not* return when you close the *same* file > > > > handle from another pthread in the same process. > > > > > > I confirm that and as I pointed it out in my previous mail - this is not > > > how it's supposed to be. > > > I'm currently on it. More news later. > > > > I am not sure about that: Linux regular pipes follow the same behaviour > > (the real destruction of the file descriptor is delayed until read() > > really returns). > > My assertion was only based on the idea that nucleus::xnpipe_release() must be > called as a result of any close() from the user space. If we have a look at the sources, sys_read uses fput_light and fget_light, which increment and decrement the file descriptor reference count (member f_count of the file structure) used by fget and fput when the file descriptor is shared between. open and close call fget and fput. "release" only get called through __fput when f_count reaches 0. -- Gilles Chanteperdrix. ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] Re: [Xenomai-help] Blocking reads from pipes 2005-11-17 19:17 ` Gilles Chanteperdrix @ 2005-11-17 19:45 ` Dmitry Adamushko 2005-11-18 8:57 ` Ignacio García Pérez 0 siblings, 1 reply; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-17 19:45 UTC (permalink / raw) To: Gilles Chanteperdrix; +Cc: xenomai, xenomai-core On Thursday 17 November 2005 20:17, you wrote: > Dmitry Adamushko wrote: > > On Thursday 17 November 2005 18:24, Gilles Chanteperdrix wrote: > > > Dmitry Adamushko wrote: > > > > > >As a conclusion, the behaviour that you observed with Xenomai > > > > > >pipes seems consistent with that of Linux' named pipes, except > > > > > >that in Linux read() returns 0, and not an error code as you > > > > > >observed with Xenomai. > > > > > > > > > > The read() call does *not* return when you close the *same* file > > > > > handle from another pthread in the same process. > > > > > > > > I confirm that and as I pointed it out in my previous mail - this > > > > is not how it's supposed to be. > > > > I'm currently on it. More news later. > > > > > > I am not sure about that: Linux regular pipes follow the same > > > behaviour (the real destruction of the file descriptor is delayed > > > until read() really returns). > > > > My assertion was only based on the idea that nucleus::xnpipe_release() > > must be > > > > called as a result of any close() from the user space. > > If we have a look at the sources, sys_read uses fput_light and > fget_light, which increment and decrement the file descriptor > reference count (member f_count of the file structure) used by fget and > fput when the file descriptor is shared between. open and close call > fget and fput. > > "release" only get called through __fput when f_count reaches 0. Exactly, I have just found out that and posted actually a long mail just before getting this mail from you :o) Yep, and before getting blocked, read() increments the counter as well, that's why we don't have a xnpipe_realease() called as a result of close(). So everything is correct. --- Dmitry ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] Re: [Xenomai-help] Blocking reads from pipes 2005-11-17 19:45 ` Dmitry Adamushko @ 2005-11-18 8:57 ` Ignacio García Pérez 2005-11-18 9:10 ` Dmitry Adamushko 0 siblings, 1 reply; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-18 8:57 UTC (permalink / raw) To: Dmitry Adamushko; +Cc: xenomai, xenomai-core >Exactly, I have just found out that and posted actually a long mail just >before getting this mail from you :o) > >Yep, and before getting blocked, read() increments the counter as well, that's >why we don't have a xnpipe_realease() called as a result of close(). >So everything is correct. > > Fine. Though then my problem is not related to xenomai, any suggestions on how to force read() to return? (without writing anything to the other end of the pipe) ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-core] Re: [Xenomai-help] Blocking reads from pipes 2005-11-18 8:57 ` Ignacio García Pérez @ 2005-11-18 9:10 ` Dmitry Adamushko 0 siblings, 0 replies; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-18 9:10 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai, xenomai-core [-- Attachment #1: Type: text/plain, Size: 991 bytes --] xenomai-core-bounces@domain.hid wrote on 18.11.2005 09:57:15: > > >Exactly, I have just found out that and posted actually a long mail just > >before getting this mail from you :o) > > > >Yep, and before getting blocked, read() increments the counter as > well, that's > >why we don't have a xnpipe_realease() called as a result of close(). > >So everything is correct. > > > > > Fine. Though then my problem is not related to xenomai, any suggestions > on how to force read() to return? (without writing anything to the other > end of the pipe) ummm... send it a certain signal with pthread_kill() (and setting up something like thread::flag == END_OF_WORK_BABY at the same time but only in case when there can be other cases of getting a signal by this thread)? In such a case, read() should return -EINTR. Note, a signal handler must be installed without a SA_RESTART flag so that the read() will not be restarted after signal processing. --- Dmitry [-- Attachment #2: Type: text/html, Size: 1232 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-core] Re: [Xenomai-help] Blocking reads from pipes 2005-11-17 17:24 ` Gilles Chanteperdrix 2005-11-17 17:55 ` [Xenomai-core] " Dmitry Adamushko @ 2005-11-17 19:40 ` Dmitry Adamushko 1 sibling, 0 replies; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-17 19:40 UTC (permalink / raw) To: xenomai, xenomai-core On Thursday 17 November 2005 18:24, Gilles Chanteperdrix wrote: > Dmitry Adamushko wrote: > > > >As a conclusion, the behaviour that you observed with Xenomai > > > >pipes seems consistent with that of Linux' named pipes, except > > > >that in Linux read() returns 0, and not an error code as you > > > >observed with Xenomai. > > > > > > The read() call does *not* return when you close the *same* file > > > handle from another pthread in the same process. > > > > I confirm that and as I pointed it out in my previous mail - this is not > > how it's supposed to be. > > I'm currently on it. More news later. > > I am not sure about that: Linux regular pipes follow the same behaviour > (the real destruction of the file descriptor is delayed until read() > really returns). Ok, it's me who is a stupid uneducated zorr... I mean bozzo :o) The reason is quite simple indeed. The file_operations::release() is called when a <file *> object is about to be destroyed (file * object is created for each open file). It happens when its refference count becomes 0. Rigth after open() the counter == 1. As one may guess, close() decrease it on 1. There is another entity - file_operations::flush() which is called on each close() call. But file_operations::release() is called only when all the references on the object have been closed. There can be N:1 relation. Imagine, dup() or fork() make a copy of the file descriptor and as a result - the regerence is increased appropriately. Now what happens is that read/write() calls increase the counter before using a file object and decrease it right before returning. thread1::open() --> file_operations::open() == xnpipe_open() ---> counter=1 thread1::read() --> ... counter=2 .. -> file_operations::read() == xnpipe_read() - blocked ... (*) thread2::close() --> ... -> file_operations::flush() [ we don't make use of this one in pipe.c ] --> counter = 1 So that's why xnpipe_release() is not called! 10 seconds have elapsed thread1::read (*) - unblocked() --> copies data to the user's buffer ---> counter = 0. Oooops! As a result -> file_operations::release() is called! Next thread1::read() call returns an error code. So that's what happens. We can define file_operations::flush() and wake up all the readers there. But we can't know that this is a last reference on the file (ok, we can actually but with a bit of hacking). I mean : f = open() -> 1 reference f2 = dup(f) -> the 2-nd close(f); close(f2); 2 flush() calls but only 1 release() so do we need to wake up all the readers if the file is still valid? So well, at least, there is no problem with the xenomai codebase, that's good :o) --- Dmitry ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] Blocking reads from pipes 2005-11-17 9:44 ` [Xenomai-help] Blocking reads from pipes Ignacio García Pérez 2005-11-17 10:21 ` Romain Lenglet @ 2005-11-17 10:46 ` Dmitry Adamushko 1 sibling, 0 replies; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-17 10:46 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai [-- Attachment #1: Type: text/plain, Size: 943 bytes --] > Hi, > > My application consists of a real time module and a non-realtime user > mode program. They communicate through several pipes. > > The user mode program creates a thread (pthread) that opens a pipe and > blocks in a read call, waiting for data. Under certain conditions, the > user mode program must do an orderly exit, and thus I need a way to > unblock that thread. > > I've done that in the past with sockets. If you have one thread blocked > reading from a socket handle, and you close it from another thread, the > read call will immediately return with an error code. > > However, that doesn't seem to work with xenomai pipes. One posix thread > blocked reading from a pipe (using posix open/read) won't unblock when > you close the file handle from another thread. Actually, it should be unblocked but with 0 as a return value. I'll take a look at that. > > Any suggestions? > > Thanks. > > Nacho. --- Best regards, Dmitry [-- Attachment #2: Type: text/html, Size: 1227 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-help] xn_pipe_create [minor] 2005-11-14 10:52 ` Ignacio García Pérez 2005-11-14 11:26 ` Philippe Gerum @ 2005-11-14 12:15 ` Ignacio García Pérez 2005-11-14 13:53 ` Dmitry Adamushko 1 sibling, 1 reply; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-14 12:15 UTC (permalink / raw) To: xenomai Hi, The registry system is great, allows to forget about agreeing about an arbitrary minor number for pipes. But as far as I ca see, you still have to pass an unique "minor" number to rt_pipe_create. What if you have several rt modules?... you must make sure you assign different minor numbers to each pipe!. Wouldn't be useful to have a way to let the rt_pipe_create decide which minor to use? (a free one, of course) Nacho. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] xn_pipe_create [minor] 2005-11-14 12:15 ` [Xenomai-help] xn_pipe_create [minor] Ignacio García Pérez @ 2005-11-14 13:53 ` Dmitry Adamushko 2005-11-14 16:28 ` Ignacio García Pérez 0 siblings, 1 reply; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-14 13:53 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai [-- Attachment #1: Type: text/plain, Size: 1269 bytes --] xenomai-help-bounces@domain.hid wrote on 14.11.2005 13:15:07: > Hi, > > The registry system is great, allows to forget about agreeing about an > arbitrary minor number for pipes. But as far as I ca see, you still have > to pass an unique "minor" number to rt_pipe_create. > > What if you have several rt modules?... you must make sure you assign > different minor numbers to each pipe!. > > Wouldn't be useful to have a way to let the rt_pipe_create decide which > minor to use? (a free one, of course) It can be done and that would work if both sides of the communication channel are real-time threads so a rt_pipe_create/bind() pair may be used to establish a connection. But what should be done if another side is a linux task and uses a mere open() call? Currently, a naming convention is a "/dev/rtpN", N - is a minor being used by rt_pipe_create() and both sides of the channel must be aware of it. Moreover, a client side of the connection may be open even in case there is no server side yet (the one that calls rt_pipe_create) at the mement. In that case, the client is blocked in open(). So the only convention between both sides can be a minor number + pre-created /dev/rtp[0, OPT_PIPE_NRDEV] character devices. > > Nacho. > --- Best regards, Dmitry [-- Attachment #2: Type: text/html, Size: 1580 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] xn_pipe_create [minor] 2005-11-14 13:53 ` Dmitry Adamushko @ 2005-11-14 16:28 ` Ignacio García Pérez 2005-11-14 16:29 ` Philippe Gerum 2005-11-14 16:40 ` [Xenomai-help] xn_pipe_create [minor] Dmitry Adamushko 0 siblings, 2 replies; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-14 16:28 UTC (permalink / raw) To: Dmitry Adamushko; +Cc: xenomai Dmitry Adamushko wrote: > xenomai-help-bounces@domain.hid wrote on 14.11.2005 13:15:07: > > > Hi, > > > > The registry system is great, allows to forget about agreeing about an > > arbitrary minor number for pipes. But as far as I ca see, you still have > > to pass an unique "minor" number to rt_pipe_create. > > > > What if you have several rt modules?... you must make sure you assign > > different minor numbers to each pipe!. > > > > Wouldn't be useful to have a way to let the rt_pipe_create decide which > > minor to use? (a free one, of course) > > It can be done and that would work if both sides of the communication > channel are real-time threads so a rt_pipe_create/bind() pair may be > used to establish a connection. > > But what should be done if another side is a linux task and uses a > mere open() call? > > Currently, a naming convention is a "/dev/rtpN", N - is a minor being > used by rt_pipe_create() and both sides of the channel must be aware > of it. > > Moreover, a client side of the connection may be open even in case > there is no server side yet (the one that calls rt_pipe_create) at the > mement. In that case, the client is blocked in open(). > > So the only convention between both sides can be a minor number + > pre-created /dev/rtp[0, OPT_PIPE_NRDEV] character devices. > Um... I think you are wrong. When the rt task creates a pipe, a symbolik link appears at /proc/xenomai/registry/pipes. Its name is the fifo name, and points to the /dev/rtpN device. That's what I was talking about when I said "clever procfs usage of xenomai". Using this scheme, user mode programs just need to open() /proc/xenomai/registry/pipes/whatever to access a named pipe, without having to know the minor number. Under these circumstances, it would be *very* useful to have rt_pipe_create choose an unused minor automagically (for example passing -1 as the minor). Currently, I'm emulating this by calling rt_pipe_create for minor = 0,1,2... until it succeeds or returns any error different than -EBUSY. Nacho. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] xn_pipe_create [minor] 2005-11-14 16:28 ` Ignacio García Pérez @ 2005-11-14 16:29 ` Philippe Gerum 2005-11-14 16:41 ` Ignacio García Pérez 2005-11-14 16:40 ` [Xenomai-help] xn_pipe_create [minor] Dmitry Adamushko 1 sibling, 1 reply; 53+ messages in thread From: Philippe Gerum @ 2005-11-14 16:29 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai Ignacio García Pérez wrote: > Dmitry Adamushko wrote: > > >>xenomai-help-bounces@domain.hid wrote on 14.11.2005 13:15:07: >> >> >>>Hi, >>> >>>The registry system is great, allows to forget about agreeing about an >>>arbitrary minor number for pipes. But as far as I ca see, you still have >>>to pass an unique "minor" number to rt_pipe_create. >>> >>>What if you have several rt modules?... you must make sure you assign >>>different minor numbers to each pipe!. >>> >>>Wouldn't be useful to have a way to let the rt_pipe_create decide which >>>minor to use? (a free one, of course) >> >>It can be done and that would work if both sides of the communication >>channel are real-time threads so a rt_pipe_create/bind() pair may be >>used to establish a connection. >> >>But what should be done if another side is a linux task and uses a >>mere open() call? >> >>Currently, a naming convention is a "/dev/rtpN", N - is a minor being >>used by rt_pipe_create() and both sides of the channel must be aware >>of it. >> >>Moreover, a client side of the connection may be open even in case >>there is no server side yet (the one that calls rt_pipe_create) at the >>mement. In that case, the client is blocked in open(). >> >>So the only convention between both sides can be a minor number + >>pre-created /dev/rtp[0, OPT_PIPE_NRDEV] character devices. >> > > Um... I think you are wrong. When the rt task creates a pipe, a symbolik > link appears at /proc/xenomai/registry/pipes. Its name is the fifo name, > and points to the /dev/rtpN device. That's what I was talking about when > I said "clever procfs usage of xenomai". > > Using this scheme, user mode programs just need to open() > /proc/xenomai/registry/pipes/whatever to access a named pipe, without > having to know the minor number. > > Under these circumstances, it would be *very* useful to have > rt_pipe_create choose an unused minor automagically (for example passing > -1 as the minor). > Sounds reasonable. > Currently, I'm emulating this by calling rt_pipe_create for minor = > 0,1,2... until it succeeds or returns any error different than -EBUSY. > > Nacho. > > _______________________________________________ > Xenomai-help mailing list > Xenomai-help@domain.hid > https://mail.gna.org/listinfo/xenomai-help > -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] xn_pipe_create [minor] 2005-11-14 16:29 ` Philippe Gerum @ 2005-11-14 16:41 ` Ignacio García Pérez 2005-11-14 16:52 ` Dmitry Adamushko 0 siblings, 1 reply; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-14 16:41 UTC (permalink / raw) To: Philippe Gerum; +Cc: xenomai >> Using this scheme, user mode programs just need to open() >> /proc/xenomai/registry/pipes/whatever to access a named pipe, without >> having to know the minor number. >> >> Under these circumstances, it would be *very* useful to have >> rt_pipe_create choose an unused minor automagically (for example passing >> -1 as the minor). >> > > Sounds reasonable. On the heels of our abs/rel discussion, I suggest to use a #define istead of -1 Will you implement it, or should I give a try? Nacho. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] xn_pipe_create [minor] 2005-11-14 16:41 ` Ignacio García Pérez @ 2005-11-14 16:52 ` Dmitry Adamushko 2005-11-14 17:38 ` Philippe Gerum 2005-11-14 18:03 ` [Xenomai-help] Strange pipe behaviour Ignacio García Pérez 0 siblings, 2 replies; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-14 16:52 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai [-- Attachment #1: Type: text/plain, Size: 867 bytes --] Ignacio García Pérez <iggarpe@domain.hid> wrote on 14.11.2005 17:41:13: > > >> Using this scheme, user mode programs just need to open() > >> /proc/xenomai/registry/pipes/whatever to access a named pipe, without > >> having to know the minor number. > >> > >> Under these circumstances, it would be *very* useful to have > >> rt_pipe_create choose an unused minor automagically (for example passing > >> -1 as the minor). ah.. yep, that's what I have meant with a PIPE_MINOR_AUTO thing :) > >> > > > > Sounds reasonable. > > On the heels of our abs/rel discussion, I suggest to use a #define > istead of -1 > > Will you implement it, or should I give a try? > If you want to have some fun (and you have some time and desire for that) then go ahead :) Otherwise, no problem, I'll do that. > Nacho. > --- Best regards, Dmitry [-- Attachment #2: Type: text/html, Size: 1216 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] xn_pipe_create [minor] 2005-11-14 16:52 ` Dmitry Adamushko @ 2005-11-14 17:38 ` Philippe Gerum 2005-11-14 18:33 ` Dmitry Adamushko 2005-11-14 18:03 ` [Xenomai-help] Strange pipe behaviour Ignacio García Pérez 1 sibling, 1 reply; 53+ messages in thread From: Philippe Gerum @ 2005-11-14 17:38 UTC (permalink / raw) To: Dmitry Adamushko; +Cc: xenomai Dmitry Adamushko wrote: > Ignacio García Pérez <iggarpe@domain.hid> wrote on 14.11.2005 17:41:13: > > > > > >> Using this scheme, user mode programs just need to open() > > >> /proc/xenomai/registry/pipes/whatever to access a named pipe, without > > >> having to know the minor number. > > >> > > >> Under these circumstances, it would be *very* useful to have > > >> rt_pipe_create choose an unused minor automagically (for example > passing > > >> -1 as the minor). > > ah.. yep, that's what I have meant with a PIPE_MINOR_AUTO thing :) > > > >> > > > > > > Sounds reasonable. > > > > On the heels of our abs/rel discussion, I suggest to use a #define > > istead of -1 > > > > Will you implement it, or should I give a try? > > > > If you want to have some fun (and you have some time and desire for > that) then go ahead :) Otherwise, no problem, I'll do that. > Please make sure to implement this at the nucleus level, and if using a bitmap to locate free/busy slots, it should be large enough to handle FDSETSIZE channels, not BITS_PER_LONG. -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] xn_pipe_create [minor] 2005-11-14 17:38 ` Philippe Gerum @ 2005-11-14 18:33 ` Dmitry Adamushko 2005-11-15 8:04 ` Philippe Gerum 0 siblings, 1 reply; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-14 18:33 UTC (permalink / raw) To: rpm; +Cc: xenomai On Monday 14 November 2005 18:38, Philippe Gerum wrote: > xenomai@xenomai.org > > If you want to have some fun (and you have some time and desire for > > that) then go ahead :) Otherwise, no problem, I'll do that. > > > > Please make sure to implement this at the nucleus level, and if using a > bitmap to locate free/busy slots, it should be large enough to handle > FDSETSIZE channels, not BITS_PER_LONG. We have xnpipe_states[XNPIPE_DEVS] array of pipe objects. Choosing a minor value is about choosing a free slot (minor == id of that slot) so there are XNPIPE_DEVS possible values. The bitmap must contain at least XNPIPE_DEVS bits. I don't understand what FDSETSIZE has to do here (if you mean the one that is used to configure select() behaviour). > -- > > Philippe. --- Dmitry ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] xn_pipe_create [minor] 2005-11-14 18:33 ` Dmitry Adamushko @ 2005-11-15 8:04 ` Philippe Gerum 0 siblings, 0 replies; 53+ messages in thread From: Philippe Gerum @ 2005-11-15 8:04 UTC (permalink / raw) To: Dmitry Adamushko; +Cc: xenomai Dmitry Adamushko wrote: > On Monday 14 November 2005 18:38, Philippe Gerum wrote: > >>xenomai@xenomai.org > > >>>If you want to have some fun (and you have some time and desire for >>>that) then go ahead :) Otherwise, no problem, I'll do that. >>> >> >>Please make sure to implement this at the nucleus level, and if using a >>bitmap to locate free/busy slots, it should be large enough to handle >>FDSETSIZE channels, not BITS_PER_LONG. > > > We have xnpipe_states[XNPIPE_DEVS] array of pipe objects. Choosing a minor > value is about choosing a free slot (minor == id of that slot) so there are > XNPIPE_DEVS possible values. The bitmap must contain at least XNPIPE_DEVS > bits. I don't understand what FDSETSIZE has to do here (if you mean the one > that is used to configure select() behaviour). The point is about not being limited to the number of bits in a long, because I know of configurations with more than 32 active channels. IOW, #define XNPIPE_DEVS FDSETSIZE should be possible. > > >>-- >> >>Philippe. > > > --- > > Dmitry > -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-help] Strange pipe behaviour 2005-11-14 16:52 ` Dmitry Adamushko 2005-11-14 17:38 ` Philippe Gerum @ 2005-11-14 18:03 ` Ignacio García Pérez 2005-11-16 5:45 ` Philippe Gerum 1 sibling, 1 reply; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-14 18:03 UTC (permalink / raw) To: xenomai Hi, I have the following piece of code: RT_PIPE_MSG *msg; while ((r = rt_pipe_receive(&mypipe, &msg, TM_INFINITE)) >= 0) { /* whatever */ rt_pipe_free(msg); } When that thread enters, it blocks, as expected, in the rt_pipe_receive call. Then, from user space, I do: echo -en "\x00" > /dev/rtp0 What happens is: 1- rt_pipe_receive returns with r >= 0. 2- /* whatever */ 3- Message is freed using rt_pipe_free. 4- Next call to rt_pipe_receive returns with r = -EINTR. The only explanation I could come up with is that when the pipe is closed by the user mode process, the rt_pipe_receive tells the rt task by returning -EINTR. Is this right?. According to the docs, -EINTR is only returned if rt_task_unblock() has been called... Nacho. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] Strange pipe behaviour 2005-11-14 18:03 ` [Xenomai-help] Strange pipe behaviour Ignacio García Pérez @ 2005-11-16 5:45 ` Philippe Gerum 2005-11-16 7:45 ` Ignacio García Pérez 0 siblings, 1 reply; 53+ messages in thread From: Philippe Gerum @ 2005-11-16 5:45 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai Ignacio García Pérez wrote: > Hi, > > I have the following piece of code: > > RT_PIPE_MSG *msg; > > while ((r = rt_pipe_receive(&mypipe, &msg, TM_INFINITE)) >= 0) { > /* whatever */ > rt_pipe_free(msg); > } > > When that thread enters, it blocks, as expected, in the rt_pipe_receive > call. > > Then, from user space, I do: > > echo -en "\x00" > /dev/rtp0 > > What happens is: > > 1- rt_pipe_receive returns with r >= 0. > 2- /* whatever */ > 3- Message is freed using rt_pipe_free. > 4- Next call to rt_pipe_receive returns with r = -EINTR. > > The only explanation I could come up with is that when the pipe is > closed by the user mode process, the rt_pipe_receive tells the rt task > by returning -EINTR. Is this right?. Yes. According to the docs, -EINTR is > only returned if rt_task_unblock() has been called... > Actually, this is what happened through the internal interface. driver::release(pipe) -> nucleus::unblock(sleepers_on_pipe) > Nacho. > > > > > _______________________________________________ > Xenomai-help mailing list > Xenomai-help@domain.hid > https://mail.gna.org/listinfo/xenomai-help > -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] Strange pipe behaviour 2005-11-16 5:45 ` Philippe Gerum @ 2005-11-16 7:45 ` Ignacio García Pérez 2005-11-16 11:45 ` Philippe Gerum 0 siblings, 1 reply; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-16 7:45 UTC (permalink / raw) To: Philippe Gerum; +Cc: xenomai >> >> 1- rt_pipe_receive returns with r >= 0. >> 2- /* whatever */ >> 3- Message is freed using rt_pipe_free. >> 4- Next call to rt_pipe_receive returns with r = -EINTR. >> >> The only explanation I could come up with is that when the pipe is >> closed by the user mode process, the rt_pipe_receive tells the rt task >> by returning -EINTR. Is this right?. > > > Yes. > > According to the docs, -EINTR is > >> only returned if rt_task_unblock() has been called... >> > > Actually, this is what happened through the internal interface. > driver::release(pipe) -> nucleus::unblock(sleepers_on_pipe) Sure, but that behaviour is *extremely* confusing for a newbie (like me). Should be described in the docs (this time I don't submit a patch because I don't quite understand the pipe internals yet). And anyway, I don't see the point in notifying the RT task that the non-RT end has closed the pipe. Or, in other words, if we want to provide such a notification, we should provide also opening notification. By the way, where is the xnpipe_* API documentation? I could not find it in the online docs (firefox downloads the file search.php when I try to use the search feature). > >> Nacho. >> >> >> >> >> _______________________________________________ >> Xenomai-help mailing list >> Xenomai-help@domain.hid >> https://mail.gna.org/listinfo/xenomai-help >> > > ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] Strange pipe behaviour 2005-11-16 7:45 ` Ignacio García Pérez @ 2005-11-16 11:45 ` Philippe Gerum 0 siblings, 0 replies; 53+ messages in thread From: Philippe Gerum @ 2005-11-16 11:45 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai Ignacio García Pérez wrote: >>>1- rt_pipe_receive returns with r >= 0. >>>2- /* whatever */ >>>3- Message is freed using rt_pipe_free. >>>4- Next call to rt_pipe_receive returns with r = -EINTR. >>> >>>The only explanation I could come up with is that when the pipe is >>>closed by the user mode process, the rt_pipe_receive tells the rt task >>>by returning -EINTR. Is this right?. >> >> >>Yes. >> >> According to the docs, -EINTR is >> >> >>>only returned if rt_task_unblock() has been called... >>> >> >>Actually, this is what happened through the internal interface. >>driver::release(pipe) -> nucleus::unblock(sleepers_on_pipe) > > > Sure, but that behaviour is *extremely* confusing for a newbie (like > me). Should be described in the docs (this time I don't submit a patch > because I don't quite understand the pipe internals yet). > If you understand enough of the API documentation to disagree with it, I guess that you should be able to reword it in a way that seems less error-prone in your eyes. You don't have to explain the gory details of the implementation to do that. > And anyway, I don't see the point in notifying the RT task that the > non-RT end has closed the pipe. Message pipes are connection-oriented thingies. You cannot just let one communication end-point vanish and leave the other side lingering indefinitely without notifying it. Or, in other words, if we want to > provide such a notification, we should provide also opening notification. > That's irrelevant. rt_pipe_connect() from kernel space is semantically similar to open(some_named_fifo,O_RDWR|O_NONBLOCK) from user-space, since the caller does not wait for the other end-point to show up. But even in that case, closing the named fifo at the other side causes any subsequent read() on the connecting side to be notified of the closure. The same goes for message pipes. The only thing you could argue is that read() would first return a zero-sized message first as an end-of-file marker, then an error upon all subsequent reads; since we don't want to forcibly close the kernel side upon user-space closure, a possible change would be to make rt_pipe_recv() return -EPIPE instead of -EINTR in that specific case. And actually, the nucleus interface does provide support for registering a connection notification handler, but it is not exported by the native skin since it would buy us nothing in the context of a regular API. > By the way, where is the xnpipe_* API documentation? I could not find it > in the online docs (firefox downloads the file search.php when I try to > use the search feature). > Still undocumented portion. > >>>Nacho. >>> >>> >>> >>> >>>_______________________________________________ >>>Xenomai-help mailing list >>>Xenomai-help@domain.hid >>>https://mail.gna.org/listinfo/xenomai-help >>> >> >> > > -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] xn_pipe_create [minor] 2005-11-14 16:28 ` Ignacio García Pérez 2005-11-14 16:29 ` Philippe Gerum @ 2005-11-14 16:40 ` Dmitry Adamushko 1 sibling, 0 replies; 53+ messages in thread From: Dmitry Adamushko @ 2005-11-14 16:40 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai [-- Attachment #1: Type: text/plain, Size: 3103 bytes --] Ignacio García Pérez <iggarpe@domain.hid> wrote on 14.11.2005 17:28:24: > Dmitry Adamushko wrote: > > > xenomai-help-bounces@domain.hid wrote on 14.11.2005 13:15:07: > > > > > Hi, > > > > > > The registry system is great, allows to forget about agreeing about an > > > arbitrary minor number for pipes. But as far as I ca see, you still have > > > to pass an unique "minor" number to rt_pipe_create. > > > > > > What if you have several rt modules?... you must make sure you assign > > > different minor numbers to each pipe!. > > > > > > Wouldn't be useful to have a way to let the rt_pipe_create decide which > > > minor to use? (a free one, of course) > > > > It can be done and that would work if both sides of the communication > > channel are real-time threads so a rt_pipe_create/bind() pair may be > > used to establish a connection. > > > > But what should be done if another side is a linux task and uses a > > mere open() call? > > > > Currently, a naming convention is a "/dev/rtpN", N - is a minor being > > used by rt_pipe_create() and both sides of the channel must be aware > > of it. > > > > Moreover, a client side of the connection may be open even in case > > there is no server side yet (the one that calls rt_pipe_create) at the > > mement. In that case, the client is blocked in open(). > > > > So the only convention between both sides can be a minor number + > > pre-created /dev/rtp[0, OPT_PIPE_NRDEV] character devices. > > > Um... I think you are wrong. When the rt task creates a pipe, a symbolik > link appears at /proc/xenomai/registry/pipes. Its name is the fifo name, > and points to the /dev/rtpN device. That's what I was talking about when > I said "clever procfs usage of xenomai". > > Using this scheme, user mode programs just need to open() > /proc/xenomai/registry/pipes/whatever to access a named pipe, without > having to know the minor number. > > Under these circumstances, it would be *very* useful to have > rt_pipe_create choose an unused minor automagically (for example passing > -1 as the minor). > > Currently, I'm emulating this by calling rt_pipe_create for minor = > 0,1,2... until it succeeds or returns any error different than -EBUSY. > Ok, I have missed that point. But one more thing I have pointed out before remains. Currently it's possible to have a client blocked in open(/dev/rtpN, flags) waiting for a pipe to be created (if flags does contain O_NONBLOCK). And it can be done only through /dev/rtpN since there is still nothing at /proc/xenomai/registry/pipe/ (there is no pipe object yet created by the "server" side). Does anybody need that? me, no at the moment. Ok, we can keep actually this functionality as well but just extend the rt_pipe_create() interface to rt_pipe_create (&pipe, whatever_name, PIPE_MINOR_AUTO) so in that case a minor value will be "auto-generated" without a need to bother a user. And the old interface is still can be used. Technically, nothing difficult to implement that. > Nacho. --- Best regards, Dmitry [-- Attachment #2: Type: text/html, Size: 3901 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] printk 2005-11-11 9:30 ` [Xenomai-help] printk Ignacio García Pérez 2005-11-11 11:07 ` Dmitry Adamushko @ 2005-11-12 19:45 ` Philippe Gerum 2005-11-14 10:47 ` [Xenomai-help] Invalid characters in task's names Ignacio García Pérez 2 siblings, 0 replies; 53+ messages in thread From: Philippe Gerum @ 2005-11-12 19:45 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai Ignacio García Pérez wrote: > Hi, > > I'm porting an app from RTAI to Xenomai, and when it came to the > rt_printk function, I had to replace it with plain printk (the > xnarch_log* functions all use printk). > > What I want to know if: > > 1- Is totally safe to call the standard kernel printk function from a > real time task? > Yes. > 2- Even if it's safe, can it affect the performance of a real time task? > (or can it block under *any* conceivable condition?) > No. > Thanks. > > Nacho. > > > > _______________________________________________ > Xenomai-help mailing list > Xenomai-help@domain.hid > https://mail.gna.org/listinfo/xenomai-help > -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* [Xenomai-help] Invalid characters in task's names 2005-11-11 9:30 ` [Xenomai-help] printk Ignacio García Pérez 2005-11-11 11:07 ` Dmitry Adamushko 2005-11-12 19:45 ` [Xenomai-help] printk Philippe Gerum @ 2005-11-14 10:47 ` Ignacio García Pérez 2005-11-14 11:39 ` Philippe Gerum 2 siblings, 1 reply; 53+ messages in thread From: Ignacio García Pérez @ 2005-11-14 10:47 UTC (permalink / raw) To: xenomai Hi, I just noticed "/" is not a valid character for a task's name. Probably something to do with the clever use that xeno makes of the /proc filesystem. Anyway: 1- Are there any other "forbidden" characters? 2- Does this limitation apply to the other named objects? 3- Shouldn't those characters be internally escaped somehow to overcome this limitation? 4- If (2) is not possible, shouldn't this limitation be mentioned in the API documentation. Thanks. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] Invalid characters in task's names 2005-11-14 10:47 ` [Xenomai-help] Invalid characters in task's names Ignacio García Pérez @ 2005-11-14 11:39 ` Philippe Gerum 0 siblings, 0 replies; 53+ messages in thread From: Philippe Gerum @ 2005-11-14 11:39 UTC (permalink / raw) To: Ignacio García Pérez; +Cc: xenomai Ignacio García Pérez wrote: > Hi, > > I just noticed "/" is not a valid character for a task's name. Probably > something to do with the clever use that xeno makes of the /proc > filesystem.: > It's strictly /procfs related, yes. > 1- Are there any other "forbidden" characters? No. > > 2- Does this limitation apply to the other named objects? > Yes. Everything that goes through the registry support. > 3- Shouldn't those characters be internally escaped somehow to overcome > this limitation? > At some point in time, especially the day we add distributed computing facilities, we could find an interesting use of this single reserved character to express object hierarchies too. > 4- If (2) is not possible, shouldn't this limitation be mentioned in the > API documentation. > It is actually. Excerpt from rt_registry_enter()'s documentation: * - -EINVAL is returned if @a key or @a objaddr are NULL, or if @a * key constains an invalid '/' character. The connection between any object creation routine and the registry is clearly stated throughout the documentation, but the indirect use of rt_registry_enter might not be explicitely mentioned though. > Thanks. > > _______________________________________________ > Xenomai-help mailing list > Xenomai-help@domain.hid > https://mail.gna.org/listinfo/xenomai-help > -- Philippe. ^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: [Xenomai-help] Creation of a rt-queue from the user space 2005-11-10 21:05 [Xenomai-help] Creation of a rt-queue from the user space ROSSIER Daniel 2005-11-11 9:30 ` [Xenomai-help] printk Ignacio García Pérez @ 2005-11-11 14:08 ` Jan Kiszka 1 sibling, 0 replies; 53+ messages in thread From: Jan Kiszka @ 2005-11-11 14:08 UTC (permalink / raw) To: ROSSIER Daniel; +Cc: xenomai-help [-- Attachment #1: Type: text/plain, Size: 1779 bytes --] ROSSIER Daniel wrote: > Hello everyone, > > I've recently posted a message in this mailing list about an issue regarding the use of realtime queue in xenomai from the user space. > > I didn't make any significant progress regarding this issue. I've upgraded to linux 2.6.12; everything works in the user/kernel space except the queue. If I correctly understood, it's necessary to have a /dev/rtheap in order to set up a shared memory segment between user and kernel space. > If this entry does not exist, we get an error at the queue creation time. > > I've observed that if I'm creating manually the entry in /dev, I get the same error and the entry disappears from /dev. Then, I've transfered the udev/rtheap.rules located in the xenomai/nucleus directory into /etc/udev/rules.d. But the system totally freezes after xeno-load. > > I've put the segment of code (very simple) for the creation of a simple rt-queue. > > ---------------- > > int main(int argc, char *argv[]) { > > printf("Now starting: %s\n", argv[0]); > > /* Timer initialization */ > err = rt_timer_start(1000000); /* So, one tick will be equal to 1 ms */ > if (err != 0) { > printf("Error timer: %d\n", err); > clean_exit(0); > } > > /* Create the mailbox */ > err = rt_queue_create(&mailbox, "MAILBOX", 80, 1, Q_FIFO); > if (err != 0) { > printf("mbox creation failed: %d\n", err); > clean_exit(0); > } > > ------------ > > Thanks for any support. > > Regards > Daniel > Everything's fine here with your test on 2.6.13.4-ipipe-1.0.09 + Xenomai SVN + /dev/rtheap. Moreover, I don't see a reason why your manually created device node should disappear. Maybe your build is inconsistent in some subtle way. Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 250 bytes --] ^ permalink raw reply [flat|nested] 53+ messages in thread
end of thread, other threads:[~2005-11-18 9:10 UTC | newest] Thread overview: 53+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-11-10 21:05 [Xenomai-help] Creation of a rt-queue from the user space ROSSIER Daniel 2005-11-11 9:30 ` [Xenomai-help] printk Ignacio García Pérez 2005-11-11 11:07 ` Dmitry Adamushko 2005-11-14 10:52 ` Ignacio García Pérez 2005-11-14 11:26 ` Philippe Gerum 2005-11-14 12:03 ` Dmitry Adamushko 2005-11-14 13:22 ` Philippe Gerum 2005-11-14 13:47 ` Philippe Gerum 2005-11-14 14:50 ` [Xenomai-core] " Dmitry Adamushko 2005-11-14 15:56 ` [Xenomai-core] rt_pipe_* usage Ignacio García Pérez 2005-11-14 16:15 ` [Xenomai-core] More on rt pipes usage Ignacio García Pérez 2005-11-15 13:24 ` Philippe Gerum 2005-11-15 16:41 ` [Xenomai-help] " Ignacio García Pérez 2005-11-14 16:23 ` [Xenomai-core] rt_pipe_* usage Dmitry Adamushko 2005-11-14 16:36 ` Ignacio García Pérez 2005-11-15 12:41 ` [Xenomai-core] Web site error (API doc search) Ignacio García Pérez 2005-11-15 13:16 ` [Xenomai-core] rt_pipe_* usage Philippe Gerum 2005-11-15 16:22 ` Ignacio García Pérez 2005-11-16 5:38 ` Philippe Gerum 2005-11-15 9:38 ` [Xenomai-core] Re: [Xenomai-help] printk Philippe Gerum 2005-11-15 10:00 ` Dmitry Adamushko 2005-11-16 12:58 ` Philippe Gerum 2005-11-16 14:44 ` Dmitry Adamushko 2005-11-17 9:44 ` [Xenomai-help] Blocking reads from pipes Ignacio García Pérez 2005-11-17 10:21 ` Romain Lenglet 2005-11-17 13:16 ` Ignacio García Pérez 2005-11-17 15:11 ` Dmitry Adamushko 2005-11-17 17:24 ` Gilles Chanteperdrix 2005-11-17 17:55 ` [Xenomai-core] " Dmitry Adamushko 2005-11-17 19:17 ` Gilles Chanteperdrix 2005-11-17 19:45 ` Dmitry Adamushko 2005-11-18 8:57 ` Ignacio García Pérez 2005-11-18 9:10 ` Dmitry Adamushko 2005-11-17 19:40 ` Dmitry Adamushko 2005-11-17 10:46 ` Dmitry Adamushko 2005-11-14 12:15 ` [Xenomai-help] xn_pipe_create [minor] Ignacio García Pérez 2005-11-14 13:53 ` Dmitry Adamushko 2005-11-14 16:28 ` Ignacio García Pérez 2005-11-14 16:29 ` Philippe Gerum 2005-11-14 16:41 ` Ignacio García Pérez 2005-11-14 16:52 ` Dmitry Adamushko 2005-11-14 17:38 ` Philippe Gerum 2005-11-14 18:33 ` Dmitry Adamushko 2005-11-15 8:04 ` Philippe Gerum 2005-11-14 18:03 ` [Xenomai-help] Strange pipe behaviour Ignacio García Pérez 2005-11-16 5:45 ` Philippe Gerum 2005-11-16 7:45 ` Ignacio García Pérez 2005-11-16 11:45 ` Philippe Gerum 2005-11-14 16:40 ` [Xenomai-help] xn_pipe_create [minor] Dmitry Adamushko 2005-11-12 19:45 ` [Xenomai-help] printk Philippe Gerum 2005-11-14 10:47 ` [Xenomai-help] Invalid characters in task's names Ignacio García Pérez 2005-11-14 11:39 ` Philippe Gerum 2005-11-11 14:08 ` [Xenomai-help] Creation of a rt-queue from the user space Jan Kiszka
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.