On Tuesday 13 March 2001 20:42, s_a_white wrote:
[...]
> So the question is is there a better way to pass the data between the
> Kernel and real time threads?  Preferabaly I do not want to upgrade to
> Kernel 2.4.0 as I have extra Kernel modules which aren't ready for it yet. 
> Also I don't want to use the fifos because I want it to be a contained
> driver providing it's own ioctls.

I don't see why a correctly designed semaphore or spinlock based connection 
wouldn't work, but how about a lock-free FIFO between the Linux driver and 
the RTLinux thread?

Note that a lock-free FIFO in itself can't be slept on, so you need to wake 
the RTL thread up from the Linux driver code some other way to get it to 
check the FIFO, unless it just wakes up and checks the FIFO at regular 
intervals when it's got nothing else to do.

Looking at the code, it actually seems like throwing in a lock-free FIFO 
right between the driver calls and the RTL thread would be the cleanest and 
simplest way. You don't have to do *any* additional synchronization between 
the write function and the RTL thread; you only have to deal with FIFO 
underruns and of course, large block writes, as with any kernel driver.

Personally, I consider buffer underruns in audio systems fatal errors, so I 
wouldn't spend much time trying to handle them nicely. How about just going 
to sleep for a while and then retry? (If you get an underrun, timing is 
screwed up anyway as you have no data to play, so why try to be smart?)


I can send you a lock-free FIFO implementation (pretty generic; works in user 
space, kernel space, DOS real mode, and probably in quite a few other 
environments as well) with some kernel driver code fragments if you like.


BTW, looking closer at the code, it seems like you're doing a HardSID (or 
other 6581/8580 card) driver with cycle accurate timing. :-)

(Listening to the Robocop 3 theme on a SID emulator right now.)


[...]
>     for(;;)
>     {
>         sem_wait (&todoSem);
>         sid = sid_data[0]; // Hard coded to minor 0 for testing
>         sem_wait (&sid->todoSem);
>
>         cmd = sid->buffer[sid->curCommand++];
>         sid->curCommand &= HSID_BUFFER_SIZE - 1;
>         delay += (cmd >> 16) * 1000;
>
>         if ((cmd & 0x1f00) == 0x1f00)
>         {
>             up (&sid->bufferSem);
>             continue;
>         }

Does 0x1f00 mean "end of buffer"?

Wouldn't be needed with a lock-free FIFO; just stay in the {read command; 
nanosleep; write register} loop forever. Seems very logical to me BTW: Time 
does not stop, and does not come in chunks, so why insert "end" or "chunk" 
markers in a continous stream of timestamped events? :-)


> NOTE:  Using:
>
> RTL_MARK_SUSPENDED (self);
> pthread_make_periodic_np (....); // With period 0
>
> or
>
> pthread_make_periodic_np (....); // With period 0
> pthread_wait_np ();
>
> Instead of nanosleep/usleep will lock up the machine for small delays when
> the system becomes loaded through another program running in the
> background....?

Strange... Are you sure *that's* what causing the stalls, as opposed to 
buffer underruns making your RT thread spin for extended amounts of time or 
something like that?


//David

.- M A I A -------------------------------------------------.
|      Multimedia Application Integration Architecture      |
| A Free/Open Source Plugin API for Professional Multimedia |
`----------------------> http://www.linuxaudiodev.com/maia -'
.- David Olofson -------------------------------------------.
| Audio Hacker - Open Source Advocate - Singer - Songwriter |
`--------------------------------------> [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/

Reply via email to