diff --git a/storage/local/locker.go b/storage/local/locker.go index 1628ec127..85effcdbe 100644 --- a/storage/local/locker.go +++ b/storage/local/locker.go @@ -15,10 +15,21 @@ package local import ( "sync" + "unsafe" "github.com/prometheus/common/model" ) +const ( + cacheLineSize = 64 +) + +// Avoid false sharing when using array of mutexes. +type paddedMutex struct { + sync.Mutex + pad [cacheLineSize - unsafe.Sizeof(sync.Mutex{})]byte +} + // fingerprintLocker allows locking individual fingerprints. To limit the number // of mutexes needed for that, only a fixed number of mutexes are // allocated. Fingerprints to be locked are assigned to those pre-allocated @@ -30,7 +41,7 @@ import ( // fingerprint at the same time. (In that case a collision would try to acquire // the same mutex twice). type fingerprintLocker struct { - fpMtxs []sync.Mutex + fpMtxs []paddedMutex numFpMtxs uint } @@ -41,7 +52,7 @@ func newFingerprintLocker(preallocatedMutexes int) *fingerprintLocker { preallocatedMutexes = 1024 } return &fingerprintLocker{ - make([]sync.Mutex, preallocatedMutexes), + make([]paddedMutex, preallocatedMutexes), uint(preallocatedMutexes), } }