2022-05-26 16:25:30 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <immintrin.h>
|
|
|
|
#include <x86intrin.h>
|
2022-05-26 16:36:03 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <sys/sysctl.h>
|
|
|
|
|
2022-05-26 16:25:30 +00:00
|
|
|
#include "topo.h"
|
2022-05-26 20:18:49 +00:00
|
|
|
#include "topop.h"
|
2022-05-26 16:25:30 +00:00
|
|
|
|
|
|
|
#define S2NS (1000000000UL)
|
|
|
|
|
|
|
|
static uint64_t
|
2022-05-26 20:18:49 +00:00
|
|
|
tsc2ns(uint64_t tsc, uint64_t tsc_freq)
|
2022-05-26 16:25:30 +00:00
|
|
|
{
|
|
|
|
return (uint64_t)(
|
2022-05-26 20:18:49 +00:00
|
|
|
(double)tsc / (double)tsc_freq * S2NS);
|
2022-05-26 16:25:30 +00:00
|
|
|
}
|
|
|
|
|
2022-05-26 16:36:03 +00:00
|
|
|
int
|
2022-05-26 20:18:49 +00:00
|
|
|
topo_ts_init(struct topo_desc * desc, int verbose)
|
2022-05-26 16:36:03 +00:00
|
|
|
{
|
|
|
|
int rc;
|
2022-05-26 20:18:49 +00:00
|
|
|
|
|
|
|
size_t sz = sizeof(desc->tsc_freq);
|
2022-05-26 16:36:03 +00:00
|
|
|
|
|
|
|
// init nm_tsc2ns
|
2022-05-26 20:18:49 +00:00
|
|
|
if ((rc = sysctlbyname("machdep.tsc_freq", &desc->tsc_freq, &sz, NULL, 0)) < 0) {
|
|
|
|
fprintf(stderr,"libtopo: failed to query tsc frequency via sysctl (%d)\n", errno);
|
|
|
|
} else {
|
2022-05-26 16:36:03 +00:00
|
|
|
if (verbose) {
|
2022-05-26 20:18:49 +00:00
|
|
|
fprintf(stdout,"libtopo: tsc frequency = %lu\n", desc->tsc_freq);
|
2022-05-26 16:36:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
2022-05-26 16:25:30 +00:00
|
|
|
|
|
|
|
uint64_t
|
2022-05-26 20:18:49 +00:00
|
|
|
topo_desc_uptime_ns(struct topo_desc * desc)
|
2022-05-26 16:25:30 +00:00
|
|
|
{
|
|
|
|
unsigned int dummy;
|
|
|
|
_mm_lfence();
|
|
|
|
uint64_t tsc = __rdtscp(&dummy);
|
|
|
|
_mm_lfence();
|
2022-05-26 20:18:49 +00:00
|
|
|
return tsc2ns(tsc, desc->tsc_freq);
|
2022-06-10 11:29:01 +00:00
|
|
|
}
|