diff --git a/src/dbinc/lock.h b/src/dbinc/lock.h index d6133e800..1090779ef 100644 --- a/src/dbinc/lock.h +++ b/src/dbinc/lock.h @@ -329,6 +329,8 @@ struct __db_lock { /* SHARED */ MUTEX_UNLOCK(env, (region)->mtx_dd) #define LOCK_LOCKERS(env, region) \ MUTEX_LOCK(env, (region)->mtx_lockers) +#define RDLOCK_LOCKERS(env, region) \ + MUTEX_READLOCK(env, (region)->mtx_lockers) #define UNLOCK_LOCKERS(env, region) \ MUTEX_UNLOCK(env, (region)->mtx_lockers) diff --git a/src/lock/lock.c b/src/lock/lock.c index 73400d92d..7bd16e870 100644 --- a/src/lock/lock.c +++ b/src/lock/lock.c @@ -596,7 +596,7 @@ __lock_get_api(env, locker, flags, obj, lock_mode, lock) region = env->lk_handle->reginfo.primary; - LOCK_LOCKERS(env, region); + RDLOCK_LOCKERS(env, region); ret = __lock_getlocker_int(env->lk_handle, locker, 0, &sh_locker); UNLOCK_LOCKERS(env, region); LOCK_SYSTEM_LOCK(env->lk_handle, region); diff --git a/src/lock/lock_region.c b/src/lock/lock_region.c index bd5a7a170..29695cdfb 100644 --- a/src/lock/lock_region.c +++ b/src/lock/lock_region.c @@ -253,8 +253,16 @@ __lock_region_init(env, lt) env, MTX_LOCK_REGION, 0, ®ion->mtx_dd)) != 0) return (ret); + /* + * The locker mutex is a SHARED latch: the hot lock-get path looks up + * an existing locker (a read-only hash walk) and takes it shared, so + * many cores can resolve their locker concurrently; locker create, + * free, the deadlock detector's locker-list walk, failchk, and stat + * take it exclusive. This removes the per-operation global + * serialization on lock_get/lock_put. + */ if ((ret = __mutex_alloc( - env, MTX_LOCK_REGION, 0, ®ion->mtx_lockers)) != 0) + env, MTX_LOCK_REGION, DB_MUTEX_SHARED, ®ion->mtx_lockers)) != 0) return (ret); /* Allocate room for the locker hash table and initialize it. */