On Tuesday 25 September 2001 02:58, fred august wrote:
[...]
> 2) I've tried with User space threads that read data
> from the RT thread and do the sends and receives.
> Thought it would be simple but I've had trouble,
> probably due to limited experience.
What OS are you using for the processing part? Unless it's a hard RTOS, I
can't really see why you should use RTL for the communication.
Linux/Lowlatency ("very firm" real time in user space) should do, and
allows you to use the standard Linux drivers.
> First I've tried FIFOs. They would work fine until
> some delay in the transmission. In that case the FIFO
> would "record" that delay and would never catch up,
> i.e. it would be sending old elements waiting in the
> queue. I've tried to flush extra elements out with
> little success.
A very common problem - that's usually easy to solve.
The same things happen in games and GUI toolkits when they receive more
mouse move events than they can respond to. (For example, you might be
dragging a scroller widget that scrolls a window that takes some time to
update.)
The simplest solution is to simply read *all* events (ie empty the FIFO),
parsing them, but not doing anything time consuming in response to events
that are likely to come in large numbers. (Mouse move messages, repeat
key-down messages, high bandwidth sensor data,...) Then, when the
queue/FIFO is empty, check the time, and process the data you just
stuffed in temporary buffers. (Current mouse position, key up/down
states, last data buffer,...)
> I've used mbuff to communicate between RT and user
> space thread that does the UDP send. I thought this
> would solve the FIFO problems and would make more
> sense in general.
I don't think so in this case. Shared memory is basically just a
performance hack when used in this kind of situation. It doesn't add any
functionality; it just forces you to reimplement it - possibly in a way
that fits your application better.
> Unfortunately I can't control the
> speed at which the user space thread sends stuff and,
> if I let it poll for data to send, it will do more
> than one send for each data coming from the RTL
> thread, i.e. will send at a rate higher than 1KHz,
> which is the rate at which the other machine receives
> data. Again this has a "fill up" effect on the
> connection creating a delay.
I can't see why it should send a buffer more than once if you poll... Why
not poll a buffer counter instead of a flag? (Write-only for the RTL
thread, read-only for the user space thread, constantly increasing and
wrapping.)
If you need more power, you can use a lock-free FIFO buffer in shared
memory. You might want to look at my "sfifo" at http://olofson.net/mixed,
although you'd have to tweak it a little to work with shared memory.
(It currently uses it's own [k]malloc()ed buffer, and expects the reader
and writer to be in the same address space. Sooner or later, I'll need a
shared memory version myself, but don't hold your breath...)
Note that the "sfifo" is single-reader/single-writer safe only, and that
the lock-free nature has a side effect; reads and writes cannot block.
It's perfect in situations where you have two threads that mustn't be
able to disturb each other's timing, and blocks on other I/O operations -
such as MIDI input and audio output.
> So I tried to have an attribute "new" attached to each
> piece of data and have the user space thread
> constantly poll this attribute until it's ready to
> poll a new piece of data from RTL. In that case the
> data is read from mbuff, encoded and sent, and the
> attribute is set to "old" again. I thought this would
> work but now the user thread is too slow.
Besides, read/write access from both sides is inherently messy. It's hard
to do it right, so that you don't miss blocks, get extra blocks, end up
in "wait forever" situations etc.
Anyway, why would the user space thread be too slow? One reason I can see
would be the Linux scheduler lowering the priority as a result of the
thread never sleeping. That would result in the thread being stalled for
"extended periods of time", if there are other processe in the system
that have work to do.
> I was wondering if there is some really obvious way to
> solve this rather simple problem or not.
>
> Would it make sense, and is it possible, to send a
> soft interrupt from RTL to sleeping user threads so
> that the latter can read the new data and send it via
> UDP?
Probably, but why not use an RTL FIFO as some kind of semaphore or lock
instead - or maybe even passing pointers (or offsets) into shared memory?
> I'm pretty sure that if I could do sends and receives
> from inside the RT Thread the problem would not
> exist... but apparently I can't...
I can't see why that would make a significant difference, unless there's
an OS with hard RT networking in the other end of the connection. Unless
you're sending several MB/s of data, bandwidth shouldn't be an issue even
with the most trivial RTL FIFO based solution - and if you set the user
space part up correctly, even non-lowlatency Linux should be pretty
responsive most of the time.
Something must be wrong with your code, or the system configuration or
something, I think...
//David Olofson --- Programmer, Reologica Instruments AB
.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
`----------------------------> http://www.linuxdj.com/maia -'
.- David Olofson -------------------------------------------.
| Audio Hacker - Open Source Advocate - Singer - Songwriter |
`-------------------------------------> http://olofson.net -'
-- [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/