tools/testing/selftests/timers/freq-step.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/timers/freq-step.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/timers/freq-step.c
Extension
.c
Size
5956 bytes
Lines
264
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 sample {
	double offset;
	double time;
};

static time_t mono_raw_base;
static time_t mono_base;
static long user_hz;
static double precision;
static double mono_freq_offset;

static double diff_timespec(struct timespec *ts1, struct timespec *ts2)
{
	return ts1->tv_sec - ts2->tv_sec + (ts1->tv_nsec - ts2->tv_nsec) / 1e9;
}

static double get_sample(struct sample *sample)
{
	double delay, mindelay = 0.0;
	struct timespec ts1, ts2, ts3;
	int i;

	for (i = 0; i < SAMPLE_READINGS; i++) {
		clock_gettime(CLOCK_MONOTONIC_RAW, &ts1);
		clock_gettime(CLOCK_MONOTONIC, &ts2);
		clock_gettime(CLOCK_MONOTONIC_RAW, &ts3);

		ts1.tv_sec -= mono_raw_base;
		ts2.tv_sec -= mono_base;
		ts3.tv_sec -= mono_raw_base;

		delay = diff_timespec(&ts3, &ts1);
		if (delay <= 1e-9) {
			i--;
			continue;
		}

		if (!i || delay < mindelay) {
			sample->offset = diff_timespec(&ts2, &ts1);
			sample->offset -= delay / 2.0;
			sample->time = ts1.tv_sec + ts1.tv_nsec / 1e9;
			mindelay = delay;
		}
	}

	return mindelay;
}

static void reset_ntp_error(void)
{
	struct timex txc;

	txc.modes = ADJ_SETOFFSET;
	txc.time.tv_sec = 0;
	txc.time.tv_usec = 0;

	if (adjtimex(&txc) < 0) {
		perror("[FAIL] adjtimex");
		ksft_exit_fail();
	}
}

static void set_frequency(double freq)
{
	struct timex txc;
	int tick_offset;

	tick_offset = 1e6 * freq / user_hz;

	txc.modes = ADJ_TICK | ADJ_FREQUENCY;
	txc.tick = 1000000 / user_hz + tick_offset;
	txc.freq = (1e6 * freq - user_hz * tick_offset) * (1 << 16);

	if (adjtimex(&txc) < 0) {
		perror("[FAIL] adjtimex");
		ksft_exit_fail();
	}
}

static void regress(struct sample *samples, int n, double *intercept,
		    double *slope, double *r_stddev, double *r_max)
{
	double x, y, r, x_sum, y_sum, xy_sum, x2_sum, r2_sum;
	int i;

	x_sum = 0.0, y_sum = 0.0, xy_sum = 0.0, x2_sum = 0.0;

	for (i = 0; i < n; i++) {
		x = samples[i].time;
		y = samples[i].offset;

Annotation

Implementation Notes