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