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