From patchwork Wed Jun 23 17:12:46 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 56695 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 43066B6EF3 for ; Thu, 24 Jun 2010 03:13:04 +1000 (EST) Received: (qmail 10078 invoked by alias); 23 Jun 2010 17:13:01 -0000 Received: (qmail 10064 invoked by uid 22791); 23 Jun 2010 17:12:58 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_CP, 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; Wed, 23 Jun 2010 17:12:52 +0000 Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o5NHCoOY006792 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 23 Jun 2010 13:12:50 -0400 Received: from redhat.com (vpn-11-8.rdu.redhat.com [10.11.11.8]) by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o5NHCkMN015058 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Wed, 23 Jun 2010 13:12:48 -0400 Date: Wed, 23 Jun 2010 13:12:46 -0400 From: Aldy Hernandez To: rth@redhat.com, gcc-patches@gcc.gnu.org Subject: [trans-mem] implement _ITM_dropReferences Message-ID: <20100623171245.GA19259@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-08-17) 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 The following patch implements _ITM_dropReferences() in the library. This function removes any internal reference to a given chunk of memory. Two comments. First, we are effectively ignoring length, especially in the allocations tree (drop_references_allocations). Will this make a difference? In the local log (drop_references_local) I bend over backwards to ignore any pointer that would effectively be within [PTR + len]. Again, does this make a difference? You keep saying something about cancel-and-throw which I obviously don't know what it is... Second, I had to mark _ITM_dropReferences() as `transaction_pure' so it can be user-called, otherwise we try to call the clone of _ITM_dropReferences(). We probably need to provide similar treatment to other functions in (say _ITM_addUserCommitAction, etc)? How does this look? * alloc_c.cc (_ITM_dropReferences): New. * libitm.map (_ITM_dropReferences): Add. * libitm.h (_ITM_dropReferences): Add transaction_pure attribute. * alloc.cc (record_allocation): Ignore when applicable. (forget_allocation): Same. (commit_allocations_1): Same. (drop_references_allocations): New. * libitm_i.h (struct gtm_alloc_action): Add ignore field. (struct gtm_transaction): Declare drop_references_allocations. Declare drop_references_local. * local.cc (struct gtm_local_undo): Add ignore field. (rollback_local): Ignore when applicable. (drop_references_local): New. (GTM_LB): Set ignore field. Index: alloc_c.cc =================================================================== --- alloc_c.cc (revision 161187) +++ alloc_c.cc (working copy) @@ -57,4 +57,15 @@ _ITM_free (void *ptr) gtm_tx()->forget_allocation (ptr, free); } +/* Forget any internal references to PTR. */ + +__attribute__((transaction_pure)) +void ITM_REGPARM +_ITM_dropReferences (const void *ptr, size_t len) +{ + gtm_transaction *tx = gtm_tx(); + tx->drop_references_local (ptr, len); + tx->drop_references_allocations (ptr); +} + } // extern "C" Index: libitm.map =================================================================== --- libitm.map (revision 161187) +++ libitm.map (working copy) @@ -167,6 +167,7 @@ LIBITM_1.0 { _ITM_malloc; _ITM_calloc; _ITM_free; + _ITM_dropReferences; _ZGTtnwm; _ZGTtnam; Index: libitm.h =================================================================== --- libitm.h (revision 161187) +++ libitm.h (working copy) @@ -152,6 +152,7 @@ extern void _ITM_addUserUndoAction(_ITM_ extern int _ITM_getThreadnum(void) ITM_REGPARM; +__attribute__((transaction_pure)) extern void _ITM_dropReferences (const void *, size_t) ITM_REGPARM; Index: alloc.cc =================================================================== --- alloc.cc (revision 161187) +++ alloc.cc (working copy) @@ -33,7 +33,10 @@ gtm_transaction::record_allocation (void gtm_alloc_action *a = this->alloc_actions.find(iptr); if (a == 0) - a = this->alloc_actions.insert(iptr); + { + a = this->alloc_actions.insert(iptr); + a->ignore = false; + } a->free_fn = free_fn; a->allocated = true; @@ -46,7 +49,10 @@ gtm_transaction::forget_allocation (void gtm_alloc_action *a = this->alloc_actions.find(iptr); if (a == 0) - a = this->alloc_actions.insert(iptr); + { + a = this->alloc_actions.insert(iptr); + a->ignore = false; + } a->free_fn = free_fn; a->allocated = false; @@ -58,6 +64,9 @@ commit_allocations_1 (uintptr_t key, gtm void *ptr = (void *)key; uintptr_t revert_p = (uintptr_t) cb_data; + if (a->ignore) + return; + if (a->allocated == revert_p) a->free_fn (ptr); } @@ -74,4 +83,24 @@ gtm_transaction::commit_allocations (boo this->alloc_actions.clear (); } +/* Forget any references to PTR in the allocations tree. + + ?? We ignore the chunk length. Pray this doesn't wreck havoc. */ + +void +gtm_transaction::drop_references_allocations (const void *ptr) +{ + uintptr_t iptr = (uintptr_t) ptr; + + gtm_alloc_action *a = this->alloc_actions.find(iptr); + if (a == 0) + { + a = this->alloc_actions.insert(iptr); + a->free_fn = NULL; + a->allocated = false; + } + + a->ignore = true; +} + } // namespace GTM Index: testsuite/libitm.c/dropref.c =================================================================== --- testsuite/libitm.c/dropref.c (revision 0) +++ testsuite/libitm.c/dropref.c (revision 0) @@ -0,0 +1,11 @@ +#include + +char *pp; + +int main() +{ + __transaction { + _ITM_dropReferences (pp, 555); + } + return 0; +} Index: testsuite/libitm.c++/dropref.C =================================================================== --- testsuite/libitm.c++/dropref.C (revision 0) +++ testsuite/libitm.c++/dropref.C (revision 0) @@ -0,0 +1,11 @@ +#include + +char *pp; + +int main() +{ + __transaction { + _ITM_dropReferences (pp, 555); + } + return 0; +} Index: libitm_i.h =================================================================== --- libitm_i.h (revision 161187) +++ libitm_i.h (working copy) @@ -155,6 +155,7 @@ struct gtm_alloc_action { void (*free_fn)(void *); bool allocated; + bool ignore; }; // This type is private to local.c. @@ -226,6 +227,7 @@ struct gtm_transaction void commit_allocations (bool); void record_allocation (void *, void (*)(void *)); void forget_allocation (void *, void (*)(void *)); + void drop_references_allocations (const void *); // In beginend.cc void rollback (); @@ -247,6 +249,7 @@ struct gtm_transaction // In local.cc void commit_local (void); void rollback_local (void); + void drop_references_local (const void *, size_t); // In retry.cc void decide_retry_strategy (gtm_restart_reason); Index: local.cc =================================================================== --- local.cc (revision 161187) +++ local.cc (working copy) @@ -30,6 +30,7 @@ struct gtm_local_undo { void *addr; size_t len; + bool ignore; char saved[]; }; @@ -65,13 +66,36 @@ gtm_transaction::rollback_local (void) for (i = n; i-- > 0; ) { gtm_local_undo *u = local_undo[i]; - memcpy (u->addr, u->saved, u->len); + if (!u->ignore) + memcpy (u->addr, u->saved, u->len); free (u); } this->n_local_undo = 0; } } +/* Forget any references to PTR in the local log. */ + +void +gtm_transaction::drop_references_local (const void *ptr, size_t len) +{ + gtm_local_undo **local_undo = this->local_undo; + size_t i, n = this->n_local_undo; + + if (n > 0) + { + for (i = n; i > 0; i--) + { + gtm_local_undo *u = local_undo[i]; + /* ?? Do we need such granularity, or can we get away with + just comparing PTR and LEN. ?? */ + if ((const char *)u->addr >= (const char *)ptr + && ((const char *)u->addr + u->len <= (const char *)ptr + len)) + u->ignore = true; + } + } +} + void ITM_REGPARM GTM_LB (const void *ptr, size_t len) { @@ -81,6 +105,7 @@ GTM_LB (const void *ptr, size_t len) undo = (gtm_local_undo *) xmalloc (sizeof (struct gtm_local_undo) + len); undo->addr = (void *) ptr; undo->len = len; + undo->ignore = false; if (tx->local_undo == NULL) {