diff --git a/tools/perf/util/Build b/tools/perf/util/Build index ff2fd1a36bb8..96f4ea1d45c5 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -145,6 +145,7 @@ perf-y += mem2node.o perf-y += clockid.o perf-y += list_sort.o perf-y += mutex.o +perf-y += sharded_mutex.o perf-$(CONFIG_LIBBPF) += bpf-loader.o perf-$(CONFIG_LIBBPF) += bpf_map.o diff --git a/tools/perf/util/sharded_mutex.c b/tools/perf/util/sharded_mutex.c new file mode 100644 index 000000000000..e11e8d0945a7 --- /dev/null +++ b/tools/perf/util/sharded_mutex.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "sharded_mutex.h" + +#include + +struct sharded_mutex *sharded_mutex__new(size_t num_shards) +{ + struct sharded_mutex *result; + size_t size; + unsigned int bits; + + for (bits = 0; ((size_t)1 << bits) < num_shards; bits++) + ; + + size = sizeof(*result) + sizeof(struct mutex) * (1 << bits); + result = malloc(size); + if (!result) + return NULL; + + result->cap_bits = bits; + for (size_t i = 0; i < ((size_t)1 << bits); i++) + mutex_init(&result->mutexes[i]); + + return result; +} + +void sharded_mutex__delete(struct sharded_mutex *sm) +{ + for (size_t i = 0; i < ((size_t)1 << sm->cap_bits); i++) + mutex_destroy(&sm->mutexes[i]); + + free(sm); +} diff --git a/tools/perf/util/sharded_mutex.h b/tools/perf/util/sharded_mutex.h new file mode 100644 index 000000000000..7325e969eee3 --- /dev/null +++ b/tools/perf/util/sharded_mutex.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef PERF_SHARDED_MUTEX_H +#define PERF_SHARDED_MUTEX_H + +#include "mutex.h" +#include "hashmap.h" + +/* + * In a situation where a lock is needed per object, having a mutex can be + * relatively memory expensive (40 bytes on x86-64). If the object can be + * constantly hashed, a sharded mutex is an alternative global pool of mutexes + * where the mutex is looked up from a hash value. This can lead to collisions + * if the number of shards isn't large enough. + */ +struct sharded_mutex { + /* mutexes array is 1<mutexes[hash_bits(hash, sm->cap_bits)]; +} + +#endif /* PERF_SHARDED_MUTEX_H */