[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: kde4libs vs qt4



Carlos O'Donell wrote:
On Tue, Jun 10, 2008 at 4:10 PM, Helge Deller <deller@gmx.de> wrote:
For Qt it might work as I mentioned without copying atomic.h from glibc.
Qt uses ldcw() not directly. Instead it uses q_atomic_lock(), which then
utilizes q_ldcw().

Here is the code (from src/corelib/arch/parisc/qatomic_parisc.cpp):
   void q_atomic_lock(int *lock)
   {
       // ldcw requires a 16-byte aligned address
       volatile int *x = align16(lock);
       while (q_ldcw(x) == 0)
           ;
   }
So, the 16byte alignment is taken care of by align16().
My attempt was based on having a minimal patch against Qt.

How is align16() implemented? Is the "int *lock" actually a block of
more than 4 ints? If yes, then this will work, and it's similar to the
approach taken by linuxthreads.

Yes.

#define UNLOCKED    {-1,-1,-1,-1}
#define UNLOCKED2      UNLOCKED,UNLOCKED
#define UNLOCKED4     UNLOCKED2,UNLOCKED2
#define UNLOCKED8     UNLOCKED4,UNLOCKED4
#define UNLOCKED16    UNLOCKED8,UNLOCKED8
#define UNLOCKED32   UNLOCKED16,UNLOCKED16
#define UNLOCKED64   UNLOCKED32,UNLOCKED32
#define UNLOCKED128  UNLOCKED64,UNLOCKED64
#define UNLOCKED256 UNLOCKED128,UNLOCKED128

// use a 4k page for locks
static int locks[256][4] = { UNLOCKED256 };

int *getLock(volatile void *addr)
{ return locks[qHash(const_cast<void *>(addr)) % 256]; }

static int *align16(int *lock)
{
    ulong off = (((ulong) lock) % 16);
    return off ? (int *)(ulong(lock) + 16 - off) : lock;
}


Reply to: