From 20c1f68d41553d9ac80309e6334180a673d2e4c3 Mon Sep 17 00:00:00 2001 From: Kurt Wilson Date: Sat, 9 Nov 2024 14:32:52 -0500 Subject: [PATCH] add simple timer package needed to build --- src/simple_timer/CMakeLists.txt | 61 ++++++++++++ .../include/simple_timer/cycle_timer.hpp | 23 +++++ .../include/simple_timer/period_timer.hpp | 25 +++++ .../include/simple_timer/rt-sched.hpp | 98 +++++++++++++++++++ src/simple_timer/package.xml | 18 ++++ src/simple_timer/src/cycle_timer.cpp | 43 ++++++++ src/simple_timer/src/period_timer.cpp | 56 +++++++++++ src/simple_timer/src/rt-sched.cpp | 50 ++++++++++ 8 files changed, 374 insertions(+) create mode 100644 src/simple_timer/CMakeLists.txt create mode 100644 src/simple_timer/include/simple_timer/cycle_timer.hpp create mode 100644 src/simple_timer/include/simple_timer/period_timer.hpp create mode 100644 src/simple_timer/include/simple_timer/rt-sched.hpp create mode 100644 src/simple_timer/package.xml create mode 100644 src/simple_timer/src/cycle_timer.cpp create mode 100644 src/simple_timer/src/period_timer.cpp create mode 100644 src/simple_timer/src/rt-sched.cpp diff --git a/src/simple_timer/CMakeLists.txt b/src/simple_timer/CMakeLists.txt new file mode 100644 index 0000000..f0630d9 --- /dev/null +++ b/src/simple_timer/CMakeLists.txt @@ -0,0 +1,61 @@ +cmake_minimum_required(VERSION 3.5) +project(simple_timer) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +# uncomment the following section in order to fill in +# further dependencies manually. +# find_package( REQUIRED) + +add_library(simple_timer src/cycle_timer.cpp src/period_timer.cpp) +target_include_directories(simple_timer PUBLIC + $ + $ +) +add_library(rt-sched src/rt-sched.cpp) +target_include_directories(rt-sched PUBLIC + $ + $ +) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +install( + DIRECTORY include/ + DESTINATION include +) + +install( + TARGETS simple_timer rt-sched + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin +) + +ament_export_include_directories(include) +ament_export_libraries(simple_timer) +ament_export_libraries(rt-sched) +ament_package() diff --git a/src/simple_timer/include/simple_timer/cycle_timer.hpp b/src/simple_timer/include/simple_timer/cycle_timer.hpp new file mode 100644 index 0000000..556c8d4 --- /dev/null +++ b/src/simple_timer/include/simple_timer/cycle_timer.hpp @@ -0,0 +1,23 @@ +#ifndef __CYCLE_TIMER__ +#define __CYCLE_TIMER__ + +#include +#include "simple_timer/rt-sched.hpp" +namespace simple_timer +{ + class CycleTimer + { + public: + CycleTimer(long start_delay=0); + void tick() ; + const u64 start_delay_time; + u64 start_time = 0; + u64 last_cycle_time = 0; + unsigned long max_diff = 0; + unsigned long min_diff = 0; + unsigned long last_diff = 0; + bool recording = false; + }; +} // namespace simple_timer + +#endif \ No newline at end of file diff --git a/src/simple_timer/include/simple_timer/period_timer.hpp b/src/simple_timer/include/simple_timer/period_timer.hpp new file mode 100644 index 0000000..bdc909c --- /dev/null +++ b/src/simple_timer/include/simple_timer/period_timer.hpp @@ -0,0 +1,25 @@ +#ifndef __PERIOD_TIMER__ +#define __PERIOD_TIMER__ + +#include +#include "simple_timer/rt-sched.hpp" +namespace simple_timer +{ + class PeriodTimer + { + public: + PeriodTimer(long start_delay = 0); + void start(); + void stop(); + const u64 start_delay_time; + u64 start_time = 0; + + u64 last_period_time = 0; + unsigned long max_period = 0; + unsigned long min_period = 0; + unsigned long last_period = 0; + bool recording = false; + }; +} // namespace simple_timer + +#endif \ No newline at end of file diff --git a/src/simple_timer/include/simple_timer/rt-sched.hpp b/src/simple_timer/include/simple_timer/rt-sched.hpp new file mode 100644 index 0000000..4f035b2 --- /dev/null +++ b/src/simple_timer/include/simple_timer/rt-sched.hpp @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * rt-sched.h - sched_setattr() and sched_getattr() API + * (C) Dario Faggioli , 2009, 2010 + * Copyright (C) 2014 BMW Car IT GmbH, Daniel Wagner +#include +#include +#include +#include + +#ifndef SCHED_DEADLINE +#define SCHED_DEADLINE 6 +#endif + +#ifdef __x86_64__ +#define __NR_sched_setattr 314 +#define __NR_sched_getattr 315 +#endif + +#ifdef __i386__ +#define __NR_sched_setattr 351 +#define __NR_sched_getattr 352 +#endif + +#ifdef __arm__ +#ifndef __NR_sched_setattr +#define __NR_sched_setattr 380 +#endif +#ifndef __NR_sched_getattr +#define __NR_sched_getattr 381 +#endif +#endif + +#ifdef __tilegx__ +#define __NR_sched_setattr 274 +#define __NR_sched_getattr 275 +#endif + +typedef unsigned long long u64; +#define NS_TO_MS 1000000 +struct sched_attr { + uint32_t size; + uint32_t sched_policy; + uint64_t sched_flags; + + /* SCHED_NORMAL, SCHED_BATCH */ + int32_t sched_nice; + + /* SCHED_FIFO, SCHED_RR */ + uint32_t sched_priority; + + /* SCHED_DEADLINE */ + uint64_t sched_runtime; + uint64_t sched_deadline; + uint64_t sched_period; +}; + +int sched_setattr(pid_t pid, + const struct sched_attr *attr, + unsigned int flags); + +int sched_getattr(pid_t pid, + struct sched_attr *attr, + unsigned int size, + unsigned int flags); + +u64 get_time_us(void); + +typedef struct node_time_logger +{ + std::shared_ptr>> recorded_times; +} node_time_logger; + +void log_entry(node_time_logger logger, std::string text); +node_time_logger create_logger(); + +inline u64 get_time_us(void) +{ + struct timespec ts; + unsigned long long time; + + clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + time = ts.tv_sec * 1000000; + time += ts.tv_nsec / 1000; + + return time; +} + +#endif /* __RT_SCHED_H__ */ diff --git a/src/simple_timer/package.xml b/src/simple_timer/package.xml new file mode 100644 index 0000000..f009c67 --- /dev/null +++ b/src/simple_timer/package.xml @@ -0,0 +1,18 @@ + + + + simple_timer + 0.0.0 + TODO: Package description + nvidia + TODO: License declaration + + ament_cmake + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/src/simple_timer/src/cycle_timer.cpp b/src/simple_timer/src/cycle_timer.cpp new file mode 100644 index 0000000..143f13b --- /dev/null +++ b/src/simple_timer/src/cycle_timer.cpp @@ -0,0 +1,43 @@ +#include "simple_timer/cycle_timer.hpp" + +namespace simple_timer +{ + CycleTimer::CycleTimer(long start_delay) : start_delay_time(start_delay * 1000) + { + } + + void CycleTimer::tick() + { + u64 current_wall_time = get_time_us(); + u64 time_diff = 0; + + if (!recording) + { + + if (start_time == 0) + { + start_time = current_wall_time; + } + else if (current_wall_time - start_time > start_delay_time) + { + recording = true; + last_cycle_time = current_wall_time; + start_time = current_wall_time; + } + } + else + { + time_diff = current_wall_time - last_cycle_time; + if (time_diff < min_diff || min_diff == 0) + { + min_diff = time_diff; + } + if (time_diff > max_diff || max_diff == 0) + { + max_diff = time_diff; + } + last_cycle_time = current_wall_time; + last_diff = time_diff; + } + } +} // namespace simple_timer diff --git a/src/simple_timer/src/period_timer.cpp b/src/simple_timer/src/period_timer.cpp new file mode 100644 index 0000000..9c9a9ce --- /dev/null +++ b/src/simple_timer/src/period_timer.cpp @@ -0,0 +1,56 @@ + +#include "simple_timer/period_timer.hpp" + +namespace simple_timer +{ + PeriodTimer::PeriodTimer(long start_delay) : start_delay_time(start_delay * 1000) + { + } + + void PeriodTimer::start() + { + u64 current_wall_time = get_time_us(); + + if (!recording) + { + + if (start_time == 0) + { + start_time = current_wall_time; + } + else if (current_wall_time - start_time > start_delay_time) + { + recording = true; + start_time = current_wall_time; + last_period_time = current_wall_time; + } + } + else + { + last_period_time = current_wall_time; + } + } + void PeriodTimer::stop() + { + u64 current_wall_time = get_time_us(); + u64 time_diff = 0; + + if (!recording) + { + return; + } + else + { + time_diff = current_wall_time - last_period_time; + if (time_diff < min_period || min_period == 0) + { + min_period = time_diff; + } + if (time_diff > max_period || max_period == 0) + { + max_period = time_diff; + } + last_period = time_diff; + } + } +} // namespace simple_timer diff --git a/src/simple_timer/src/rt-sched.cpp b/src/simple_timer/src/rt-sched.cpp new file mode 100644 index 0000000..000c370 --- /dev/null +++ b/src/simple_timer/src/rt-sched.cpp @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * rt-sched.h - sched_setattr() and sched_getattr() API + * + * (C) Dario Faggioli , 2009, 2010 + * Copyright (C) 2014 BMW Car IT GmbH, Daniel Wagner +#include +#include +#include + +#include "simple_timer/rt-sched.hpp" + +int sched_setattr(pid_t pid, + const struct sched_attr *attr, + unsigned int flags) +{ + return syscall(__NR_sched_setattr, pid, attr, flags); +} + +int sched_getattr(pid_t pid, + struct sched_attr *attr, + unsigned int size, + unsigned int flags) +{ + return syscall(__NR_sched_getattr, pid, attr, size, flags); +} + +void log_entry(node_time_logger logger, std::string text) +{ + if (logger.recorded_times != nullptr) + { + logger.recorded_times->push_back(std::make_pair(text, get_time_us() / 1000)); + // std::cout<>>(); + return logger; +} \ No newline at end of file