1
1

Improved support for OSX timers.

Этот коммит содержится в:
George Bosilca 2014-11-24 17:15:49 -05:00
родитель b7fa0e312f
Коммит 261684858f
2 изменённых файлов: 57 добавлений и 46 удалений

Просмотреть файл

@ -27,17 +27,29 @@ typedef uint64_t opal_timer_t;
/* frequency in mhz */
OPAL_DECLSPEC extern opal_timer_t opal_timer_darwin_freq;
OPAL_DECLSPEC extern mach_timebase_info_data_t opal_timer_darwin_info;
OPAL_DECLSPEC extern opal_timer_t opal_timer_darwin_bias;
/**
* Use the pragmatic solution proposed at
* http://stackoverflow.com/questions/23378063/how-can-i-use-mach-absolute-time-without-overflowing/23378064#23378064
*/
static inline opal_timer_t
opal_timer_base_get_cycles(void)
{
uint64_t now = mach_absolute_time();
if( opal_timer_darwin_info.denom == 0 ) {
(void)mach_timebase_info(&opal_timer_darwin_info);
if( opal_timer_darwin_info.denom > 1024 ) {
double frac = (double)opal_timer_darwin_info.numer/opal_timer_darwin_info.denom;
opal_timer_darwin_info.denom = 1024;
opal_timer_darwin_info.numer = opal_timer_darwin_info.denom * frac + 0.5;
}
/* this is basically a wrapper around the "right" assembly to get
the tick counter off the PowerPC Time Base. I believe it's
something similar on x86 */
return mach_absolute_time() * opal_timer_darwin_info.numer / opal_timer_darwin_info.denom / 1000;
opal_timer_darwin_bias = now;
}
/* this is basically a wrapper around the "right" assembly to convert
the tick counter off the PowerPC Time Base into nanos. */
return (now - opal_timer_darwin_bias) * opal_timer_darwin_info.numer / opal_timer_darwin_info.denom;
}
@ -45,7 +57,7 @@ static inline opal_timer_t
opal_timer_base_get_usec(void)
{
/* freq is in Hz, so this gives usec */
return mach_absolute_time() * 1000000 / opal_timer_darwin_freq;
return opal_timer_base_get_cycles() / 1000;
}

Просмотреть файл

@ -26,6 +26,7 @@
opal_timer_t opal_timer_darwin_freq;
mach_timebase_info_data_t opal_timer_darwin_info = {.denom = 0};
opal_timer_t opal_timer_darwin_bias;
static int opal_timer_darwin_open(void);
@ -51,13 +52,6 @@ const opal_timer_base_component_2_0_0_t mca_timer_darwin_component = {
},
};
int opal_timer_darwin_open(void)
{
mach_timebase_info_data_t sTBI;
mach_timebase_info(&sTBI);
/* mach_timebase_info() returns a fraction that can be multiplied
by the difference between two calls to mach_absolute_time() to
get the number of nanoseconds that passed between the two
@ -94,7 +88,12 @@ int opal_timer_darwin_open(void)
1000000000 will give you a frequency in cycles / second if you
think of mach_absolute_time() always returning a cycle count.
*/
opal_timer_darwin_freq = sTBI.denom * (1000000000 / sTBI.numer);
int opal_timer_darwin_open(void)
{
/* Call the opal_timer_base_get_cycles once to start the enging */
(void)opal_timer_base_get_cycles();
opal_timer_darwin_freq = opal_timer_darwin_info.denom * (1000000000 / opal_timer_darwin_info.numer);
return OPAL_SUCCESS;
}