mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
Make the TSC architecture-agnostic and adjust CMakeLists
- Add a separate section for architecture-agnostic timing using CLOCK MONOTONIC (Linux specific) - Add a specific variant for the initialization of the TSC structure - Move the file to the linux-only section in the CMakeLists file Signed-off-by: Leonardo Carreras <leonardo.carreras@eonerc.rwth-aachen.de>
This commit is contained in:
parent
e2b090b270
commit
5c2fe58a3e
3 changed files with 45 additions and 16 deletions
|
@ -1,4 +1,4 @@
|
|||
/* Measure time and sleep with IA-32 time-stamp counter.
|
||||
/* Measure time and sleep with IA-32 time-stamp counter (x86) or a generic cycle-based timing.
|
||||
*
|
||||
* Author: Steffen Vogel <post@steffenvogel.de>
|
||||
* SPDX-FileCopyrightText: 2014-2023 Institute for Automation of Complex Power Systems, RWTH Aachen University
|
||||
|
@ -7,11 +7,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#if !(__x86_64__ || __i386__)
|
||||
#error this header is for x86 only
|
||||
#endif
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
|
||||
#include <cpuid.h>
|
||||
#include <x86intrin.h>
|
||||
|
||||
|
@ -24,17 +23,41 @@
|
|||
#define bit_TSC_INVARIANT (1 << 8)
|
||||
#define bit_RDTSCP (1 << 27)
|
||||
|
||||
#else
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifndef NSEC_PER_SEC
|
||||
#define NSEC_PER_SEC 1000000000L
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_RAW
|
||||
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC // Fallback for macOS/BSD
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
struct Tsc {
|
||||
uint64_t frequency;
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
bool rdtscp_supported;
|
||||
bool is_invariant;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
__attribute__((unused)) static uint64_t tsc_now(struct Tsc *t) {
|
||||
uint32_t tsc_aux;
|
||||
return t->rdtscp_supported ? __rdtscp(&tsc_aux) : __rdtsc();
|
||||
}
|
||||
#else
|
||||
// Fallback for CLOCK_MONOTONIC_RAW (linux/BSD/mac specific)
|
||||
__attribute__((unused)) static uint64_t tsc_now(struct Tsc *t) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||
return (ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec) * t->frequency / NSEC_PER_SEC;
|
||||
}
|
||||
#endif
|
||||
|
||||
int tsc_init(struct Tsc *t) __attribute__((warn_unused_result));
|
||||
|
||||
|
|
|
@ -33,10 +33,6 @@ add_library(villas-common SHARED
|
|||
version.cpp
|
||||
)
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
||||
target_sources(villas-common PRIVATE tsc.cpp)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Linux)
|
||||
target_sources(villas-common PRIVATE
|
||||
kernel/devices/ip_device.cpp
|
||||
|
@ -46,6 +42,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL Linux)
|
|||
kernel/vfio_device.cpp
|
||||
kernel/vfio_group.cpp
|
||||
kernel/vfio_container.cpp
|
||||
tsc.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
#include <villas/tsc.hpp>
|
||||
|
||||
using namespace villas;
|
||||
|
||||
int tsc_init(struct Tsc *t) {
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
|
||||
|
||||
// Check if TSC is supported
|
||||
|
@ -32,15 +31,25 @@ int tsc_init(struct Tsc *t) {
|
|||
if (ecx != 0)
|
||||
t->frequency = ecx * ebx / eax;
|
||||
else {
|
||||
int ret;
|
||||
#ifdef __linux__
|
||||
ret = kernel::get_cpu_frequency(&t->frequency);
|
||||
int ret = kernel::get_cpu_frequency(&t->frequency);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
#elif defined(__aarch64__)
|
||||
// Read counter frequency from system register
|
||||
uint64_t cntfrq;
|
||||
asm volatile("mrs %0, cntfrq_el0" : "=r"(cntfrq));
|
||||
t->frequency = cntfrq;
|
||||
#else
|
||||
#ifdef __linux__
|
||||
int ret = kernel::get_cpu_frequency(&t->frequency);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
#endif
|
||||
return (int)(t->frequency);
|
||||
}
|
||||
|
||||
uint64_t tsc_rate_to_cycles(struct Tsc *t, double rate) {
|
||||
|
|
Loading…
Add table
Reference in a new issue