tools/testing/selftests/rseq/slice_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/rseq/slice_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/rseq/slice_test.c
Extension
.c
Size
5035 bytes
Lines
222
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 noise_params {
	int64_t	noise_nsecs;
	int64_t	sleep_nsecs;
	int64_t	run;
};

FIXTURE(slice_ext)
{
	pthread_t		noise_thread;
	struct noise_params	noise_params;
};

FIXTURE_VARIANT(slice_ext)
{
	int64_t	total_nsecs;
	int64_t	slice_nsecs;
	int64_t	noise_nsecs;
	int64_t	sleep_nsecs;
	bool	no_yield;
};

FIXTURE_VARIANT_ADD(slice_ext, n2_2_50)
{
	.total_nsecs	=  5LL * NSEC_PER_SEC,
	.slice_nsecs	=  2LL * NSEC_PER_USEC,
	.noise_nsecs    =  2LL * NSEC_PER_USEC,
	.sleep_nsecs	= 50LL * NSEC_PER_USEC,
};

FIXTURE_VARIANT_ADD(slice_ext, n50_2_50)
{
	.total_nsecs	=  5LL * NSEC_PER_SEC,
	.slice_nsecs	= 50LL * NSEC_PER_USEC,
	.noise_nsecs    =  2LL * NSEC_PER_USEC,
	.sleep_nsecs	= 50LL * NSEC_PER_USEC,
};

FIXTURE_VARIANT_ADD(slice_ext, n2_2_50_no_yield)
{
	.total_nsecs	=  5LL * NSEC_PER_SEC,
	.slice_nsecs	=  2LL * NSEC_PER_USEC,
	.noise_nsecs    =  2LL * NSEC_PER_USEC,
	.sleep_nsecs	= 50LL * NSEC_PER_USEC,
	.no_yield	= true,
};


static inline bool elapsed(struct timespec *start, struct timespec *now,
			   int64_t span)
{
	int64_t delta = now->tv_sec - start->tv_sec;

	delta *= NSEC_PER_SEC;
	delta += now->tv_nsec - start->tv_nsec;
	return delta >= span;
}

static void *noise_thread(void *arg)
{
	struct noise_params *p = arg;

	while (RSEQ_READ_ONCE(p->run)) {
		struct timespec ts_start, ts_now;

		clock_gettime(CLOCK_MONOTONIC, &ts_start);
		do {
			clock_gettime(CLOCK_MONOTONIC, &ts_now);
		} while (!elapsed(&ts_start, &ts_now, p->noise_nsecs));

		ts_start.tv_sec = 0;
		ts_start.tv_nsec = p->sleep_nsecs;
		clock_nanosleep(CLOCK_MONOTONIC, 0, &ts_start, NULL);
	}
	return NULL;
}

FIXTURE_SETUP(slice_ext)
{
	cpu_set_t affinity;

	if (__rseq_register_current_thread(true, false))
		SKIP(return, "RSEQ not supported\n");

	if (prctl(PR_RSEQ_SLICE_EXTENSION, PR_RSEQ_SLICE_EXTENSION_SET,
		  PR_RSEQ_SLICE_EXT_ENABLE, 0, 0))
		SKIP(return, "Time slice extension not supported\n");

	ASSERT_EQ(sched_getaffinity(0, sizeof(affinity), &affinity), 0);

	/* Pin it on a single CPU. Avoid CPU 0 */

Annotation

Implementation Notes