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

Re: FTBFS on sparc: __sync_test_and_add_4

On Thu, 2009-04-30 at 00:55 +1000, Felipe Sateler wrote:
> El 29/04/09 22:28 Martin escribió:
> > On Wed, 2009-04-29 at 14:11 +1000, Felipe Sateler wrote:
> > > Hi sparc porters. I'm writing to ask for your assistance on a FTBFS on
> > > my package csound on sparc. The build log is here[1]. The failure is
> > >
> > > the following:
> > > > libCsoundAC.so.5.2: undefined reference to `__sync_fetch_and_add_4'
> > >
> > > Csound uses __sync_lock_test_and_set for spinlocks,
> >
> > <unhelpful pedantry>
> > Given that pthread_spinlock is in one of the POSIX extensions, is there
> > a good reason you are building your own synchronisation primatives?
> > </unhelpful pedantry>
> Hmm, not so unhelpful, given that csound already uses pthreads... maybe this 
> function just escaped upstreams attention. Wouldn't it be slower to use 
> (shared) library calls instead of gcc builtins?
Correctness is more important than speed.  Synchronisation primatives
are notoriously tricky to implement correctly and are prone to obscure,
subtle race conditions.  Thus it is best to use the system (libc) ones.
In rare cases where these are a key bottleneck, changing your algorithm
is likely to make a bigger difference to performance and scalability
than changing the implementation of the synchronisation primatives.

> > >  and tests for
> > > their existence at build time to use them.
> >
> > This is the following test?
> >
> > Checking for __sync_lock_test_and_set((int32_t *)0, 0) in C library m...
> > yes
> > found sync lock
> Yes. It just builds a .c file calling that function from main and compiles it.
OK, as long as this is the only primative you need, you should be OK.
If you want to use others then you will need to check for them.
Alternatively libatomic-ops would be a good direction to go in, if you
absolutely *must* have your own synchronisation primatives.

> > > Sparc's gcc apparently
> > > provides said function, since the test succeeds, but I'm getting the
> > > above failure (note that __sync_fetch_and_add_4 is nowhere mentioned
> > > in the csound sources).
> >
> > May it come from a supporting library?  Which synchronisation primatives do
> > you use?
> felipe@pcfelipe:csound% rgrep __sync *
> H/csound.h:    while (__sync_lock_test_and_set(spinlock, 1) == 1) {        \
> H/csound.h:    __sync_lock_release(spinlock);              \
This looks like a custom spinlock.  I'd (as a general point) advise
against this and suggest using POSIX spinlocks.

> SConstruct:   syncLockTestAndSetFound = 
> configure.CheckLibWithHeader('m', 'stdint.h', 'C', '__sync_lock_test_and_set((int32_t 
> *)0, 0);')
> felipe@pcfelipe:csound% 
> >
> > > What is a possible cause for this? I don't have access to sparc
> > > machines so I'm kind of unsure what to do here. Note that csound uses
> > > -Wl,--as-needed for most of its libraries.
> > >
> > > Please CC me on replies, I'm not suscribed.
> >
> > OK, __sync_* aren't part of the C library as such, they are GCC
> > built-ins that give a (psuedo) machine independant wrapper around atomic
> > instructions.  Unfortunately which atomic ops machines implement varies
> > greatly.  The GCC interface is kind of written assuming the union of x86
> > and Alpha, in many cases unavailable atomic ops can be emulated.
> >
> > SPARC, certainly early revisions, are very short on atomic operations.
> > I'll have to check an architecture manual but IIRC V7 only has test and
> > set and atomic swap, V9 / V8+ is needed to get compare and swap.  I
> > believe the current default is for Debian to target V8.  This would be
> > sufficient to pass a check for test_and_set, but not enough to give
> > fetch_and_add, which you'd need compare and swap to emulated.
> But I'm not using fetch_and_add... not directly at least.

Yes, which makes me suspect it might be being used indirectly by one of
the libraries that you use.

> > I'd try to isolate which section of code you needs these instructions,
> > see if there is a more portable way of writing that section of code (if
> > it is a library it may be necessary to bug report this back)
> How can I go around to do that? I don't have sparc access,
I /believe/ there are (or at leats were at one point) SPARC machines
that were accessible to all Debian developers.  Alsa none of my
Debian/SPARC boxes are in a usable state at the moment.

>  and my amd64 binaries have no trace of any __sync functions.
IIRC if the target architecture has suitable assembler, it uses that,
references to __sync functions are only inserted if there aren't
suitabel instructions - thus allowing programmers to provide their own

> > and failing 
> > all else you may want to try setting the architecture to V8+, but be
> > aware this may have portability issues, plus I'm not entirely sure what
> > the current policy on shipping V8+ packages is; it may be necessary to
> > produce two versions, one V8 and one V8+
> I'd prefer disabling multithreading support than providing useless binaries to 
> some users.
If there is no way of resolving this problem and the code requires
atomic ops that are not available in V8 then one option might be to ship
a single-threaded V8 version and a multi-threaded V8+ package.  I'm not
convinced that it is that bad though, and there might be a way of
reoslving this.


 - Martin

Reply to: