// SPDX-License-Identifier: GPL-2.0-only /* * Copyright 2006 Andi Kleen, SUSE Labs. * * Fast user context implementation of clock_gettime, gettimeofday, and time. * * The code should have no internal unresolved relocations. * Check with readelf after changing. * Also alternative() doesn't work.
*/ /* * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
*/
/* * Compute the vvar page's address in the process address space, and return it * as a pointer to the vvar_data.
*/
notrace static __always_inline struct vvar_data *get_vvar_data(void)
{ unsignedlong ret;
/* * vdso data page is the first vDSO page so grab the PC * and move up a page to get to the data page.
*/
__asm__("rd %%pc, %0" : "=r" (ret));
ret &= ~(8192 - 1);
ret -= 8192;
switch (clock) { case CLOCK_REALTIME: if (unlikely(vvd->vclock_mode == VCLOCK_NONE)) break; return do_realtime(vvd, ts); case CLOCK_MONOTONIC: if (unlikely(vvd->vclock_mode == VCLOCK_NONE)) break; return do_monotonic(vvd, ts); case CLOCK_REALTIME_COARSE: return do_realtime_coarse(vvd, ts); case CLOCK_MONOTONIC_COARSE: return do_monotonic_coarse(vvd, ts);
} /* * Unknown clock ID ? Fall back to the syscall.
*/ return vdso_fallback_gettime(clock, ts);
} int
clock_gettime(clockid_t, struct __kernel_old_timespec *)
__attribute__((weak, alias("__vdso_clock_gettime")));
switch (clock) { case CLOCK_REALTIME: if (unlikely(vvd->vclock_mode == VCLOCK_NONE)) break; return do_realtime_stick(vvd, ts); case CLOCK_MONOTONIC: if (unlikely(vvd->vclock_mode == VCLOCK_NONE)) break; return do_monotonic_stick(vvd, ts); case CLOCK_REALTIME_COARSE: return do_realtime_coarse(vvd, ts); case CLOCK_MONOTONIC_COARSE: return do_monotonic_coarse(vvd, ts);
} /* * Unknown clock ID ? Fall back to the syscall.
*/ return vdso_fallback_gettime(clock, ts);
}
if (likely(vvd->vclock_mode != VCLOCK_NONE)) { if (likely(tv != NULL)) { union tstv_t { struct __kernel_old_timespec ts; struct __kernel_old_timeval tv;
} *tstv = (union tstv_t *) tv;
do_realtime(vvd, &tstv->ts); /* * Assign before dividing to ensure that the division is * done in the type of tv_usec, not tv_nsec. * * There cannot be > 1 billion usec in a second: * do_realtime() has already distributed such overflow * into tv_sec. So we can assign it to an int safely.
*/
tstv->tv.tv_usec = tstv->ts.tv_nsec;
tstv->tv.tv_usec /= 1000;
} if (unlikely(tz != NULL)) { /* Avoid memcpy. Some old compilers fail to inline it */
tz->tz_minuteswest = vvd->tz_minuteswest;
tz->tz_dsttime = vvd->tz_dsttime;
} return 0;
} return vdso_fallback_gettimeofday(tv, tz);
} int
gettimeofday(struct __kernel_old_timeval *, struct timezone *)
__attribute__((weak, alias("__vdso_gettimeofday")));
if (likely(vvd->vclock_mode != VCLOCK_NONE)) { if (likely(tv != NULL)) { union tstv_t { struct __kernel_old_timespec ts; struct __kernel_old_timeval tv;
} *tstv = (union tstv_t *) tv;
do_realtime_stick(vvd, &tstv->ts); /* * Assign before dividing to ensure that the division is * done in the type of tv_usec, not tv_nsec. * * There cannot be > 1 billion usec in a second: * do_realtime() has already distributed such overflow * into tv_sec. So we can assign it to an int safely.
*/
tstv->tv.tv_usec = tstv->ts.tv_nsec;
tstv->tv.tv_usec /= 1000;
} if (unlikely(tz != NULL)) { /* Avoid memcpy. Some old compilers fail to inline it */
tz->tz_minuteswest = vvd->tz_minuteswest;
tz->tz_dsttime = vvd->tz_dsttime;
} return 0;
} return vdso_fallback_gettimeofday(tv, tz);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.25 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.