github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/ingester/locker.go (about) 1 package ingester 2 3 import ( 4 "sync" 5 "unsafe" 6 7 "github.com/prometheus/common/model" 8 9 "github.com/cortexproject/cortex/pkg/util" 10 ) 11 12 const ( 13 cacheLineSize = 64 14 ) 15 16 // Avoid false sharing when using array of mutexes. 17 type paddedMutex struct { 18 sync.Mutex 19 //nolint:structcheck,unused 20 pad [cacheLineSize - unsafe.Sizeof(sync.Mutex{})]byte 21 } 22 23 // fingerprintLocker allows locking individual fingerprints. To limit the number 24 // of mutexes needed for that, only a fixed number of mutexes are 25 // allocated. Fingerprints to be locked are assigned to those pre-allocated 26 // mutexes by their value. Collisions are not detected. If two fingerprints get 27 // assigned to the same mutex, only one of them can be locked at the same 28 // time. As long as the number of pre-allocated mutexes is much larger than the 29 // number of goroutines requiring a fingerprint lock concurrently, the loss in 30 // efficiency is small. However, a goroutine must never lock more than one 31 // fingerprint at the same time. (In that case a collision would try to acquire 32 // the same mutex twice). 33 type fingerprintLocker struct { 34 fpMtxs []paddedMutex 35 numFpMtxs uint32 36 } 37 38 // newFingerprintLocker returns a new fingerprintLocker ready for use. At least 39 // 1024 preallocated mutexes are used, even if preallocatedMutexes is lower. 40 func newFingerprintLocker(preallocatedMutexes int) *fingerprintLocker { 41 if preallocatedMutexes < 1024 { 42 preallocatedMutexes = 1024 43 } 44 return &fingerprintLocker{ 45 make([]paddedMutex, preallocatedMutexes), 46 uint32(preallocatedMutexes), 47 } 48 } 49 50 // Lock locks the given fingerprint. 51 func (l *fingerprintLocker) Lock(fp model.Fingerprint) { 52 l.fpMtxs[util.HashFP(fp)%l.numFpMtxs].Lock() 53 } 54 55 // Unlock unlocks the given fingerprint. 56 func (l *fingerprintLocker) Unlock(fp model.Fingerprint) { 57 l.fpMtxs[util.HashFP(fp)%l.numFpMtxs].Unlock() 58 }