Re: [linux-audio-dev] atomic xchg

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

Subject: Re: [linux-audio-dev] atomic xchg
From: Paul Barton-Davis (pbd_AT_Op.Net)
Date: to loka   14 1999 - 20:51:51 EDT


>Why is it so important to do it without a lock? Mutexes just aren't
>that expensive, and you WILL end up shooting yourself in the foot if
>you try to get by without them.

on an MP machine, mutexes are incredibly expensive if you block to
wait for a short-held spinlock.

most of the time i have such locks, i use my own implementation of
pthreads_mutex_spinlock()

int
pthread_spin_lock (pthread_mutex_t *mp)

{
#if NCPUS > 1

        int err;
        int i;

        i = SPINLIMIT;

        while (--i && ((err = pthread_mutex_trylock (mp)) == EBUSY))
                ;
        
        if (i == 0) {
            err = pthread_mutex_lock (mp);
        }

        return err;

#else
        return pthread_mutex_lock (mp);

#endif NCPUS
}

SPINLIMIT needs to be tuned to match roughly the loop-cnt-per-thread
context switch time (Karlin et al, 1991).

                                  You're talking about swapping
>pointers in a double-buffered workspace... the amount of time to do
>the "work" is going to far overwhelm the time to do a piddly
>pthread_mutex_lock() / swap pointers / pthread_mutex_unlock().

yes, but pthread_mutex_lock() doesn't spin at all. if the lock is
held, your thread will go to sleep. on an MP system, this is a disaster.

>> Paul make sure that we have a fallback solution (compile time) for CPU
>> architectures which do not provide these specialized asm instructions,
>> since it would be nice to run our audio engine on any powerful Linux
>> architecture ( Alpha, G4 PPC etc).
>
>...which is the best reason to use a standard API (POSIX threads) and
>don't depend on hardware-specific tricks.

i don't know of any hardware that doesn't have an atomic exchange
operation. if there is, i can guarantee you that it doesn't support
POSIX threads either. compare-and-swap (CAS) is something else
altogether, and as cute as Herlihy's wait-free synchronization can be,
i would never suggest we use it because CAS doesn't exist for all
architectures. but you can't implement (sorry, use) *any* thread
system without an atomic exchange op.

you don't need locks in many situations where people typically still
use them - primarily single reader ones. for example, by using the
following outline, you can avoid a 99% of the lock acquisitions in an
engine thread that wants to check for new requests:

   atomic_t requests_pending; /* /usr/src/linux/asm/atomic.h */
   pthread_mutex_lock request_lock;
   some_queue_type_t request_queue;
 
READER (engine):

        if (atomic_read (&requests_pending)) {
             pthread_mutex_spinlock (&request_lock);
             top = request_queue.pop ();
             pthread_mutex_unlock (&request_lock);
        }

WRITER (requestor):

        pthread_mutex_spinlock (&request_lock);
        request_queue.push (req);
        atomic_inc (&requests_pending);
        pthread_mutex_unlock (&request_lock);
                  
This can be an enormous win on an MP machine - the engine thread will
almost never acquire the lock, and when it does, it knows for sure
that its about the be released "real soon now", so spinning makes a
lot of sense. with this scheme, requestor threads can stuff things
onto the queue knowing that they will not cause the engine thread to
block while they manipulate the queue.

for UP machines, this all comes out in the wash: you *want* the
threads to block. however, as several people on this list are
realizing, the incredibly low cost of dual CPU boxes presents a
compelling practical argument for proper support of SMP systems, even
if a desire for elegance did not :)

--p


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

This archive was generated by hypermail 2b28 : pe maalis 10 2000 - 07:27:59 EST