xref: /openbmc/linux/tools/perf/util/sharded_mutex.h (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
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 Rogers static 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