tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c
Extension
.c
Size
4235 bytes
Lines
174
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 random_thread_args {
	pthread_t thread_id;
	bool do_yields;
	pthread_barrier_t *barrier;
};

void *dscr_explicit_random_thread(void *in)
{
	struct random_thread_args *args = (struct random_thread_args *)in;
	unsigned long expected_dscr = 0;
	int err;

	srand(gettid());

	err = pthread_barrier_wait(args->barrier);
	FAIL_IF_EXIT(err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD);

	for (int i = 0; i < COUNT; i++) {
		expected_dscr = rand() % DSCR_MAX;
		set_dscr(expected_dscr);

		for (int j = rand() % 5; j > 0; --j) {
			FAIL_IF_EXIT(get_dscr() != expected_dscr);
			FAIL_IF_EXIT(get_dscr_usr() != expected_dscr);

			if (args->do_yields && rand() % 2)
				sched_yield();
		}

		expected_dscr = rand() % DSCR_MAX;
		set_dscr_usr(expected_dscr);

		for (int j = rand() % 5; j > 0; --j) {
			FAIL_IF_EXIT(get_dscr() != expected_dscr);
			FAIL_IF_EXIT(get_dscr_usr() != expected_dscr);

			if (args->do_yields && rand() % 2)
				sched_yield();
		}
	}

	return NULL;
}

int dscr_explicit_random_test(void)
{
	struct random_thread_args threads[THREADS];
	pthread_barrier_t barrier;

	SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));

	FAIL_IF(pthread_barrier_init(&barrier, NULL, THREADS));

	for (int i = 0; i < THREADS; i++) {
		threads[i].do_yields = i % 2 == 0;
		threads[i].barrier = &barrier;

		FAIL_IF(pthread_create(&threads[i].thread_id, NULL,
				       dscr_explicit_random_thread, (void *)&threads[i]));
	}

	for (int i = 0; i < THREADS; i++)
		FAIL_IF(pthread_join(threads[i].thread_id, NULL));

	FAIL_IF(pthread_barrier_destroy(&barrier));

	return 0;
}

int main(int argc, char *argv[])
{
	unsigned long orig_dscr_default = 0;
	int err = 0;

	if (have_hwcap2(PPC_FEATURE2_DSCR))
		orig_dscr_default = get_default_dscr();

	err |= test_harness(dscr_explicit_lockstep_test, "dscr_explicit_lockstep_test");
	err |= test_harness(dscr_explicit_random_test, "dscr_explicit_random_test");

	if (have_hwcap2(PPC_FEATURE2_DSCR))
		set_default_dscr(orig_dscr_default);

	return err;
}

Annotation

Implementation Notes