diff --git a/CMakeLists.txt b/CMakeLists.txt index 23b3432..c8d1e55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ target_compile_options(topo PRIVATE ${C_FLAGS} ${XML_CFLAGS}) target_include_directories(topo PRIVATE ${XML_INCLUDE_DIRS}) target_link_libraries(topo PRIVATE ${XML_LINK_LIBRARIES}) -add_executable(test test/topo.c) +add_executable(test test/test.c) set_target_properties(test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/test) target_link_libraries(test PRIVATE topo) target_compile_options(test PRIVATE ${C_FLAGS}) diff --git a/test/test.c b/test/test.c new file mode 100644 index 0000000..9ca3c39 --- /dev/null +++ b/test/test.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include + +#include "topo.h" + +#define S2NS (1000000000UL) + +static inline uint64_t +get_uptime() +{ + struct timespec tp; + clock_gettime(CLOCK_MONOTONIC, &tp); + return (tp.tv_sec * S2NS + tp.tv_nsec); +} + +void test(const char * case_name, struct timespec * ts) +{ + uint64_t slow; + uint64_t fast; + + slow = get_uptime(); + if (nanosleep(ts, NULL) != 0) { + perror("nanosleep() interrupted!"); + exit(-1); + } + slow = get_uptime() - slow; + + fast = topo_uptime_ns(); + if (nanosleep(ts, NULL) != 0) { + perror("nanosleep() interrupted!"); + exit(-1); + } + fast = topo_uptime_ns() - fast; + + printf("%s: clock_gettime(): %lu, topo_uptime_ns(): %lu, %% diff: %.2f%%\n", case_name, slow, fast, ((float)fast - (float)slow) / (float)slow * 100); +} + +int ts_test() +{ + struct timespec ts; + // 1s + ts.tv_nsec = 0; + ts.tv_sec = 1; + test("1s", &ts); + + // 100ms + ts.tv_nsec = 100000000; + ts.tv_sec = 0; + test("100ms", &ts); + + // 10ms + ts.tv_nsec = 10000000; + ts.tv_sec = 0; + test("10ms", &ts); + + // 1ms + ts.tv_nsec = 1000000; + ts.tv_sec = 0; + test("1ms", &ts); + + // 100us + ts.tv_nsec = 100000; + ts.tv_sec = 0; + test("100us", &ts); + + // 10us + ts.tv_nsec = 10000; + ts.tv_sec = 0; + test("10us", &ts); + + // 1us + ts.tv_nsec = 1000; + ts.tv_sec = 0; + test("1us", &ts); + + // 100ns + ts.tv_nsec = 100; + ts.tv_sec = 0; + test("100ns", &ts); + + // 10ns + ts.tv_nsec = 10; + ts.tv_sec = 0; + test("10ns", &ts); + + // 1ns + ts.tv_nsec = 1; + ts.tv_sec = 0; + test("1ns", &ts); + + return 0; +} + +int main() +{ + topo_init(1, 1); + ts_test(); + return 0; +} \ No newline at end of file diff --git a/test/topo.c b/test/topo.c deleted file mode 100644 index f51ae56..0000000 --- a/test/topo.c +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include "topo.h" - -int main() -{ - topo_init(1, 1); - return 0; -} \ No newline at end of file diff --git a/timestamp.c b/timestamp.c index 23b1710..e7ecdc5 100644 --- a/timestamp.c +++ b/timestamp.c @@ -1,6 +1,9 @@ #include #include #include +#include +#include + #include "topo.h" static uint64_t sysctl_tsc_freq = 0; @@ -14,6 +17,23 @@ tsc2ns(uint64_t tsc) (double)tsc / (double)sysctl_tsc_freq * S2NS); } +int +topo_ts_init(int verbose) +{ + int rc; + size_t sz = sizeof(sysctl_tsc_freq); + + // init nm_tsc2ns + if ((rc = sysctlbyname( + "machdep.tsc_freq", &sysctl_tsc_freq, &sz, NULL, 0)) < 0) { + if (verbose) { + fprintf(stderr, + "libnm: failed to query tsc frequency via sysctl (%d)\n", errno); + } + } + + return rc; +} uint64_t topo_uptime_ns() diff --git a/topo.c b/topo.c index eb89c78..6011445 100644 --- a/topo.c +++ b/topo.c @@ -386,6 +386,8 @@ _topo_init(int verbose, int alloc_init, struct topo_obj ** obj) } } + rc = topo_ts_init(verbose); + if (alloc_init && rc == 0) { rc = topo_alloc_init(verbose, *obj); }