X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=libgc%2Finclude%2Fprivate%2Fgc_locks.h;h=83fe57d917d70ad2a20a5b3b4452610ba86c263c;hb=b5a53bc535df5d5cfb450be0986e9980b25d5c2d;hp=d1ccf0ed0da550eb4061b8998ea6a1a5d4d7ce87;hpb=496dfbf9ec0fd3143e5dd560a863d916e56a52b8;p=mono.git diff --git a/libgc/include/private/gc_locks.h b/libgc/include/private/gc_locks.h index d1ccf0ed0da..83fe57d917d 100644 --- a/libgc/include/private/gc_locks.h +++ b/libgc/include/private/gc_locks.h @@ -155,43 +155,23 @@ # define GC_TEST_AND_SET_DEFINED # endif # if defined(POWERPC) -# if CPP_WORDSZ == 64 - inline static int GC_test_and_set(volatile unsigned int *addr) { - unsigned long oldval; - unsigned long temp = 1; /* locked value */ - - __asm__ __volatile__( - "1:\tldarx %0,0,%3\n" /* load and reserve */ - "\tcmpdi %0, 0\n" /* if load is */ - "\tbne 2f\n" /* non-zero, return already set */ - "\tstdcx. %2,0,%1\n" /* else store conditional */ - "\tbne- 1b\n" /* retry if lost reservation */ - "\tsync\n" /* import barrier */ - "2:\t\n" /* oldval is zero if we set */ - : "=&r"(oldval), "=p"(addr) - : "r"(temp), "1"(addr) - : "cr0","memory"); - return (int)oldval; - } -# else inline static int GC_test_and_set(volatile unsigned int *addr) { int oldval; int temp = 1; /* locked value */ __asm__ __volatile__( - "1:\tlwarx %0,0,%3\n" /* load and reserve */ + "1:\tlwarx %0,0,%1\n" /* load and reserve */ "\tcmpwi %0, 0\n" /* if load is */ "\tbne 2f\n" /* non-zero, return already set */ "\tstwcx. %2,0,%1\n" /* else store conditional */ "\tbne- 1b\n" /* retry if lost reservation */ "\tsync\n" /* import barrier */ "2:\t\n" /* oldval is zero if we set */ - : "=&r"(oldval), "=p"(addr) - : "r"(temp), "1"(addr) + : "=&r"(oldval) + : "r"(addr), "r"(temp) : "cr0","memory"); return oldval; } -# endif # define GC_TEST_AND_SET_DEFINED inline static void GC_clear(volatile unsigned int *addr) { __asm__ __volatile__("lwsync" : : : "memory"); @@ -437,6 +417,29 @@ } # endif /* I386 */ +# if defined(X86_64) +# if !defined(GENERIC_COMPARE_AND_SWAP) + /* Returns TRUE if the comparison succeeded. */ + inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr, + GC_word old, + GC_word new_val) + { + char result; + __asm__ __volatile__("lock; cmpxchgq %2, %0; setz %1" + : "+m"(*(addr)), "=r"(result) + : "r" (new_val), "a"(old) : "memory"); + return (GC_bool) result; + } +# endif /* !GENERIC_COMPARE_AND_SWAP */ + inline static void GC_memory_barrier() + { + /* We believe the processor ensures at least processor */ + /* consistent ordering. Thus a compiler barrier */ + /* should suffice. */ + __asm__ __volatile__("" : : : "memory"); + } +# endif /* X86_64 */ + # if defined(POWERPC) # if !defined(GENERIC_COMPARE_AND_SWAP) # if CPP_WORDSZ == 64