summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <andrew.morton@mongodb.com>2023-05-16 22:21:24 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-05-17 00:50:01 +0000
commite94168acd89dba4faef5e43f970633a781e8cba2 (patch)
tree0d7652f551fe7152fa49512ca1ba7ff730b51e79
parentb34244749ab66e8aa761dbc715dad736e3186894 (diff)
downloadmongo-e94168acd89dba4faef5e43f970633a781e8cba2.tar.gz
Import wiredtiger: d310d6330ea5b23835d9eb231f65bb9f91bdef21 from branch mongodb-master
ref: 2a63f4a39c..d310d6330e for: 7.1.0-rc0 WT-11066 Add mechanisms for checking whether a session holds a spinlock
-rw-r--r--src/third_party/wiredtiger/dist/s_funcs.list2
-rw-r--r--src/third_party/wiredtiger/dist/s_string.ok1
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/src/include/extern.h5
-rw-r--r--src/third_party/wiredtiger/src/include/mutex.h3
-rw-r--r--src/third_party/wiredtiger/src/include/mutex_inline.h70
-rw-r--r--src/third_party/wiredtiger/src/include/session.h6
7 files changed, 84 insertions, 5 deletions
diff --git a/src/third_party/wiredtiger/dist/s_funcs.list b/src/third_party/wiredtiger/dist/s_funcs.list
index 1b831580e27..7ac890052d6 100644
--- a/src/third_party/wiredtiger/dist/s_funcs.list
+++ b/src/third_party/wiredtiger/dist/s_funcs.list
@@ -31,6 +31,8 @@ __wt_nlpo2
__wt_nlpo2_round
__wt_print_huffman_code
__wt_session_breakpoint
+__wt_spin_locked
+__wt_spin_unlock_if_owned
__wt_stat_join_aggregate
__wt_stat_join_clear_all
__wt_strcat
diff --git a/src/third_party/wiredtiger/dist/s_string.ok b/src/third_party/wiredtiger/dist/s_string.ok
index b6dd3317d7c..cdfa81cadef 100644
--- a/src/third_party/wiredtiger/dist/s_string.ok
+++ b/src/third_party/wiredtiger/dist/s_string.ok
@@ -329,6 +329,7 @@ SDK
SIMD
SLVG
SMT
+SPINLOCK
SSHH
SSq
STR
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index cef97e34740..426b41c6c48 100644
--- a/src/third_party/wiredtiger/import.data
+++ b/src/third_party/wiredtiger/import.data
@@ -2,5 +2,5 @@
"vendor": "wiredtiger",
"github": "wiredtiger/wiredtiger.git",
"branch": "mongodb-master",
- "commit": "2a63f4a39c3a74467005c2c7423823f22f5af394"
+ "commit": "d310d6330ea5b23835d9eb231f65bb9f91bdef21"
}
diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h
index 4fa14f94f2a..19e55c1feee 100644
--- a/src/third_party/wiredtiger/src/include/extern.h
+++ b/src/third_party/wiredtiger/src/include/extern.h
@@ -2085,6 +2085,10 @@ static inline bool __wt_row_leaf_value_is_encoded(WT_ROW *rip)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline bool __wt_session_can_wait(WT_SESSION_IMPL *session)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+static inline bool __wt_spin_locked(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
+ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
+static inline bool __wt_spin_owned(WT_SESSION_IMPL *session, WT_SPINLOCK *t)
+ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline bool __wt_split_descent_race(WT_SESSION_IMPL *session, WT_REF *ref,
WT_PAGE_INDEX *saved_pindex) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline bool __wt_txn_tw_start_visible(WT_SESSION_IMPL *session, WT_TIME_WINDOW *tw)
@@ -2480,6 +2484,7 @@ static inline void __wt_spin_destroy(WT_SESSION_IMPL *session, WT_SPINLOCK *t);
static inline void __wt_spin_lock(WT_SESSION_IMPL *session, WT_SPINLOCK *t);
static inline void __wt_spin_lock_track(WT_SESSION_IMPL *session, WT_SPINLOCK *t);
static inline void __wt_spin_unlock(WT_SESSION_IMPL *session, WT_SPINLOCK *t);
+static inline void __wt_spin_unlock_if_owned(WT_SESSION_IMPL *session, WT_SPINLOCK *t);
static inline void __wt_struct_size_adjust(WT_SESSION_IMPL *session, size_t *sizep);
static inline void __wt_timing_stress(WT_SESSION_IMPL *session, u_int flag, struct timespec *tsp);
static inline void __wt_timing_stress_sleep_random(WT_SESSION_IMPL *session);
diff --git a/src/third_party/wiredtiger/src/include/mutex.h b/src/third_party/wiredtiger/src/include/mutex.h
index 43eb7b2376a..143de6ce6f9 100644
--- a/src/third_party/wiredtiger/src/include/mutex.h
+++ b/src/third_party/wiredtiger/src/include/mutex.h
@@ -108,7 +108,8 @@ struct __wt_spinlock {
#error Unknown spinlock type
#endif
- const char *name; /* Mutex name */
+ const char *name; /* Mutex name */
+ uint32_t session_id; /* The session ID */
/*
* We track acquisitions and time spent waiting for some locks. For performance reasons and to
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.
*
diff --git a/src/third_party/wiredtiger/src/include/session.h b/src/third_party/wiredtiger/src/include/session.h
index 43a336eb214..f9a49ae7030 100644
--- a/src/third_party/wiredtiger/src/include/session.h
+++ b/src/third_party/wiredtiger/src/include/session.h
@@ -53,6 +53,12 @@ typedef TAILQ_HEAD(__wt_cursor_list, __wt_cursor) WT_CURSOR_LIST;
/* Maximum number of buckets to visit during a regular cursor sweep. */
#define WT_SESSION_CURSOR_SWEEP_MAX 64
+/* Invalid session ID. */
+#define WT_SESSION_ID_INVALID 0xffffffff
+
+/* A fake session ID for when we need to refer to a session that is actually NULL. */
+#define WT_SESSION_ID_NULL 0xfffffffe
+
/*
* WT_SESSION_IMPL --
* Implementation of WT_SESSION.