Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Feb 2018 00:38:14 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r329540 - in head/sys: kern sys
Message-ID:  <201802190038.w1J0cE7U090402@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Mon Feb 19 00:38:14 2018
New Revision: 329540
URL: https://svnweb.freebsd.org/changeset/base/329540

Log:
  mtx: add mtx_spin_wait_unlocked
  
  The primitive can be used to wait for the lock to be released. Intended
  usage is for locks in structures which are about to be freed.
  
  The benefit is the avoided interrupt enable/disable trip + atomic op to
  grab the lock and shorter wait if the lock is held (since there is no
  worry someone will contend on the lock, re-reads can be more aggressive).
  
  Briefly discussed with:	 kib

Modified:
  head/sys/kern/kern_mutex.c
  head/sys/sys/mutex.h

Modified: head/sys/kern/kern_mutex.c
==============================================================================
--- head/sys/kern/kern_mutex.c	Sun Feb 18 23:35:23 2018	(r329539)
+++ head/sys/kern/kern_mutex.c	Mon Feb 19 00:38:14 2018	(r329540)
@@ -1226,6 +1226,23 @@ _mtx_lock_indefinite_check(struct mtx *m, struct lock_
 	cpu_spinwait();
 }
 
+void
+mtx_spin_wait_unlocked(struct mtx *m)
+{
+	struct lock_delay_arg lda;
+
+	lda.spin_cnt = 0;
+
+	while (atomic_load_acq_ptr(&m->mtx_lock) != MTX_UNOWNED) {
+		if (__predict_true(lda.spin_cnt < 10000000)) {
+			cpu_spinwait();
+			lda.spin_cnt++;
+		} else {
+			_mtx_lock_indefinite_check(m, &lda);
+		}
+	}
+}
+
 #ifdef DDB
 void
 db_show_mtx(const struct lock_object *lock)

Modified: head/sys/sys/mutex.h
==============================================================================
--- head/sys/sys/mutex.h	Sun Feb 18 23:35:23 2018	(r329539)
+++ head/sys/sys/mutex.h	Mon Feb 19 00:38:14 2018	(r329540)
@@ -125,6 +125,8 @@ int	__mtx_trylock_spin_flags(volatile uintptr_t *c, in
 	     const char *file, int line);
 void	__mtx_unlock_spin_flags(volatile uintptr_t *c, int opts,
 	    const char *file, int line);
+void	mtx_spin_wait_unlocked(struct mtx *m);
+
 #if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
 void	__mtx_assert(const volatile uintptr_t *c, int what, const char *file,
 	    int line);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802190038.w1J0cE7U090402>