Skip to content

Commit 00300f4

Browse files
bosilcajsquyres
authored andcommitted
Add support for clock_gettime on Linux. Allow the user to
request a monotonic timer via MCA parameters.
1 parent 7e41e0e commit 00300f4

File tree

9 files changed

+136
-33
lines changed

9 files changed

+136
-33
lines changed

configure.ac

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,9 @@ OPAL_SEARCH_LIBS_CORE([dirname], [gen])
867867
# Darwin doesn't need -lm, as it's a symlink to libSystem.dylib
868868
OPAL_SEARCH_LIBS_CORE([ceil], [m])
869869

870+
# -lrt might be needed for clock_gettime
871+
OPAL_SEARCH_LIBS_CORE([clock_gettime], [rt])
872+
870873
AC_CHECK_FUNCS([asprintf snprintf vasprintf vsnprintf openpty isatty getpwuid fork waitpid execve pipe ptsname setsid mmap tcgetpgrp posix_memalign strsignal sysconf syslog vsyslog regcmp regexec regfree _NSGetEnviron socketpair strncpy_s usleep mkfifo dbopen dbm_open statfs statvfs setpgid setenv])
871874

872875
# Sanity check: ensure that we got at least one of statfs or statvfs.

opal/include/opal/sys/amd64/timer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222

2323
typedef uint64_t opal_timer_t;
2424

25+
/* Using RDTSC(P) results in non-monotonic timers across cores */
26+
#undef OPAL_TIMER_MONOTONIC
27+
#define OPAL_TIMER_MONOTONIC 0
2528

2629
#if OPAL_GCC_INLINE_ASSEMBLY
2730

opal/include/opal/sys/timer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@
7070
*
7171
*********************************************************************/
7272

73+
/* By default we suppose all timers are monotonic per node. */
74+
#define OPAL_TIMER_MONOTONIC 1
75+
7376
BEGIN_C_DECLS
7477

7578
/* If you update this list, you probably also want to update

opal/mca/timer/base/base.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ BEGIN_C_DECLS
3535
* Framework structure declaration
3636
*/
3737
OPAL_DECLSPEC extern mca_base_framework_t opal_timer_base_framework;
38-
38+
39+
/**
40+
* MCA param to force monotonic timers.
41+
*/
42+
OPAL_DECLSPEC extern int mca_timer_base_monotonic;
43+
3944
END_C_DECLS
4045

4146
/* include implementation to call */

opal/mca/timer/base/timer_base_open.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "opal/constants.h"
2323
#include "opal/mca/timer/base/base.h"
2424

25+
int mca_timer_base_monotonic = 1;
2526

2627
/*
2728
* The following file was created by configure. It contains extern
@@ -30,9 +31,23 @@
3031
*/
3132
#include "opal/mca/timer/base/static-components.h"
3233

34+
static int mca_timer_base_register(mca_base_register_flag_t flags)
35+
{
36+
/* figure out which bcol and sbgp components will actually be used */
37+
/* get list of sub-grouping functions to use */
38+
(void) mca_base_var_register("opal", "timer", "require", "monotonic",
39+
"Node-level monotonic timer required (default yes)",
40+
MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
41+
OPAL_INFO_LVL_9,
42+
MCA_BASE_VAR_SCOPE_LOCAL,
43+
&mca_timer_base_monotonic);
44+
45+
return OPAL_SUCCESS;
46+
}
47+
3348
/*
3449
* Globals
3550
*/
3651
/* Use default register/open/close functions */
37-
MCA_BASE_FRAMEWORK_DECLARE(opal, timer, NULL, NULL, NULL, NULL,
52+
MCA_BASE_FRAMEWORK_DECLARE(opal, timer, "OPAL OS timer", mca_timer_base_register, NULL, NULL,
3853
mca_timer_base_static_components, 0);

opal/mca/timer/linux/Makefile.am

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
33
# University Research and Technology
44
# Corporation. All rights reserved.
5-
# Copyright (c) 2004-2005 The University of Tennessee and The University
5+
# Copyright (c) 2004-2014 The University of Tennessee and The University
66
# of Tennessee Research Foundation. All rights
77
# reserved.
88
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
@@ -17,6 +17,8 @@
1717
# $HEADER$
1818
#
1919

20+
dist_opaldata_DATA = help-opal-timer-linux.txt
21+
2022
noinst_LTLIBRARIES = libmca_timer_linux.la
2123

2224
libmca_timer_linux_la_SOURCES = \
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# -*- text -*-
2+
#
3+
# Copyright (c) 2014 The University of Tennessee and The University
4+
# of Tennessee Research Foundation. All rights
5+
# reserved.
6+
# $COPYRIGHT$
7+
#
8+
# Additional copyrights may follow
9+
#
10+
# $HEADER$
11+
#
12+
# This is the US/English help file for Open MPI's Linux timer support.
13+
#
14+
[monotonic not supported]
15+
A monotonic timer has been requested by the user, but could not be found on the
16+
system. Falling back to a non-monotonic timer (such as RDTSC).
17+

opal/mca/timer/linux/timer_linux.h

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,35 +24,10 @@
2424

2525
OPAL_DECLSPEC extern opal_timer_t opal_timer_linux_freq;
2626

27-
static inline opal_timer_t
28-
opal_timer_base_get_cycles(void)
29-
{
30-
#if OPAL_HAVE_SYS_TIMER_GET_CYCLES
31-
return opal_sys_timer_get_cycles();
32-
#else
33-
return 0;
34-
#endif
35-
}
36-
37-
38-
static inline opal_timer_t
39-
opal_timer_base_get_usec(void)
40-
{
41-
#if OPAL_HAVE_SYS_TIMER_GET_CYCLES
42-
/* freq is in Hz, so this gives usec */
43-
return opal_sys_timer_get_cycles() * 1000000 / opal_timer_linux_freq;
44-
#else
45-
return 0;
46-
#endif
47-
}
48-
49-
50-
static inline opal_timer_t
51-
opal_timer_base_get_freq(void)
52-
{
53-
return opal_timer_linux_freq;
54-
}
27+
OPAL_DECLSPEC extern opal_timer_t *opal_timer_base_get_cycles(void);
28+
OPAL_DECLSPEC extern opal_timer_t *opal_timer_base_get_usec(void);
5529

30+
OPAL_DECLSPEC extern opal_timer_t opal_timer_base_get_freq(void);
5631

5732
#define OPAL_TIMER_CYCLE_NATIVE OPAL_HAVE_SYS_TIMER_GET_CYCLES
5833
#define OPAL_TIMER_CYCLE_SUPPORTED OPAL_HAVE_SYS_TIMER_GET_CYCLES

opal/mca/timer/linux/timer_linux_component.c

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,19 @@
2626
#include "opal/mca/timer/linux/timer_linux.h"
2727
#include "opal/constants.h"
2828

29+
static opal_timer_t opal_timer_base_get_cycles_sys_timer(void);
30+
static opal_timer_t opal_timer_base_get_usec_sys_timer(void);
31+
32+
#if OPAL_HAVE_CLOCK_GETTIME
33+
static opal_timer_t opal_timer_base_get_cycles_clock_gettime(void);
34+
static opal_timer_t opal_timer_base_get_usec_clock_gettime(void);
35+
opal_timer_t *opal_timer_base_get_cycles = opal_timer_base_get_cycles_clock_gettime;
36+
opal_timer_t *opal_timer_base_get_usec = opal_timer_base_get_usec_clock_gettime;
37+
#else
38+
opal_timer_t *opal_timer_base_get_cycles = opal_timer_base_get_cycles_sys_timer;
39+
opal_timer_t *opal_timer_base_get_usec = opal_timer_base_get_usec_sys_timer;
40+
#endif /* OPAL_HAVE_CLOCK_GETTIME */
41+
2942
opal_timer_t opal_timer_linux_freq;
3043

3144
static int opal_timer_linux_open(void);
@@ -73,8 +86,7 @@ find_info(FILE* fp, char *str, char *buf, size_t buflen)
7386
return NULL;
7487
}
7588

76-
int
77-
opal_timer_linux_open(void)
89+
static int opal_timer_linux_find_freq(void)
7890
{
7991
FILE *fp;
8092
char *loc;
@@ -130,3 +142,71 @@ opal_timer_linux_open(void)
130142

131143
return OPAL_SUCCESS;
132144
}
145+
146+
int opal_timer_linux_open(void)
147+
{
148+
int ret = OPAL_SUCCESS;
149+
#if !OPAL_HAVE_CLOCK_GETTIME
150+
ret = opal_timer_linux_find_freq();
151+
#endif
152+
153+
if(mca_timer_base_monotonic) {
154+
#if OPAL_HAVE_CLOCK_GETTIME
155+
struct timespec *res;
156+
if( 0 == clock_getres(CLOCK_MONOTONIC, &res)) {
157+
opal_timer_linux_freq = res.tv_nsec;
158+
return ret;
159+
}
160+
#else
161+
#if (0 == OPAL_TIMER_MONOTONIC)
162+
/* Monotonic time requested but cannot be found. Complain! */
163+
opal_show_help("help-opal-timer-linux.txt", "monotonic not supported", 1);
164+
#endif /* (0 == OPAL_TIMER_MONOTONIC) */
165+
#endif
166+
}
167+
return ret;
168+
}
169+
170+
#if OPAL_HAVE_CLOCK_GETTIME
171+
opal_timer_t opal_timer_base_get_usec_clock_gettime(void)
172+
{
173+
struct timespec *tp;
174+
175+
if( 0 == clock_gettime(CLOCK_MONOTONIC, &tp) ) {
176+
return (tp.tv_sec * 1e9 + tp.tv_nsec);
177+
}
178+
return 0;
179+
}
180+
181+
opal_timer_t opal_timer_base_get_cycles_clock_gettime(void)
182+
{
183+
return opal_timer_base_get_usec_clock_gettime() * opal_timer_linux_freq;
184+
}
185+
#endif /* OPAL_HAVE_CLOCK_GETTIME */
186+
187+
opal_timer_t opal_timer_base_get_cycles_sys_timer(void)
188+
{
189+
#if OPAL_HAVE_SYS_TIMER_GET_CYCLES
190+
return opal_sys_timer_get_cycles();
191+
#else
192+
return 0;
193+
#endif
194+
}
195+
196+
197+
opal_timer_t opal_timer_base_get_usec_sys_timer(void)
198+
{
199+
#if OPAL_HAVE_SYS_TIMER_GET_CYCLES
200+
/* freq is in Hz, so this gives usec */
201+
return opal_sys_timer_get_cycles() * 1000000 / opal_timer_linux_freq;
202+
#else
203+
return 0;
204+
#endif
205+
}
206+
207+
opal_timer_t opal_timer_base_get_freq(void)
208+
{
209+
return opal_timer_linux_freq;
210+
}
211+
212+

0 commit comments

Comments
 (0)