From patchwork Sat Mar 10 17:43:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Torvald Riegel X-Patchwork-Id: 145878 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 C810BB6FAB for ; Sun, 11 Mar 2012 04:43:54 +1100 (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=1332006235; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Subject:From:To:Cc:Content-Type:Date:Message-ID:Mime-Version: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=2FgZQcQgxRwxgdg3kJff OhOsUnM=; b=YXIeYlWUdsnVm5MhsMwXt1bjDKyw9xDf+hUHm3Bpq24xSrkhf28C DKNrtKWsOV/yfKd3GAZ6yJ1GmuqBpSl5rHQCa5nz9nWsvheHE8waBahZ5cwvsw+I 4TAn/HzLS3ND4DHALFmRGbGwNus+wSVQ1VL0o9nJ3b7l9drrUJsRe1A= 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:Received:Subject:From:To:Cc:Content-Type:Date:Message-ID:Mime-Version:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=hSa60xKwJhxWkd+MaavyJ+ue12KEVP4R4MhR6yuWChJJWrNKRtiD37LiMa90pn V1n8TCqbiVYkBuXkAnJXYomDI3TSRuAlujvTdr5lAYiIWaYszuZ9v5pI8+cVwDps KgJZC5FFxtLTP3vhp+Zs7eAND9L0I05u0aSSNNpwdO8Ao=; Received: (qmail 4278 invoked by alias); 10 Mar 2012 17:43:49 -0000 Received: (qmail 4257 invoked by uid 22791); 10 Mar 2012 17:43:47 -0000 X-SWARE-Spam-Status: No, hits=-6.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 10 Mar 2012 17:43:32 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2AHhWPN009203 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 10 Mar 2012 12:43:32 -0500 Received: from [10.36.5.132] (vpn1-5-132.ams2.redhat.com [10.36.5.132]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q2AHhUAu001104; Sat, 10 Mar 2012 12:43:31 -0500 Subject: [patch, 4.7] libitm: Fix lost wake-up in serial lock. From: Torvald Riegel To: GCC Patches Cc: Richard Henderson , Jakub Jelinek , Patrick MARLIER Date: Sat, 10 Mar 2012 18:43:29 +0100 Message-ID: <1331401409.2986.8974.camel@triegel.csb> Mime-Version: 1.0 X-IsSubscribed: yes 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 This patch fixes PR52526, a lost wake-up in libitm (ie, one ore more threads could hang and not get woken up anymore). The problem was missing handling of one corner case in the futex-based serial lock implementation (config/linux/rwlock.cc, read_lock()): Multiple readers would set READERS to 1 and only call futex_wait(&readers, 1) if there were any writers. Writers would set READERS to 0 and then call futex_wake(&readers). That's fine, but because there are multiple readers, it can happen that some would set READERS to 1 after the writer's futex_wake() call, enabling the futex_wait() in other readers (because READERS isn't 0 anymore). This patch fixes this by having readers wake up all potentially waiting readers when they set READERS to 1 without an existing writer (thus taking over what the writer would do). OK for trunk? OK for 4.7 too? This is a showstopper if users hit it, so I'd prefer if it could go into 4.7 as well. commit 07d6d68b423797311bb04d8eb571f053d2078aa4 Author: Torvald Riegel Date: Sat Mar 10 17:44:37 2012 +0100 libitm: Fix lost wake-up in serial lock. PR libitm/52526 * config/linux/rwlock.cc (GTM::gtm_rwlock::read_lock): Fix lost wake-up. diff --git a/libitm/config/linux/rwlock.cc b/libitm/config/linux/rwlock.cc index ad1b042..cf1fdd5 100644 --- a/libitm/config/linux/rwlock.cc +++ b/libitm/config/linux/rwlock.cc @@ -74,6 +74,32 @@ gtm_rwlock::read_lock (gtm_thread *tx) atomic_thread_fence (memory_order_seq_cst); if (writers.load (memory_order_relaxed)) futex_wait(&readers, 1); + else + { + // There is no writer, actually. However, we can have enabled + // a futex_wait in other readers by previously setting readers + // to 1, so we have to wake them up because there is no writer + // that will do that. We don't know whether the wake-up is + // really necessary, but we can get lost wake-up situations + // otherwise. + // No additional barrier nor a nonrelaxed load is required due + // to coherency constraints. write_unlock() checks readers to + // see if any wake-up is necessary, but it is not possible that + // a reader's store prevents a required later writer wake-up; + // If the waking reader's store (value 0) is in modification + // order after the waiting readers store (value 1), then the + // latter will have to read 0 in the futex due to coherency + // constraints and the happens-before enforced by the futex + // (paragraph 6.10 in the standard, 6.19.4 in the Batty et al + // TR); second, the writer will be forced to read in + // modification order too due to Dekker-style synchronization + // with the waiting reader (see write_unlock()). + // ??? Can we avoid the wake-up if readers is zero (like in + // write_unlock())? Anyway, this might happen too infrequently + // to improve performance significantly. + readers.store (0, memory_order_relaxed); + futex_wake(&readers, INT_MAX); + } } // And we try again to acquire a read lock.