/* * SPDX-FileCopyrightText: 2025 Eilertsens Kodeknekkeri * SPDX-FileCopyrightText: 2025 The FreeBSD Foundation * SPDX-FileContributor: Harald Eilertsen * * SPDX-License-Identifier: BSD-2-Clause */ #include "helpers.hpp" #include "fast_cpu_time.hpp" #include "procstat_cpu_time.hpp" #include "sysctl_cpu_time.hpp" #include #include #include #include #include #include pid_t ktid; // Kernel thread id, /* * A simple thread. * * As we're only interested in observing the thread from another thread, it's * not important what it does, only that it stays around for long enough that * we can make our observations. */ void * thread_start(void * arg) { // Get the kernel thread id for the thread and save it // so it's accessible to the main thread. ktid = pthread_getthreadid_np(); for (auto i = 0; i < 5; ++i) { sleep(1); std::cout << "."; } /* * We can use getrusage(2) to quickly obtain the running time for * the current thread. This does not seem to be exposed for other * threads. */ auto ru = new struct rusage{}; getrusage(RUSAGE_THREAD, ru); std::cout << " done!" << std::endl; return ru; } int main(int argc, char * argv[]) { std::cout << "Hello Victims!" << std::endl; pthread_t thread; auto res = pthread_create(&thread, nullptr, thread_start, nullptr); assert(res == 0); #ifndef NDEBUG std::cout << "[*] thread = " << thread << ", " << "kernel tid = " << ktid << std::endl; #endif sleep(2); auto fast_time = fast_thread_cpu_time(thread); struct timeval procstat_user_time; struct timeval procstat_sys_time; procstat_cpu_time(thread, &procstat_user_time, &procstat_sys_time); struct timeval sysctl_user_time; struct timeval sysctl_sys_time; sysctl_cpu_time(thread, &sysctl_user_time, &sysctl_sys_time); void * thread_res; auto join_res = pthread_join(thread, &thread_res); assert(join_res == 0); std::cout << "Fast time: " << fast_time << "\n"; std::cout << "Procstat:" << " User time: " << timeval_to_long(procstat_user_time) << ", " << " Sys time : " << timeval_to_long(procstat_sys_time) << "\n"; std::cout << "Sysctl :" << " User time: " << timeval_to_long(sysctl_user_time) << ", " << " Sys time : " << timeval_to_long(sysctl_sys_time) << "\n"; auto ru = reinterpret_cast(thread_res); std::cout << "Rusage :" << " User time: " << timeval_to_long(ru->ru_utime) << ", " << " Sys time : " << timeval_to_long(ru->ru_stime) << "\n"; }