lib: try CLOCK_THREAD_CPUTIME_ID

This might be faster if at some point in the future the Linux vDSO
supports CLOCK_THREAD_CPUTIME_ID without making a syscall.  (Same
applies for other OSes.)

Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
David Lamparter 2021-04-13 20:49:26 +02:00 committed by David Lamparter
parent 45f0118832
commit 6418e2d342
3 changed files with 27 additions and 3 deletions

View file

@ -2229,6 +2229,10 @@ AC_CHECK_DECL([CLOCK_MONOTONIC],
AC_DEFINE([HAVE_CLOCK_MONOTONIC], [1], [Have monotonic clock])
], [AC_MSG_RESULT([no])], [FRR_INCLUDES])
AC_CHECK_DECL([CLOCK_THREAD_CPUTIME_ID], [
AC_DEFINE([HAVE_CLOCK_THREAD_CPUTIME_ID], [1], [Have cpu-time clock])
], [AC_MSG_RESULT([no])], [FRR_INCLUDES])
AC_SEARCH_LIBS([clock_nanosleep], [rt], [
AC_DEFINE([HAVE_CLOCK_NANOSLEEP], [1], [Have clock_nanosleep()])
])

View file

@ -1821,9 +1821,14 @@ static unsigned long timeval_elapsed(struct timeval a, struct timeval b)
unsigned long thread_consumed_time(RUSAGE_T *now, RUSAGE_T *start,
unsigned long *cputime)
{
#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
*cputime = (now->cpu.tv_sec - start->cpu.tv_sec) * TIMER_SECOND_MICRO
+ (now->cpu.tv_nsec - start->cpu.tv_nsec) / 1000;
#else
/* This is 'user + sys' time. */
*cputime = timeval_elapsed(now->cpu.ru_utime, start->cpu.ru_utime)
+ timeval_elapsed(now->cpu.ru_stime, start->cpu.ru_stime);
#endif
return timeval_elapsed(now->real, start->real);
}
@ -1856,14 +1861,25 @@ void thread_set_yield_time(struct thread *thread, unsigned long yield_time)
void thread_getrusage(RUSAGE_T *r)
{
monotime(&r->real);
if (!cputime_enabled) {
memset(&r->cpu, 0, sizeof(r->cpu));
return;
}
#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
/* not currently implemented in Linux's vDSO, but maybe at some point
* in the future?
*/
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &r->cpu);
#else /* !HAVE_CLOCK_THREAD_CPUTIME_ID */
#if defined RUSAGE_THREAD
#define FRR_RUSAGE RUSAGE_THREAD
#else
#define FRR_RUSAGE RUSAGE_SELF
#endif
monotime(&r->real);
if (cputime_enabled)
getrusage(FRR_RUSAGE, &(r->cpu));
getrusage(FRR_RUSAGE, &(r->cpu));
#endif
}
/*

View file

@ -41,7 +41,11 @@ extern unsigned long cputime_threshold;
extern unsigned long walltime_threshold;
struct rusage_t {
#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
struct timespec cpu;
#else
struct rusage cpu;
#endif
struct timeval real;
};
#define RUSAGE_T struct rusage_t