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