A simple app to get run times from a thread
Just a quick app to test and demonstrate how to get run times from a specific thread on FreeBSD.
This commit is contained in:
commit
45e6aebfbf
10 changed files with 366 additions and 0 deletions
98
main.cpp
Normal file
98
main.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Eilertsens Kodeknekkeri
|
||||
* SPDX-FileCopyrightText: 2025 The FreeBSD Foundation
|
||||
* SPDX-FileContributor: Harald Eilertsen <haraldei@anduin.net>
|
||||
*
|
||||
* 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 <cassert>
|
||||
#include <iostream>
|
||||
#include <pthread.h>
|
||||
#include <pthread_np.h>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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<struct rusage *>(thread_res);
|
||||
|
||||
std::cout << "Rusage :"
|
||||
<< " User time: " << timeval_to_long(ru->ru_utime) << ", "
|
||||
<< " Sys time : " << timeval_to_long(ru->ru_stime) << "\n";
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue