Wed, 16 Feb 2000 Nicholas Mc Guire wrote:
> Hi !
>
> I got a realtime task that reads data from a DAQ and writes it into
> shm , in user-land the shm is droped to a file . My problem is now
> how can I guarantie that the user-land job will not drop some data
> due to overall system-load ??
In theory, you need a hard real time/guarenteed bandwidth fs for that.
> just setting a nice value for the
> user-land job is not realy a guarantie .
No, that just means your task gets at the fs first - it does not mean that the
fs lets it go ahead in the queue of disk operations.
> setting a lock on shm is
> no solution because I can't make the shm block big enough (1GB would
> be the minimum).
Are you saying you're using a 1 GB block that's partly swapped out...? If you
are, no wonder you're having problems! The swapping will kill the disk
transfer rate (lots of seeking, little data transfer), causing the task that
tries to write the data to a file to fail to do it in time. In this situation,
don't be surprized if you get just a few % of the disk's raw transfer rate!
BTW, can you really access the shm from RT threads if it's not locked? AFAIK,
that will at the very least result in your RT threads becoming no more real
time than the average user space task... Actually, i think you will have a
kernel crash, or at least, your RT thread will write the data in the wrong
place.
> any ideas ?
There are lots of ways to do this... I think one of the easiest ones is
chopping the shm (which must be locked!) up into blocks (a block pool), and
then pushing references to them onto an RT-FIFO. The RT thread should use that
FIFO as a pool where it gets "empty" buffers. Then it fills them and returns
through another FIFO, which is where the user space task looks for new data to
write to disk.
That is:
Disk writer task:
//get shm block
shmblock = alloc_shm_area();
//chop it up into a buffer pool
for(number_of_buffers) {
bufref = suballoc_buffer_from_shm( shmblock );
write_FIFO( to_RT, bufref );
}
//stream data to disk...
while(1) {
bufref = read_FIFO( from_RT );
if( bufref = END_OF_DATA )
break;
write_to_disk( find_buffer(bufref) );
write_FIFO( to_RT, bufref );
}
RT thread:
while(1) {
if(all_done) {
write_FIFO( from_RT, END_OF_DATA );
break;
}
bufref = read_FIFO(to_RT);
sample_data( find_buffer(bufref) );
write_FIFO( bufref );
}
If you're using an IRQ to trigger each sample, you need an interface between
the ISR the thread. If you have buffered I/O on the converter board, you can
just turn the while loop into an ISR, something like this:
ISR() {
if(all_done) {
write_FIFO( from_RT, END_OF_DATA );
disable_IRQ();
}
bufref = read_FIFO(to_RT);
grab_data( find_buffer(bufref) );
write_FIFO( bufref );
}
Note: You have to check for FIFO under/overrun as well! If that happens, you
have lost data and thus probably failed, but at least it should be handled
nicely instead of crashing the system...
Regards,
//David
P r o f e s s i o n a l L i n u x A u d i o
· ··-------------------------------------------------·· ·
MuCoS - http://www.linuxdj.com/mucos
Audiality - http://www.angelfire.com/or/audiality
David Olofson - [EMAIL PROTECTED]
-- [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/~rtlinux/