Thanks Raimund. Can you also provide th configure magic for that?
b
On Jan 8, 2013 8:44 PM, "Raimund Steger" <rs@xxxxxxxx> wrote:
Behdad Esfahbod wrote:
Raimund,
Can we use these:
http://docs.oracle.com/cd/E18659_01/html/821-1383/gjzmf.html
I have your patch in my tree, waiting to see if we can resolve this part.
Without correct memory barrier, undefined behavior can result, though, it's
only known to happen for Alpha architectures.
I believe we could use these instructions. Though they seem to be rather recent additions and some people (not including me) might still use older Sun Studio versions, but well, the non-threadsafe behavior will always continue to work.
At first glance, __memory_rw_barrier seems to be what we need. I've now compared disassembly of a few relevant routines on SPARC:
Sun Studio translates __machine_rw_barrier() into:
[ 5] 10684: membar #StoreStore | #LoadStore | #StoreLoad | #LoadLoad
6. __machine_rw_barrier();
GCC translates __sync_synchronize() into the same:
4. __sync_synchronize();
[ 4] 106f8: membar #StoreStore | #LoadStore | #StoreLoad | #LoadLoad
As for the Solaris atomic ops (add/compare-exchange), they are library functions but they can be looked up here:
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/common/atomic/sparc/atomic.s
What GCC does in comparison:
- translates __sync_fetch_and_add() into:
8. return __sync_fetch_and_add(ai,v);
[ 8] 10710: ld [%fp + 72], %o5
[ 8] 10714: ld [%fp + 68], %g3
[ 8] 10718: ld [%g3], %g2
[ 8] 1071c: mov %g2, %g1
[ 8] 10720: mov %g1, %g4
[ 8] 10724: add %g1, %o5, %g2
[ 8] 10728: membar #StoreStore | #LoadStore | #StoreLoad | #LoadLoad
[ 8] 1072c: cas [%g3] , %g1, %g2
[ 8] 10730: cmp %g2, %g1
[ 8] 10734: bne,pt %icc,0x1071c
[ 8] 10738: nop
[ 8] 1073c: mov %g4, %g1
- translates __sync_bool_compare_and_swap() into:
12. return __sync_bool_compare_and_swap(p,o,n);
[12] 1075c: ld [%fp + 72], %g1
[12] 10760: ld [%fp + 76], %g2
[12] 10764: ld [%fp + 68], %g3
[12] 10768: membar #StoreStore | #LoadStore | #StoreLoad | #LoadLoad
[12] 1076c: cas [%g3] , %g1, %g2
[12] 10770: xor %g2, %g1, %g1
[12] 10774: cmp %g0, %g1
[12] 10778: subc %g0, -1, %g1
[12] 1077c: and %g1, 255, %g1
So this looks like it is necessary to add __machine_rw_barrier() before the atomic ops.
Interestingly though, GCC on amd64 (still Solaris) translates __sync_synchronize() into 'mfence' but includes no fence instruction for the atomic add and compare-exchange operations.
I should add that there are memory barrier operations in libc on Solaris as well. They are from atomic.s, too (see link, at the end of the page). They (more or less, it differs between SPARC and amd64) provide individual access to the above 'membar' flavors. Hence to achieve the same effect as __machine_rw_barrier(), a sequence of such function calls were required.
Well in the end I suppose if we want to follow GCC's example we should probably use __machine_rw_barrier(). It's a macro that expands to an inline assembly statement.
So, maybe like the following in fcatomic.h:
[...]
#elif !defined(FC_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
#include <atomic.h>
#include <mbarrier.h>
typedef unsigned int fc_atomic_int_t;
#define fc_atomic_int_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
#define fc_atomic_ptr_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P))
#define fc_atomic_ptr_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((P), (O), (N)) == (void *) (O) ? FcTrue : FcFalse)
#elif !defined(FC_NO_MT)
[...]
Raimund
--
Worringer Str 31 Duesseldorf 40211 DE home: <rs@xxxxxxxx>
+49-179-2981632 icq 16845346 work: <rs@xxxxxxxxxxxxxxx>
_______________________________________________ Fontconfig mailing list Fontconfig@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/fontconfig