lib/vdso/gettimeofday.c

Source file repositories/reference/linux-study-clean/lib/vdso/gettimeofday.c

File Facts

System
Linux kernel
Corpus path
lib/vdso/gettimeofday.c
Extension
.c
Size
11520 bytes
Lines
494
Domain
Kernel Services
Bucket
lib
Inferred role
Kernel Services: implementation source
Status
source implementation candidate

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

while (vdso_read_begin_timens(vc, &seq)) {
			/* Re-read from the real time data page, reload seq by looping */
			vd = vdso_timens_data(vd);
			vc = &vd->aux_clock_data[idx];
		}

		/* Auxclock disabled? */
		if (vc->clock_mode == VDSO_CLOCKMODE_NONE)
			return false;

		if (!vdso_get_timestamp(vd, vc, VDSO_BASE_AUX, &sec, &ns))
			return false;
	} while (vdso_read_retry(vc, seq));

	vdso_set_timespec(ts, sec, ns);

	return true;
}

static __always_inline bool
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
			     struct __kernel_timespec *ts)
{
	const struct vdso_clock *vc = vd->clock_data;
	u32 msk;

	if (!vdso_clockid_valid(clock))
		return false;

	/*
	 * Convert the clockid to a bitmask and use it to check which
	 * clocks are handled in the VDSO directly.
	 */
	msk = 1U << clock;
	if (likely(msk & VDSO_HRES))
		vc = &vc[CS_HRES_COARSE];
	else if (msk & VDSO_COARSE)
		return do_coarse(vd, &vc[CS_HRES_COARSE], clock, ts);
	else if (msk & VDSO_RAW)
		vc = &vc[CS_RAW];
	else if (msk & VDSO_AUX)
		return do_aux(vd, clock, ts);
	else
		return false;

	return do_hres(vd, vc, clock, ts);
}

static int
__cvdso_clock_gettime_data(const struct vdso_time_data *vd, clockid_t clock,
			   struct __kernel_timespec *ts)
{
	bool ok;

	ok = __cvdso_clock_gettime_common(vd, clock, ts);

	if (unlikely(!ok))
		return clock_gettime_fallback(clock, ts);
	return 0;
}

static __maybe_unused int
__cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
{
	return __cvdso_clock_gettime_data(__arch_get_vdso_u_time_data(), clock, ts);
}

#ifdef BUILD_VDSO32
static int
__cvdso_clock_gettime32_data(const struct vdso_time_data *vd, clockid_t clock,
			     struct old_timespec32 *res)
{
	struct __kernel_timespec ts;
	bool ok;

	ok = __cvdso_clock_gettime_common(vd, clock, &ts);

	if (unlikely(!ok))
		return clock_gettime32_fallback(clock, res);

	/* For ok == true */
	res->tv_sec = ts.tv_sec;
	res->tv_nsec = ts.tv_nsec;

	return 0;
}

static __maybe_unused int
__cvdso_clock_gettime32(clockid_t clock, struct old_timespec32 *res)
{

Annotation

Implementation Notes