summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac4
-rw-r--r--lib/thread.c22
-rw-r--r--lib/thread.h4
3 files changed, 27 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 9ba95fe98..0ea209bbf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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()])
])
diff --git a/lib/thread.c b/lib/thread.c
index dd5c1fed4..835aa3811 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -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
}
/*
diff --git a/lib/thread.h b/lib/thread.h
index 737ed005c..abd94ff4f 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -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