1*0650b2b2SIan Rogers /* SPDX-License-Identifier: GPL-2.0 */ 2*0650b2b2SIan Rogers #ifndef PERF_SHARDED_MUTEX_H 3*0650b2b2SIan Rogers #define PERF_SHARDED_MUTEX_H 4*0650b2b2SIan Rogers 5*0650b2b2SIan Rogers #include "mutex.h" 6*0650b2b2SIan Rogers #include "hashmap.h" 7*0650b2b2SIan Rogers 8*0650b2b2SIan Rogers /* 9*0650b2b2SIan Rogers * In a situation where a lock is needed per object, having a mutex can be 10*0650b2b2SIan Rogers * relatively memory expensive (40 bytes on x86-64). If the object can be 11*0650b2b2SIan Rogers * constantly hashed, a sharded mutex is an alternative global pool of mutexes 12*0650b2b2SIan Rogers * where the mutex is looked up from a hash value. This can lead to collisions 13*0650b2b2SIan Rogers * if the number of shards isn't large enough. 14*0650b2b2SIan Rogers */ 15*0650b2b2SIan Rogers struct sharded_mutex { 16*0650b2b2SIan Rogers /* mutexes array is 1<<cap_bits in size. */ 17*0650b2b2SIan Rogers unsigned int cap_bits; 18*0650b2b2SIan Rogers struct mutex mutexes[]; 19*0650b2b2SIan Rogers }; 20*0650b2b2SIan Rogers 21*0650b2b2SIan Rogers struct sharded_mutex *sharded_mutex__new(size_t num_shards); 22*0650b2b2SIan Rogers void sharded_mutex__delete(struct sharded_mutex *sm); 23*0650b2b2SIan Rogers sharded_mutex__get_mutex(struct sharded_mutex * sm,size_t hash)24*0650b2b2SIan Rogersstatic inline struct mutex *sharded_mutex__get_mutex(struct sharded_mutex *sm, size_t hash) 25*0650b2b2SIan Rogers { 26*0650b2b2SIan Rogers return &sm->mutexes[hash_bits(hash, sm->cap_bits)]; 27*0650b2b2SIan Rogers } 28*0650b2b2SIan Rogers 29*0650b2b2SIan Rogers #endif /* PERF_SHARDED_MUTEX_H */ 30