Mr. Calianu,

> Let's say the RT Kernel thread is writing into an rtf as fast 
> or slightly
> faster than the user process can consume the data. 

        If slightly faster, the fifo will fill and you will lose data.
Period, end of story.  As a RT systems designer, making sure your user space
process can consume the data faster than it is generated is a big part of
your job.

> There are no
> guarantees that the user process won't hiccup on the data, are there?

        None at all.

> Let's say the rt kernel task keeps writing the string:
> 
> "realtime" into a fifo of precisely 8 bytes, every, oh i dunno, 100ms.
> 
> Now let's say my user process tries to read those 8 bytes. 
> But after the
> 4th byte was interrupted. He just gets the word 'time', and 'real'
> is left in the fifo.

        No no no... He gets the word "real" and "time" is left in the FIFO.
They are FIFOs - First In First Out, so the real in realtime would come out
first.  No reversing necessary.

> Now, the rt-task runs before the user task and
> pushes in the word 'realtime' again, clobbering the word 'real' that
> was left. 

        Hang on a second, let me browse the source...  Your description is
incorrect.  The next time the RT process tries to write "realtime" to the
buffer, it will succeed in writing "real" and the "time" portion will end up
on the floor in a sticky mess of bits.  Unless, of course, your RT task
recognizes this fact by examining the return from rtf_put and acts
accordingly.

> The user process tries to read in what he thinks are the
> remaining 4 bytes from the fifo, but he gets the word 'time' again.

        Nope, he gets the word "time" that he expected.  The problem comes
when he tries to read the next eight and only gets four "real" and then gets
four more and gets "real" again.  It would go something like this:

The RT Process writes: "realtime"
The FIFO contains:     "realtime"
The user process reads: "real" and gets interrupted
The FIFO contains:      "time"
The RT Process tries to write "realtime", only four characters succeed
The FIFO contains:      "timereal"
The user process reads: "time" - the last four characters it was expecting
last read
The FIFO contains:      "real"
The RT Process tries to write "realtime", only four characters succeed
The FIFO contains:      "realreal"
Things go down hill from here.

> (Ok, so in reality the word would be written into the fifo 
> backwards as:
> 'emitlaer' and read in forwards as 'realtime' but you get my point,
> right?).

        I get your point and I also get that you do not seem to understand
FIFOs.  They are FIFOs, not LIFO stacks.  The first thing written is the
first thing read, not the other way around.

> My question is this:  What steps should a programmer take to 
> at least be
> able to discard erroneous or hiccupped data coming from the rt-thread?

        Avoid the erroneous or hiccupped data altogether by following these
three simple steps:

1) Make sure your user space process can consume much more data than your
realtime process can generate.
2) Avoid any unnecessary interruptions to your user space process.
3) Make your FIFOs much larger than required.

        One and two should be obvious.  For three, I simply refuse to have
any FIFO smaller than 16384.  If you are really talking high-volume data,
then larger sizes are appropriate.  Unless you are on an extremely memory
starved machine, huge FIFOs are the simplest solution to your problem.
        
> More specifically, I plan on writing structs into the fifo and reading
> them in userland. 

        Then you are already dooming yourself to a great deal of pain.
Avoid simply using rtf_put on a struct and expecting the same thing in user
space.  That is, of course, unless you are willing to sort through every
compiler option and optimization setting to make absolutely certain that the
structs will be aligned exactly the same way in RT space and user space.  It
would be much better to simply define your own format for the data in the
FIFO and copy out of the struct to a buffer, send the buffer, then copy out
of the buffer into your struct.  This also assures that your code is
maximally portable across platforms, etc.

> I was thinking of delimiting these structs 
> with a few
> bytes that would never appear in the structs themselves, that 
> way the user
> process can synchronize its reads somewhat to those 
> delimiters, as well as
> use magic numbers in the structs to identify the need to synchronize.

        You could do something like that.  To tell you the truth, I have
been getting lazy lately.  My current system writes ASCII format hex data
into the FIFO and reads it at the other end.  I use carriage returns at the
end of each record to do blocking.  It's real easy to tell if I get partial
records, it's real easy on the human trying to debug things, it works great.
On the downside, there is a little overhead on both processes.  Given modern
processors, this isn't a problem for me.  Your mileage may vary.

> Is this overkill?  Is there a simpler approach to this 
> dilemma? Should I
> not be worrying about this as the rtf driver is smarter than I give it
> credit for?

        Nope, it is every bit as dumb as you expect.  The simple solution is
to use big FIFOs and never have a blocking / overflow problem.  If you write
it in there from the RT space, it will be there on the non-RT side.
Alternatively, take my lazy approach and format everything as hex strings
with carriage returns at the end.  

        Please don't expect to rtf_put C structures at one end and get
exactly the same thing at the other without some work and gcc man page
browsing.  Expect this to break with each future release of gcc as well.

> Please help me overcome my fears,

        I expect that I've helped by giving you a whole new set of fears.
Sorry about that - it is a cruel world this RT work.

> PS: I feel kind of uncomfortable writing structs in the fifo 
> in the first
> place, but am too lazy to textualize the data and then 
> re-parse it later.
> :/

        You will be amazed to find that it is *much* easier to textualize /
bufferize it yourself and disassemble the buffers at the other end, rather
than simply writing structs.  You will find this the first time the darned
compiler bites you in the rear end and you spend two days tracking down why
something that obviously works doesn't.  You may not find this until your
version of gcc changes or some such.  By then you won't remember that you
might have a problem.  In that case, expect to spend the whole week tracking
this down.  Creating the buffers properly, on the other hand, will only take
an hour of your life and you will have the pleasure of the knowledge of a
job done properly.  Your choice. :-)

Regards,

Steve Cohen

--------------------------
Stephen D. Cohen
Xybion Sensor Positioning Systems
11528 53rd Street North
Clearwater, FL 33760
Voice: (727) 299-0150
Fax: (727) 299-0804 
[EMAIL PROTECTED]
www.xybion.com

-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
--
For more information on Real-Time Linux see:
http://www.rtlinux.org/

Reply via email to