From patchwork Wed Jun 20 13:10:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Edelsohn X-Patchwork-Id: 166069 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 29200B6FD4 for ; Wed, 20 Jun 2012 23:11:13 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1340802674; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:In-Reply-To:References:Date: Message-ID:Subject:From:To:Cc:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=xin3UL25Z3ZHw76lmu8sEt4mABc=; b=qa0xzH9i9FSqeVoOsplU9vwQRrM2AJGda1bcZeWAKe/VW+k0tB21EAj3m2XFJP Vvha0p0zIlUHF41bwyQ6+eTU2NbFRTtxkLzOb7tv3d1YRSHVYeKBdAaoIEyH2IJN WEMHySVF55pGp9FM65DBZIwvVeAgrhnyArQ5jsH6vNN+k= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:MIME-Version:Received:Received:In-Reply-To:References:Date:Message-ID:Subject:From:To:Cc:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=i4ibTtUIqQkNWhV9sNGAgiZs9Ul4Qj9flhAlfq/cA7VctvL5iVyxajIk7j7Ehm OA4IIdal0ki47esC1pJlig5LxOLmkFcfks4OQkH7DaJYOFYUZeWsZPP+925xal3h eH5yg03UpKwGWFok/CYUSyGVpVoaPmTAsnkskCptFZ/wI=; Received: (qmail 30859 invoked by alias); 20 Jun 2012 13:11:08 -0000 Received: (qmail 30199 invoked by uid 22791); 20 Jun 2012 13:11:06 -0000 X-SWARE-Spam-Status: No, hits=-4.9 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, KHOP_RCVD_TRUST, KHOP_THREADED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, TW_IB X-Spam-Check-By: sourceware.org Received: from mail-yw0-f47.google.com (HELO mail-yw0-f47.google.com) (209.85.213.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 20 Jun 2012 13:10:46 +0000 Received: by yhjj56 with SMTP id j56so5860282yhj.20 for ; Wed, 20 Jun 2012 06:10:45 -0700 (PDT) MIME-Version: 1.0 Received: by 10.60.10.99 with SMTP id h3mr23588890oeb.72.1340197845192; Wed, 20 Jun 2012 06:10:45 -0700 (PDT) Received: by 10.182.197.33 with HTTP; Wed, 20 Jun 2012 06:10:44 -0700 (PDT) In-Reply-To: References: Date: Wed, 20 Jun 2012 09:10:44 -0400 Message-ID: Subject: Re: [Target maintainers]: Please update libjava/sysdep/*/locks.h with new atomic builtins From: David Edelsohn To: Uros Bizjak Cc: Alan Modra , GCC Patches Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Alan and I both re-implemented the locks and settled on the following patch. This uses the __atomic intrinsics, not the __sync instrinsics, to avoid generating expensive instructions for a memory model that is stricter than necessary. If these intrinsics correctly represent the semantics of the libjava barriers, it probably can be used as a generic implementation for targets that support the __atomic intrinsics. - David 2012-06-20 David Edelsohn Alan Modra * sysdep/powerpc/locks.h (compare_and_swap): Use GCC atomic intrinsics. (release_set): Same. (compare_and_swap_release): Same. (read_barrier): Same. (write_barrier): Same. Index: locks.h =================================================================== --- locks.h (revision 188778) +++ locks.h (working copy) @@ -11,87 +11,63 @@ #ifndef __SYSDEP_LOCKS_H__ #define __SYSDEP_LOCKS_H__ -#ifdef __LP64__ -#define _LARX "ldarx " -#define _STCX "stdcx. " -#else -#define _LARX "lwarx " -#ifdef __PPC405__ -#define _STCX "sync; stwcx. " -#else -#define _STCX "stwcx. " -#endif -#endif - typedef size_t obj_addr_t; /* Integer type big enough for object */ /* address. */ +// 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, +compare_and_swap (volatile obj_addr_t *addr, + obj_addr_t old, obj_addr_t new_val) { - obj_addr_t ret; - - __asm__ __volatile__ ( - " " _LARX "%0,0,%1 \n" - " xor. %0,%3,%0\n" - " bne $+12\n" - " " _STCX "%2,0,%1\n" - " bne- $-16\n" - : "=&r" (ret) - : "r" (addr), "r" (new_val), "r" (old) - : "cr0", "memory"); - - /* This version of __compare_and_swap is to be used when acquiring - a lock, so we don't need to worry about whether other memory - operations have completed, but we do need to be sure that any loads - after this point really occur after we have acquired the lock. */ - __asm__ __volatile__ ("isync" : : : "memory"); - return ret == 0; + return __atomic_compare_exchange_n (addr, &old, new_val, 0, + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); } + +// 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__ ("sync" : : : "memory"); - *addr = new_val; + __atomic_store_n(addr, val, __ATOMIC_RELEASE); } + +// Compare_and_swap with release semantics instead of acquire semantics. + inline static bool compare_and_swap_release (volatile obj_addr_t *addr, obj_addr_t old, obj_addr_t new_val) { - obj_addr_t ret; - - __asm__ __volatile__ ("sync" : : : "memory"); - - __asm__ __volatile__ ( - " " _LARX "%0,0,%1 \n" - " xor. %0,%3,%0\n" - " bne $+12\n" - " " _STCX "%2,0,%1\n" - " bne- $-16\n" - : "=&r" (ret) - : "r" (addr), "r" (new_val), "r" (old) - : "cr0", "memory"); - - return ret == 0; + return __atomic_compare_exchange_n (addr, &old, new_val, 0, + __ATOMIC_RELEASE, __ATOMIC_RELAXED); } + // Ensure that subsequent instructions do not execute on stale // data that was loaded from memory before the barrier. + inline static void read_barrier () { - __asm__ __volatile__ ("isync" : : : "memory"); + __atomic_thread_fence (__ATOMIC_ACQUIRE); } + // Ensure that prior stores to memory are completed with respect to other // processors. + inline static void write_barrier () { - __asm__ __volatile__ ("sync" : : : "memory"); + __atomic_thread_fence (__ATOMIC_RELEASE); } #endif