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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/powerpc/dscr/dscr_default_test.c
Extension
.c
Size
4392 bytes
Lines
170
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;
	unsigned long *expected_system_dscr;
	pthread_rwlock_t *rw_lock;
	pthread_barrier_t *barrier;
};

static void *dscr_default_random_thread(void *in)
{
	struct random_thread_args *args = (struct random_thread_args *)in;
	unsigned long *expected_dscr_p = args->expected_system_dscr;
	pthread_rwlock_t *rw_lock = args->rw_lock;
	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++) {
		unsigned long expected_dscr;
		unsigned long current_dscr;
		unsigned long current_dscr_usr;

		FAIL_IF_EXIT(pthread_rwlock_rdlock(rw_lock));
		expected_dscr = *expected_dscr_p;
		current_dscr = get_dscr();
		current_dscr_usr = get_dscr_usr();
		FAIL_IF_EXIT(pthread_rwlock_unlock(rw_lock));

		FAIL_IF_EXIT(current_dscr != expected_dscr);
		FAIL_IF_EXIT(current_dscr_usr != expected_dscr);

		if (rand() % 10 == 0) {
			unsigned long next_dscr;

			FAIL_IF_EXIT(pthread_rwlock_wrlock(rw_lock));
			next_dscr = (*expected_dscr_p + 1) % DSCR_MAX;
			set_default_dscr(next_dscr);
			*expected_dscr_p = next_dscr;
			FAIL_IF_EXIT(pthread_rwlock_unlock(rw_lock));
		}
	}

	pthread_exit((void *)0);
}

int dscr_default_random_test(void)
{
	struct random_thread_args threads[THREADS];
	unsigned long expected_system_dscr = 0;
	pthread_rwlockattr_t rwlock_attr;
	pthread_rwlock_t rw_lock;
	pthread_barrier_t barrier;

	SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));

	FAIL_IF(pthread_rwlockattr_setkind_np(&rwlock_attr,
					      PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP));
	FAIL_IF(pthread_rwlock_init(&rw_lock, &rwlock_attr));
	FAIL_IF(pthread_barrier_init(&barrier, NULL, THREADS));

	set_default_dscr(expected_system_dscr);

	for (int i = 0; i < THREADS; i++) {
		threads[i].expected_system_dscr = &expected_system_dscr;
		threads[i].rw_lock = &rw_lock;
		threads[i].barrier = &barrier;

		FAIL_IF(pthread_create(&threads[i].thread_id, NULL,
				       dscr_default_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));
	FAIL_IF(pthread_rwlock_destroy(&rw_lock));

	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();

Annotation

Implementation Notes