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