Signed-off-by: Thomas Gleixner --- tools/perf/bench/futex-hash.c | 40 ++++++++++++++++++++++++++++++---------- tools/perf/bench/futex.h | 14 ++++++++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) Index: b/tools/perf/bench/futex-hash.c =================================================================== --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c @@ -25,7 +25,7 @@ static unsigned int nthreads = 0; static unsigned int nsecs = 10; /* amount of futexes per thread */ static unsigned int nfutexes = 1024; -static bool fshared = false, done = false, silent = false; +static bool fshared = false, done = false, silent = false, attached = false; static int futex_flag = 0; struct timeval start, end, runtime; @@ -42,11 +42,12 @@ struct worker { }; static const struct option options[] = { - OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), - OPT_UINTEGER('r', "runtime", &nsecs, "Specify runtime (in seconds)"), - OPT_UINTEGER('f', "futexes", &nfutexes, "Specify amount of futexes per threads"), - OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), - OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), + OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), + OPT_UINTEGER('r', "runtime", &nsecs, "Specify runtime (in seconds)"), + OPT_UINTEGER('f', "futexes", &nfutexes, "Specify amount of futexes per threads"), + OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), + OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), + OPT_BOOLEAN( 'a', "attached", &attached, "Use attached futexes"), OPT_END() }; @@ -61,6 +62,14 @@ static void *workerfn(void *arg) unsigned int i; struct worker *w = (struct worker *) arg; + if (attached) { + for (i = 0; i < nfutexes; i++) { + ret = futex_attach(&w->futex[i], futex_flag); + if (ret < 0) + err(EXIT_FAILURE, "Attach futex failed\n"); + } + } + pthread_mutex_lock(&thread_lock); threads_starting--; if (!threads_starting) @@ -83,6 +92,14 @@ static void *workerfn(void *arg) } } while (!done); + if (attached) { + for (i = 0; i < nfutexes; i++) { + ret = futex_detach(&w->futex[i], futex_flag); + if (ret < 0) + err(EXIT_FAILURE, "Detach futex failed"); + } + } + return NULL; } @@ -136,10 +153,13 @@ int bench_futex_hash(int argc, const cha goto errmem; if (!fshared) - futex_flag = FUTEX_PRIVATE_FLAG; - - printf("Run summary [PID %d]: %d threads, each operating on %d [%s] futexes for %d secs.\n\n", - getpid(), nthreads, nfutexes, fshared ? "shared":"private", nsecs); + futex_flag |= FUTEX_PRIVATE_FLAG; + if (attached) + futex_flag |= FUTEX_ATTACHED; + + printf("Run summary [PID %d]: %d threads, each operating on %d [%s %s] futexes for %d secs.\n\n", + getpid(), nthreads, nfutexes, fshared ? "shared":"private", + attached ? "attached" : "", nsecs); init_stats(&throughput_stats); pthread_mutex_init(&thread_lock, NULL); Index: b/tools/perf/bench/futex.h =================================================================== --- a/tools/perf/bench/futex.h +++ b/tools/perf/bench/futex.h @@ -101,4 +101,18 @@ static inline int pthread_attr_setaffini } #endif +#define FUTEX_ATTACH 13 +#define FUTEX_DETACH 14 +#define FUTEX_ATTACHED 512 + +static inline int futex_attach(u_int32_t *uaddr, int opflags) +{ + return futex(uaddr, FUTEX_ATTACH, 0, NULL, NULL, 0, opflags); +} + +static inline int futex_detach(u_int32_t *uaddr, int opflags) +{ + return futex(uaddr, FUTEX_DETACH, 0, NULL, NULL, 0, opflags); +} + #endif /* _FUTEX_H */