Re: [linux-audio-dev] LAAGA - main components

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: Re: [linux-audio-dev] LAAGA - main components
From: Paul Davis (pbd_AT_Op.Net)
Date: Thu May 03 2001 - 16:00:26 EEST


>I guess we could find a good way to manage the `kill' calls if this is
>really necessary. If we hide this behind a couple of function calls
>then we can control it and change the implementation as necessary.
>For a start, saving up the calls and dispatching them at the end of
>the loop takes away a big chunk of the risk of disrupting the audio.
>
>However there may be another way of approaching this. We could have a
>call "submit_job(funcp, voidp)" which adds a job to the end of a
>job-list which is processed serially in another thread managed by the
>server. So occasional jobs that it's not worth having a whole thread
>to handle can be set to run by the real-time thread, to be executed a
>short time later in another parallel thread.

good ideas. i'll use them in ardour.

>If this fits in naturally with other things then maybe its a good way
>to go. If not, maybe forget it. We would have the plugin management
>thread constantly ticking over anyway, wouldn't we ? Perhaps that
>could handle these jobs.

the plugin management thread will almost always be the "initial"
thread started by the program. in most cases, this thread will be
running a UI (not necessarily G), and it will be responsible for
handling plugin management (typically in response to a user request
and/or a message arriving on a socket/pipe); even if there's no UI,
there's the thread listening on some file descriptor for new
connections to the engine.

>> Oh, there is the problem that such writes are not atomic on all
>> architectures (SPARC being the foremost example; I'm not sure about PPC).
>
>When I say `atomic' what I'm trying to ask is if it is possible to do
>a 32-bit read half-way through the 32-bit write, and get a scrambled
>result, neither the original value nor the new value. I guess the
>instruction itself doesn't have to be an atomic operation, just the
>memory write. I would guess that for all systems with a 32-bit bus to
>memory, this will be atomic. Is this true ? (What's this about SPARC ?)

the SPARC's cache architecture means that 32 bit writes and reads are
not atomic on an SMP system. The way the cache lines are structured,
you can end up suffering a partial-cache miss on a 32 bit value. if
you look at the linux code for atomic_t on the sparc, you'll see it
requires explicit locking to make it safe, and an atomic_t on that
architecture is only a 24bit value (definitely not a pointer!)

its not the only architecture that does this, but i can't remember
what the other(s) are. x86 is clean, for once!

>In my plan, only one process (or thread) would be writing to this
>location, and all the others will be treating it as read-only, so we
>don't have the problem of two processors competing to do an operation
>- which is what test-and-set instructions were designed to handle (I
>think, and which I'm guessing is somehow similar to compare-and-swap).

right, this is true - as long its a (one-writer; read-many) thing,
then you don't need a lock, but that doesn't address the fact that it
describes a list that gets manipulated by the engine. the engine may
modify the list as i described previously. this means that the "copy
the list, then swap pointers approach won't work.

>Paul, in ardour you say you're using some kind of lock to protect the
>list of plugins. I'm curious to know how this locking works
>internally. Perhaps I'll take a look at the pthreads source when I
>get a chance.

we just use pthread_mutex_trylock(). if the audio thread (in
AudioEngine::process(), called from the code that was woken from
poll(2)) can't get the lock, it just throw its hands in the air and
says "OK, I have nothing to do", and returns. this ensures that it
never blocks on the lock, though other threads (which use
pthread_mutex_lock()) may well do so. the obvious example: some other
thread wants to add a new plugin to the list. it tries to get the lock
but the audio thread owns it. it blocks. then the audio thread
releases the lock. thanks (unfortunately) to a system call, this will
wake up the blocked thread, which takes the lock. if for some reason
it takes too long working with the list (unlikely, but possible), then
when the audio thread next tries to use the list, it will fail to
acquire the lock, and do nothing at all (hence the click - no audio is
produced or generated for this interrupt, though we do silence the
relevant part of the audio interface DMA buffer).

this is another example where the "no system calls" rule breaks
down. with the linux pthreads implementation, you can't use any kind
of mutex without a system call to wake up threads that are blocked on
the lock. this is all part of the problem with kernel threads compared
to user threads, an area that i was somewhat familiar with from my
stint in the systems group at UofWashington. user-space threads have
their own problems as well, of course.

--p


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Thu May 03 2001 - 17:02:41 EEST