tools/perf/bench/futex-requeue.c

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

File Facts

System
Linux kernel
Corpus path
tools/perf/bench/futex-requeue.c
Extension
.c
Size
8273 bytes
Lines
320
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 (!params.pi) {
			ret = futex_wait(&futex1, 0, NULL, futex_flag);
			if (!ret)
				break;

			if (ret && errno != EAGAIN) {
				if (!params.silent)
					warnx("futex_wait");
				break;
			}
		} else {
			ret = futex_wait_requeue_pi(&futex1, 0, &futex2,
						    NULL, futex_flag);
			if (!ret) {
				/* got the lock at futex2 */
				futex_unlock_pi(&futex2, futex_flag);
				break;
			}

			if (ret && errno != EAGAIN) {
				if (!params.silent)
					warnx("futex_wait_requeue_pi");
				break;
			}
		}
	}

	return NULL;
}

static void block_threads(pthread_t *w, struct perf_cpu_map *cpu)
{
	cpu_set_t *cpuset;
	unsigned int i;
	int nrcpus = cpu__max_cpu().cpu;
	size_t size;

	threads_starting = params.nthreads;

	cpuset = CPU_ALLOC(nrcpus);
	BUG_ON(!cpuset);
	size = CPU_ALLOC_SIZE(nrcpus);

	/* create and block all threads */
	for (i = 0; i < params.nthreads; i++) {
		pthread_attr_t thread_attr;

		pthread_attr_init(&thread_attr);
		CPU_ZERO_S(size, cpuset);
		CPU_SET_S(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, size, cpuset);

		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_requeue(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_requeue_usage, 0);
	if (argc)
		goto err;

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

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

Annotation

Implementation Notes