xref: /linux/tools/perf/bench/futex.c (revision c31f4aa8fed048fa70e742c4bb49bb48dc489ab3)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <err.h>
3 #include <errno.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <sys/prctl.h>
7 
8 #include "futex.h"
9 
10 #ifndef PR_FUTEX_HASH
11 #define PR_FUTEX_HASH                   78
12 # define PR_FUTEX_HASH_SET_SLOTS        1
13 # define PR_FUTEX_HASH_GET_SLOTS        2
14 #endif // PR_FUTEX_HASH
15 
16 void futex_set_nbuckets_param(struct bench_futex_parameters *params)
17 {
18 	int ret;
19 
20 	if (params->nbuckets < 0)
21 		return;
22 
23 	ret = prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_SET_SLOTS, params->nbuckets, 0);
24 	if (ret) {
25 		printf("Requesting %d hash buckets failed: %d/%m\n",
26 		       params->nbuckets, ret);
27 		err(EXIT_FAILURE, "prctl(PR_FUTEX_HASH)");
28 	}
29 }
30 
31 void futex_print_nbuckets(struct bench_futex_parameters *params)
32 {
33 	char *futex_hash_mode;
34 	int ret;
35 
36 	ret = prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_GET_SLOTS);
37 	if (params->nbuckets >= 0) {
38 		if (ret != params->nbuckets) {
39 			if (ret < 0) {
40 				printf("Can't query number of buckets: %m\n");
41 				err(EXIT_FAILURE, "prctl(PR_FUTEX_HASH)");
42 			}
43 			printf("Requested number of hash buckets does not currently used.\n");
44 			printf("Requested: %d in usage: %d\n", params->nbuckets, ret);
45 			err(EXIT_FAILURE, "prctl(PR_FUTEX_HASH)");
46 		}
47 		if (params->nbuckets == 0)
48 			ret = asprintf(&futex_hash_mode, "Futex hashing: global hash");
49 		else
50 			ret = asprintf(&futex_hash_mode, "Futex hashing: %d hash buckets",
51 				       params->nbuckets);
52 	} else {
53 		if (ret <= 0) {
54 			ret = asprintf(&futex_hash_mode, "Futex hashing: global hash");
55 		} else {
56 			ret = asprintf(&futex_hash_mode, "Futex hashing: auto resized to %d buckets",
57 				       ret);
58 		}
59 	}
60 	if (ret < 0)
61 		err(EXIT_FAILURE, "ENOMEM, futex_hash_mode");
62 	printf("%s\n", futex_hash_mode);
63 	free(futex_hash_mode);
64 }
65