tools/perf/bench/futex-wake.c

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

File Facts

System
Linux kernel
Corpus path
tools/perf/bench/futex-wake.c
Extension
.c
Size
6298 bytes
Lines
242
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

if (pthread_attr_setaffinity_np(&thread_attr, size, cpuset)) {
			CPU_FREE(cpuset);
			err(EXIT_FAILURE, "pthread_attr_setaffinity_np");
		}

		if (pthread_create(&w[i], &thread_attr, workerfn, NULL)) {
			CPU_FREE(cpuset);
			err(EXIT_FAILURE, "pthread_create");
		}
		pthread_attr_destroy(&thread_attr);
	}
	CPU_FREE(cpuset);
}

static void toggle_done(int sig __maybe_unused,
			siginfo_t *info __maybe_unused,
			void *uc __maybe_unused)
{
	done = true;
}

int bench_futex_wake(int argc, const char **argv)
{
	int ret = 0;
	unsigned int i, j;
	struct sigaction act;
	struct perf_cpu_map *cpu;

	argc = parse_options(argc, argv, options, bench_futex_wake_usage, 0);
	if (argc) {
		usage_with_options(bench_futex_wake_usage, options);
		exit(EXIT_FAILURE);
	}

	cpu = perf_cpu_map__new_online_cpus();
	if (!cpu)
		err(EXIT_FAILURE, "calloc");

	memset(&act, 0, sizeof(act));
	sigfillset(&act.sa_mask);
	act.sa_sigaction = toggle_done;
	sigaction(SIGINT, &act, NULL);

	if (params.mlockall) {
		if (mlockall(MCL_CURRENT | MCL_FUTURE))
			err(EXIT_FAILURE, "mlockall");
	}

	if (!params.nthreads)
		params.nthreads = perf_cpu_map__nr(cpu);

	worker = calloc(params.nthreads, sizeof(*worker));
	if (!worker)
		err(EXIT_FAILURE, "calloc");

	if (!params.fshared)
		futex_flag = FUTEX_PRIVATE_FLAG;

	printf("Run summary [PID %d]: blocking on %d threads (at [%s] futex %p), "
	       "waking up %d at a time.\n\n",
	       getpid(), params.nthreads, params.fshared ? "shared":"private",
	       &futex1, params.nwakes);

	init_stats(&wakeup_stats);
	init_stats(&waketime_stats);
	mutex_init(&thread_lock);
	cond_init(&thread_parent);
	cond_init(&thread_worker);

	for (j = 0; j < bench_repeat && !done; j++) {
		unsigned int nwoken = 0;
		struct timeval start, end, runtime;

		/* create, launch & block all threads */
		block_threads(worker, cpu);

		/* make sure all threads are already blocked */
		mutex_lock(&thread_lock);
		while (threads_starting)
			cond_wait(&thread_parent, &thread_lock);
		cond_broadcast(&thread_worker);
		mutex_unlock(&thread_lock);

		usleep(100000);

		/* Ok, all threads are patiently blocked, start waking folks up */
		gettimeofday(&start, NULL);
		while (nwoken != params.nthreads)
			nwoken += futex_wake(&futex1,
					     params.nwakes, futex_flag);

Annotation

Implementation Notes