tools/perf/bench/futex-hash.c

Source file repositories/reference/linux-study-clean/tools/perf/bench/futex-hash.c

File Facts

System
Linux kernel
Corpus path
tools/perf/bench/futex-hash.c
Extension
.c
Size
6873 bytes
Lines
257
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct worker {
	int tid;
	u_int32_t *futex;
	pthread_t thread;
	unsigned long ops;
};

static struct bench_futex_parameters params = {
	.nfutexes = 1024,
	.runtime  = 10,
	.nbuckets = -1,
};

static const struct option options[] = {
	OPT_INTEGER( 'b', "buckets", &params.nbuckets, "Specify amount of hash buckets"),
	OPT_UINTEGER('t', "threads", &params.nthreads, "Specify amount of threads"),
	OPT_UINTEGER('r', "runtime", &params.runtime, "Specify runtime (in seconds)"),
	OPT_UINTEGER('f', "futexes", &params.nfutexes, "Specify amount of futexes per threads"),
	OPT_BOOLEAN( 's', "silent",  &params.silent, "Silent mode: do not display data/details"),
	OPT_BOOLEAN( 'S', "shared",  &params.fshared, "Use shared futexes instead of private ones"),
	OPT_BOOLEAN( 'm', "mlockall", &params.mlockall, "Lock all current and future memory"),
	OPT_END()
};

static const char * const bench_futex_hash_usage[] = {
	"perf bench futex hash <options>",
	NULL
};

static void *workerfn(void *arg)
{
	int ret;
	struct worker *w = (struct worker *) arg;
	unsigned int i;
	unsigned long ops = w->ops; /* avoid cacheline bouncing */

	mutex_lock(&thread_lock);
	threads_starting--;
	if (!threads_starting)
		cond_signal(&thread_parent);
	cond_wait(&thread_worker, &thread_lock);
	mutex_unlock(&thread_lock);

	do {
		for (i = 0; i < params.nfutexes; i++, ops++) {
			/*
			 * We want the futex calls to fail in order to stress
			 * the hashing of uaddr and not measure other steps,
			 * such as internal waitqueue handling, thus enlarging
			 * the critical region protected by hb->lock.
			 */
			ret = futex_wait(&w->futex[i], 1234, NULL, futex_flag);
			if (!params.silent &&
			    (!ret || errno != EAGAIN || errno != EWOULDBLOCK))
				warn("Non-expected futex return call");
		}
	}  while (!done);

	w->ops = ops;
	return NULL;
}

static void toggle_done(int sig __maybe_unused,
			siginfo_t *info __maybe_unused,
			void *uc __maybe_unused)
{
	/* inform all threads that we're done for the day */
	done = true;
	gettimeofday(&bench__end, NULL);
	timersub(&bench__end, &bench__start, &bench__runtime);
}

static void print_summary(void)
{
	unsigned long avg = avg_stats(&throughput_stats);
	double stddev = stddev_stats(&throughput_stats);

	printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n",
	       !params.silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg),
	       (int)bench__runtime.tv_sec);
	futex_print_nbuckets(&params);
}

int bench_futex_hash(int argc, const char **argv)
{
	int ret = 0;
	cpu_set_t *cpuset;
	struct sigaction act;
	unsigned int i;
	pthread_attr_t thread_attr;

Annotation

Implementation Notes