tools/testing/selftests/futex/functional/futex_priv_hash.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/futex/functional/futex_priv_hash.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/futex/functional/futex_priv_hash.c
Extension
.c
Size
7312 bytes
Lines
271
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 (futex_slotsn < 0 || futex_slots1 == futex_slotsn) {
			retry--;
			/*
			 * Auto scaling on thread creation can be slightly delayed
			 * because it waits for a RCU grace period twice. The new
			 * private hash is assigned upon the first futex operation
			 * after grace period.
			 * To cover all this for testing purposes the function
			 * below will acquire a lock and acquire it again with a
			 * 100ms timeout which must timeout. This ensures we
			 * sleep for 100ms and issue a futex operation.
			 */
			if (retry > 0) {
				futex_dummy_op();
				goto retry_getslots;
			}
			ksft_print_msg("Expected increase of hash buckets but got: %d -> %d\n",
				       futex_slots1, futex_slotsn);
			ksft_exit_fail_msg("%s", test_msg_auto_inc);
		}
		ksft_test_result_pass("%s", test_msg_auto_inc);
	} else {
		ksft_test_result_skip("%s", test_msg_auto_inc);
	}
	ret = pthread_mutex_unlock(&global_lock);

	/* Once the user changes it, it has to be what is set */
	futex_hash_slots_set_verify(2);
	futex_hash_slots_set_verify(4);
	futex_hash_slots_set_verify(8);
	futex_hash_slots_set_verify(32);
	futex_hash_slots_set_verify(16);

	ret = futex_hash_slots_set(15);
	ksft_test_result(ret < 0, "Use 15 slots\n");

	futex_hash_slots_set_verify(2);
	join_max_threads();
	ksft_test_result(counter == MAX_THREADS, "Created and waited for %d of %d threads\n",
			 counter, MAX_THREADS);
	counter = 0;
	/* Once the user set something, auto resize must be disabled */
	ret = pthread_barrier_init(&barrier_main, NULL, MAX_THREADS);

	create_max_threads(thread_lock_fn);
	join_max_threads();

	ret = futex_hash_slots_get();
	ksft_test_result(ret == 2, "No more auto-resize after manual setting, got %d\n",
			 ret);

	futex_hash_slots_set_must_fail(1 << 29);
	futex_hash_slots_set_verify(4);

	/*
	 * Once the global hash has been requested, then this requested can not
	 * be undone.
	 */
	ret = futex_hash_slots_set(0);
	ksft_test_result(ret == 0, "Global hash request\n");
	if (ret != 0)
		return;

	futex_hash_slots_set_must_fail(4);
	futex_hash_slots_set_must_fail(8);
	futex_hash_slots_set_must_fail(8);
	futex_hash_slots_set_must_fail(0);
	futex_hash_slots_set_must_fail(6);

	ret = pthread_barrier_init(&barrier_main, NULL, MAX_THREADS);
	if (ret != 0)
		ksft_exit_fail_msg("pthread_barrier_init failed: %m\n");

	create_max_threads(thread_lock_fn);
	join_max_threads();

	ret = futex_hash_slots_get();
	ksft_test_result(ret == 0, "Continue to use global hash\n");
}

TEST_HARNESS_MAIN

Annotation

Implementation Notes