summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/include/mutex_inline.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/include/mutex_inline.h')
-rw-r--r--src/third_party/wiredtiger/src/include/mutex_inline.h70
1 files changed, 67 insertions, 3 deletions
diff --git a/src/third_party/wiredtiger/src/include/mutex_inline.h b/src/third_party/wiredtiger/src/include/mutex_inline.h
index 8fab4d84628..3b6405bb442 100644
--- a/src/third_party/wiredtiger/src/include/mutex_inline.h
+++ b/src/third_party/wiredtiger/src/include/mutex_inline.h
@@ -14,6 +14,13 @@
*/
/*
+ * WT_SPIN_SESSION_ID_SAFE --
+ * Get the session ID. We need this because there are a few calls to lock and unlock where the
+ * session parameter is actually NULL.
+ */
+#define WT_SPIN_SESSION_ID_SAFE(session) ((session) != NULL ? (session)->id : WT_SESSION_ID_NULL)
+
+/*
* __spin_init_internal --
* Initialize the WT portion of a spinlock.
*/
@@ -21,6 +28,7 @@ static inline void
__spin_init_internal(WT_SPINLOCK *t, const char *name)
{
t->name = name;
+ t->session_id = WT_SESSION_ID_INVALID;
t->stat_count_off = t->stat_app_usecs_off = t->stat_int_usecs_off = -1;
t->stat_session_usecs_off = -1;
t->initialized = 1;
@@ -68,7 +76,11 @@ __wt_spin_trylock(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
{
WT_UNUSED(session);
- return (!__atomic_test_and_set(&t->lock, __ATOMIC_ACQUIRE) ? 0 : EBUSY);
+ if (!__atomic_test_and_set(&t->lock, __ATOMIC_ACQUIRE)) {
+ t->session_id = WT_SPIN_SESSION_ID_SAFE(session);
+ return (0);
+ } else
+ return (EBUSY);
}
/*
@@ -88,6 +100,8 @@ __wt_spin_lock(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
if (t->lock)
__wt_yield();
}
+
+ t->session_id = WT_SPIN_SESSION_ID_SAFE(session);
}
/*
@@ -99,6 +113,7 @@ __wt_spin_unlock(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
{
WT_UNUSED(session);
+ t->session_id = WT_SESSION_ID_INVALID;
__atomic_clear(&t->lock, __ATOMIC_RELEASE);
}
@@ -154,9 +169,13 @@ __wt_spin_destroy(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
static inline int
__wt_spin_trylock(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
{
+ WT_DECL_RET;
WT_UNUSED(session);
- return (pthread_mutex_trylock(&t->lock));
+ ret = pthread_mutex_trylock(&t->lock);
+ if (ret == 0)
+ t->session_id = WT_SPIN_SESSION_ID_SAFE(session);
+ return (ret);
}
/*
@@ -170,6 +189,7 @@ __wt_spin_lock(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
if ((ret = pthread_mutex_lock(&t->lock)) != 0)
WT_IGNORE_RET(__wt_panic(session, ret, "pthread_mutex_lock: %s", t->name));
+ t->session_id = WT_SPIN_SESSION_ID_SAFE(session);
}
#endif
@@ -182,6 +202,7 @@ __wt_spin_unlock(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
{
WT_DECL_RET;
+ t->session_id = WT_SESSION_ID_INVALID;
if ((ret = pthread_mutex_unlock(&t->lock)) != 0)
WT_IGNORE_RET(__wt_panic(session, ret, "pthread_mutex_unlock: %s", t->name));
}
@@ -233,7 +254,10 @@ __wt_spin_trylock(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
WT_UNUSED(session);
BOOL b = TryEnterCriticalSection(&t->lock);
- return (b == 0 ? EBUSY : 0);
+ if (b == 0)
+ return (EBUSY);
+ t->session_id = WT_SPIN_SESSION_ID_SAFE(session);
+ return (0);
}
/*
@@ -246,6 +270,7 @@ __wt_spin_lock(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
WT_UNUSED(session);
EnterCriticalSection(&t->lock);
+ t->session_id = WT_SPIN_SESSION_ID_SAFE(session);
}
/*
@@ -257,6 +282,7 @@ __wt_spin_unlock(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
{
WT_UNUSED(session);
+ t->session_id = WT_SESSION_ID_INVALID;
LeaveCriticalSection(&t->lock);
}
@@ -267,6 +293,44 @@ __wt_spin_unlock(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
#endif
/*
+ * __wt_spin_locked --
+ * Check whether the spinlock is locked, irrespective of which session locked it.
+ */
+static inline bool
+__wt_spin_locked(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
+{
+ WT_UNUSED(session);
+ return (t->session_id != WT_SESSION_ID_INVALID);
+}
+
+/*
+ * __wt_spin_owned --
+ * Check whether the session owns the spinlock.
+ */
+static inline bool
+__wt_spin_owned(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
+{
+ return (t->session_id == WT_SPIN_SESSION_ID_SAFE(session));
+}
+
+/*
+ * __wt_spin_unlock_if_owned --
+ * Unlock the spinlock only if it is acquired by the specified session.
+ */
+static inline void
+__wt_spin_unlock_if_owned(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
+{
+ if (__wt_spin_owned(session, t))
+ __wt_spin_unlock(session, t);
+}
+
+/*
+ * WT_ASSERT_SPINLOCK_OWNED --
+ * Assert that the session owns the spinlock.
+ */
+#define WT_ASSERT_SPINLOCK_OWNED(session, t) WT_ASSERT((session), __wt_spin_owned((session), (t)));
+
+/*
* WT_SPIN_INIT_TRACKED --
* Spinlock initialization, with tracking.
*