diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2011-12-27 10:40:23 +0100 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2011-12-27 10:40:23 +0100 |
commit | a055ca4382a2eb8857ff69bafcae5b7798b0db16 (patch) | |
tree | 2e90142c8e00550b43cd89074295f2ca7ba0dec5 /libjava | |
parent | 6231d28e0b83a7c06f71af45d0d64bf54f8fac39 (diff) | |
download | gcc-a055ca4382a2eb8857ff69bafcae5b7798b0db16.zip gcc-a055ca4382a2eb8857ff69bafcae5b7798b0db16.tar.gz gcc-a055ca4382a2eb8857ff69bafcae5b7798b0db16.tar.bz2 |
re PR libgcj/49193 (__sync_xxxx builtins aren't used in sysdep/*/locks.h)
PR libgcj/49193
* sysdep/alpha/locks.h (compare_and_swap): Call
__sync_bool_compare_and_swap.
(release_set): Call __sync_synchronize.
From-SVN: r182692
Diffstat (limited to 'libjava')
-rw-r--r-- | libjava/ChangeLog | 7 | ||||
-rw-r--r-- | libjava/sysdep/alpha/locks.h | 41 |
2 files changed, 26 insertions, 22 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 42787e1..841dfb7 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,10 @@ +2011-12-27 Uros Bizjak <ubizjak@gmail.com> + + PR libgcj/49193 + * sysdep/alpha/locks.h (compare_and_swap): Call + __sync_bool_compare_and_swap. + (release_set): Call __sync_synchronize. + 2011-12-20 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> * configure.ac (i?86-*-linux*): Set SIGNAL_HANDLER_AUX. diff --git a/libjava/sysdep/alpha/locks.h b/libjava/sysdep/alpha/locks.h index a6b4394..993afca 100644 --- a/libjava/sysdep/alpha/locks.h +++ b/libjava/sysdep/alpha/locks.h @@ -1,6 +1,6 @@ // locks.h - Thread synchronization primitives. Alpha implementation. -/* Copyright (C) 2002 Free Software Foundation +/* Copyright (C) 2002, 2011 Free Software Foundation This file is part of libgcj. @@ -11,41 +11,38 @@ details. */ #ifndef __SYSDEP_LOCKS_H__ #define __SYSDEP_LOCKS_H__ -typedef size_t obj_addr_t; /* Integer type big enough for object */ - /* address. */ +/* Integer type big enough for object address. */ +typedef size_t obj_addr_t; +// Atomically replace *addr by new_val if it was initially equal to old. +// Return true if the comparison succeeded. +// Assumed to have acquire semantics, i.e. later memory operations +// cannot execute before the compare_and_swap finishes. inline static bool compare_and_swap(volatile obj_addr_t *addr, - obj_addr_t old, - obj_addr_t new_val) + obj_addr_t old, + obj_addr_t new_val) { - unsigned long oldval; - char result; - __asm__ __volatile__( - "1:ldq_l %0, %1\n\t" \ - "cmpeq %0, %5, %2\n\t" \ - "beq %2, 2f\n\t" \ - "mov %3, %0\n\t" \ - "stq_c %0, %1\n\t" \ - "bne %0, 2f\n\t" \ - "br 1b\n\t" \ - "2:mb" - : "=&r"(oldval), "=m"(*addr), "=&r"(result) - : "r" (new_val), "m"(*addr), "r"(old) : "memory"); - return (bool) result; + return __sync_bool_compare_and_swap(addr, old, new_val); } +// Set *addr to new_val with release semantics, i.e. making sure +// that prior loads and stores complete before this +// assignment. inline static void release_set(volatile obj_addr_t *addr, obj_addr_t new_val) { - __asm__ __volatile__("mb" : : : "memory"); + __sync_synchronize(); *(addr) = new_val; } +// Compare_and_swap with release semantics instead of acquire semantics. +// On many architecture, the operation makes both guarantees, so the +// implementation can be the same. inline static bool compare_and_swap_release(volatile obj_addr_t *addr, - obj_addr_t old, - obj_addr_t new_val) + obj_addr_t old, + obj_addr_t new_val) { return compare_and_swap(addr, old, new_val); } |