From 6be35d407308417bc246bd7197c0d0cd8147eedb Mon Sep 17 00:00:00 2001 From: uros Date: Tue, 27 Dec 2011 09:40:23 +0000 Subject: [PATCH] PR libgcj/49193 * sysdep/alpha/locks.h (compare_and_swap): Call __sync_bool_compare_and_swap. (release_set): Call __sync_synchronize. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182692 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/ChangeLog | 7 +++++++ libjava/sysdep/alpha/locks.h | 41 +++++++++++++++++++---------------------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 42787e1e896..841dfb753ae 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,10 @@ +2011-12-27 Uros Bizjak + + 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 * configure.ac (i?86-*-linux*): Set SIGNAL_HANDLER_AUX. diff --git a/libjava/sysdep/alpha/locks.h b/libjava/sysdep/alpha/locks.h index a6b4394080b..993afca06d4 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); } -- 2.11.0