From patchwork Fri Dec 19 07:37:43 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andi Kleen X-Patchwork-Id: 4356 Received: (qmail 14855 invoked by alias); 19 Dec 2014 07:38:06 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 14721 invoked by uid 89); 19 Dec 2014 07:38:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mga09.intel.com X-ExtLoop1: 1 From: Andi Kleen To: libc-alpha@sourceware.org Cc: Andi Kleen Subject: [PATCH 3/7] Separate configuration structure for rwlocks Date: Thu, 18 Dec 2014 23:37:43 -0800 Message-Id: <1418974667-32587-4-git-send-email-andi@firstfloor.org> In-Reply-To: <1418974667-32587-1-git-send-email-andi@firstfloor.org> References: <1418974667-32587-1-git-send-email-andi@firstfloor.org> From: Andi Kleen Use a separate configuration structure for rwlock elision. This allows a followup patch to change the rwlock elision parameters separately for mutexes and rwlocks. 2014-12-17 Andi Kleen * sysdeps/unix/sysv/linux/x86/elision-conf.c (__elision_rwconf): Add new tuning struct for rwlocks. (elision_init): Use __elision_rwconf to disable rwlock elision. * sysdeps/unix/sysv/linux/x86/elision-conf.h (__elision_rwconf): Declare new symbol. * sysdeps/x86/elide.h (elision_adapt): (elision_adapt): Use __elision_rwconf for retry counts. (ELIDE_TRYLOCK): Dito. --- sysdeps/unix/sysv/linux/x86/elision-conf.c | 20 +++++++++++++++++++- sysdeps/unix/sysv/linux/x86/elision-conf.h | 1 + sysdeps/x86/elide.h | 12 ++++++------ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/sysdeps/unix/sysv/linux/x86/elision-conf.c b/sysdeps/unix/sysv/linux/x86/elision-conf.c index c0405a3..a78cf49 100644 --- a/sysdeps/unix/sysv/linux/x86/elision-conf.c +++ b/sysdeps/unix/sysv/linux/x86/elision-conf.c @@ -44,6 +44,24 @@ struct elision_config __elision_aconf = .skip_trylock_internal_abort = 3, }; +struct elision_config __elision_rwconf = + { + /* How often to not attempt to use elision if a transaction aborted + because the lock is already acquired. Expressed in number of lock + acquisition attempts. */ + .skip_lock_busy = 3, + /* How often to not attempt to use elision if a transaction aborted due + to reasons other than other threads' memory accesses. Expressed in + number of lock acquisition attempts. */ + .skip_lock_internal_abort = 3, + /* How often we retry using elision if there is chance for the transaction + to finish execution (e.g., it wasn't aborted due to the lock being + already acquired. */ + .retry_try_xbegin = 3, + /* Same as SKIP_LOCK_INTERNAL_ABORT but for trylock. */ + .skip_trylock_internal_abort = 3, + }; + struct tune { const char *name; @@ -167,7 +185,7 @@ elision_init (int argc __attribute__ ((unused)), __pthread_force_elision = __libc_enable_secure ? 0 : __elision_available; #endif if (!HAS_RTM) - __elision_aconf.retry_try_xbegin = 0; /* Disable elision on rwlocks */ + __elision_rwconf.retry_try_xbegin = 0; /* Disable elision on rwlocks */ /* For static builds need to call this explicitely. Noop for dynamic. */ diff --git a/sysdeps/unix/sysv/linux/x86/elision-conf.h b/sysdeps/unix/sysv/linux/x86/elision-conf.h index 6790b5a..2d95a9f 100644 --- a/sysdeps/unix/sysv/linux/x86/elision-conf.h +++ b/sysdeps/unix/sysv/linux/x86/elision-conf.h @@ -33,6 +33,7 @@ struct elision_config }; extern struct elision_config __elision_aconf attribute_hidden; +extern struct elision_config __elision_rwconf attribute_hidden; extern int __elision_available attribute_hidden; extern int __pthread_force_elision attribute_hidden; diff --git a/sysdeps/x86/elide.h b/sysdeps/x86/elide.h index 5befa53..ed17fd4 100644 --- a/sysdeps/x86/elide.h +++ b/sysdeps/x86/elide.h @@ -36,14 +36,14 @@ elision_adapt(signed char *adapt_count, unsigned int status) /* Right now we skip here. Better would be to wait a bit and retry. This likely needs some spinning. Be careful to avoid writing the lock. */ - if (*adapt_count != __elision_aconf.skip_lock_busy) - ACCESS_ONCE (*adapt_count) = __elision_aconf.skip_lock_busy; + if (*adapt_count != __elision_rwconf.skip_lock_busy) + ACCESS_ONCE (*adapt_count) = __elision_rwconf.skip_lock_busy; } /* Internal abort. There is no chance for retry. Use the normal locking and next time use lock. Be careful to avoid writing to the lock. */ - else if (*adapt_count != __elision_aconf.skip_lock_internal_abort) - ACCESS_ONCE (*adapt_count) = __elision_aconf.skip_lock_internal_abort; + else if (*adapt_count != __elision_rwconf.skip_lock_internal_abort) + ACCESS_ONCE (*adapt_count) = __elision_rwconf.skip_lock_internal_abort; return true; } @@ -58,7 +58,7 @@ elision_adapt(signed char *adapt_count, unsigned int status) \ if ((adapt_count) <= 0) \ { \ - for (int i = __elision_aconf.retry_try_xbegin; i > 0; i--) \ + for (int i = __elision_rwconf.retry_try_xbegin; i > 0; i--) \ { \ unsigned int status; \ if ((status = _xbegin ()) == _XBEGIN_STARTED) \ @@ -84,7 +84,7 @@ elision_adapt(signed char *adapt_count, unsigned int status) #define ELIDE_TRYLOCK(adapt_count, is_lock_free, write) ({ \ int ret = 0; \ - if (__elision_aconf.retry_try_xbegin > 0) \ + if (__elision_rwconf.retry_try_xbegin > 0) \ { \ if (write) \ _xabort (_ABORT_NESTED_TRYLOCK); \