LICENSES | ||
fast_cpu_time.cpp | ||
fast_cpu_time.hpp | ||
helpers.hpp | ||
main.cpp | ||
Makefile | ||
procstat_cpu_time.cpp | ||
procstat_cpu_time.hpp | ||
README.md | ||
sysctl_cpu_time.cpp | ||
sysctl_cpu_time.hpp |
Example: Getting run time of a thread in FreeBSD
I wrote this example app when researching how to find the run time of a specific thread. The OpenJDK garbage collector implementations as well as other parts of the OpenJDK needs this information. Since I had written it, I figured I might as well share it with the community. Perhaps some will find it useful.
The code demonstrated three ways of getting the run time of a thread other than the requesting thread, and one way of getting the run time of the current thread.
Getting run time via clock_gettime(2)
The system function clock_gettime(2)
will return a struct timespec
representing the current time of a given clock. We can obtain a clock that
holds the total run time of a thread by calling pthread_getcpuclockid(3)
.
This is the sum of the user and sys time of the given thread with nanosecond precision.
See fast_cpu_time.cpp for an example of using this method.
Getting run time via libprocstat(3)
Using the functions provided by libprocstat(3)
we can obtain the separate
user and sys times for a thread with microsecond precision. This involves first
opening a procstat handle (struct procstat *
) using
procstat_open_sysctl(3)
, querying the process info for all threads in the
process using procstat_getprocs(3)
, and the and iterating through the
returned array to find requested thread.
The call to procstat_getprocs(3)
will dynamically allocate the memory for the
returned array, which then has to be freed using procstat_freeprocs(3)
after
use. Finally the procstat handle must be freed using procstat_close(3)
.
In addition this method requires that we link with libprocstat(3)
.
The returned data is an array of struct kinfo_proc
structures, that contains
a field of type struct rusage
, which again contains a struct timeval
for
the threads user time and one for the system time. These have microsecond
precision.
To locate the requested thread we need the kernel thread id of the thread.
We can obtain this by calling pthread_getthreadid_np(3)
, but only from
the thread itself. To be able to use it from another thread, the thread id
must be saved somewhere accessible. In this example I just use a global
variable for illustration.
See procstat_cpu_time.cpp for an example using this method.
Getting run time via sysctl(3)
This is very similar to the libprocstat method above, but don't require linking with a library, and uses memory allocated by the caller rather than allocating it dynaically for you. This allows for using static preallocated memory if needed.
While the KERN_PROC_INC_THREAD
modifier flag for KERN_PROC_PID
is not
documented in the sysctl(3)
man page, it works the same as for the procstat
call.
See syscall_cpu_time.cpp for an example of using this method.
Getting run time vis getrusage(2)
This method is pretty straight forward, but will only get the run time for the calling thread. It has the same microsecond precision that both the libprocstat and sysctl methods above has.
It also avoids the need for dynamic allocation as the caller provides a buffer
of type struct rusage
that is filled with the data.
See the code for the thread itself in main.cpp for an example of using this method.
License
Copyright (c) 2025 The FreeBSD Foundation
Copyright (c) 2025 Eilertsens Kodeknekkeri
SPDX-License-Identifier: BSD-2-Clause
This code is shared under a BSD 2-Clause license. See the included license for details.