After reading this thread I started testing the code for clock_gettime against c++11's chrono and they don't seem to match.
There is a huge gap between them!
The std::chrono::seconds(1) seems to be equivalent to ~70,000 of the clock_gettime
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <thread>
#include <chrono>
#include <iomanip>
#include <vector>
#include <mutex>
timespec diff(timespec start, timespec end);
timespec get_cpu_now_time();
std::vector<timespec> get_start_end_pairs();
std::vector<timespec> get_start_end_pairs2();
void output_deltas(const std::vector<timespec> &start_end_pairs);
//=============================================================
int main()
{
std::cout << "Hello waiter" << std::endl; // flush is intentional
std::vector<timespec> start_end_pairs = get_start_end_pairs2();
output_deltas(start_end_pairs);
return EXIT_SUCCESS;
}
//=============================================================
std::vector<timespec> get_start_end_pairs()
{
std::vector<timespec> start_end_pairs;
for (int i = 0; i < 20; ++i)
{
start_end_pairs.push_back(get_cpu_now_time());
std::this_thread::sleep_for(std::chrono::seconds(1));
start_end_pairs.push_back(get_cpu_now_time());
}
return start_end_pairs;
}
//=============================================================
std::vector<timespec> get_start_end_pairs2()
{
std::mutex mu;
std::vector<std::thread> workers;
std::vector<timespec> start_end_pairs;
for (int i = 0; i < 20; ++i) {
workers.emplace_back([&]()->void {
auto start_time = get_cpu_now_time();
std::this_thread::sleep_for(std::chrono::seconds(1));
auto end_time = get_cpu_now_time();
std::lock_guard<std::mutex> locker(mu);
start_end_pairs.emplace_back(start_time);
start_end_pairs.emplace_back(end_time);
});
}
for (auto &worker: workers) {
if (worker.joinable()) {
worker.join();
}
}
return start_end_pairs;
}
//=============================================================
void output_deltas(const std::vector<timespec> &start_end_pairs)
{
std::cout << "size: " << start_end_pairs.size() << std::endl;
for (auto it_start = start_end_pairs.begin(); it_start < start_end_pairs.end(); it_start += 2)
{
auto it_end = it_start + 1;
auto delta = diff(*it_start, *it_end);
std::cout
<< std::setw(2)
<< std::setfill(' ')
<< std::distance(start_end_pairs.begin(), it_start) / 2
<< " Waited ("
<< delta.tv_sec
<< "\ts\t"
<< std::setw(9)
<< std::setfill('0')
<< delta.tv_nsec
<< "\tns)"
<< std::endl;
}
}
//=============================================================
timespec diff(timespec start, timespec end)
{
timespec temp;
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
if (temp.tv_nsec < 0) {
--temp.tv_sec;
temp.tv_nsec += 1000000000;
}
return temp;
}
//=============================================================
timespec get_cpu_now_time()
{
timespec now_time;
memset(&now_time, 0, sizeof(timespec));
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now_time);
return now_time;
}
output:
Hello waiter
0 Waited (0 s 000843254 ns)
1 Waited (0 s 000681141 ns)
2 Waited (0 s 000685119 ns)
3 Waited (0 s 000674252 ns)
4 Waited (0 s 000714877 ns)
5 Waited (0 s 000624202 ns)
6 Waited (0 s 000746091 ns)
7 Waited (0 s 000575267 ns)
8 Waited (0 s 000860157 ns)
9 Waited (0 s 000827479 ns)
10 Waited (0 s 000612959 ns)
11 Waited (0 s 000534818 ns)
12 Waited (0 s 000553728 ns)
13 Waited (0 s 000586501 ns)
14 Waited (0 s 000627116 ns)
15 Waited (0 s 000616725 ns)
16 Waited (0 s 000616507 ns)
17 Waited (0 s 000641251 ns)
18 Waited (0 s 000683380 ns)
19 Waited (0 s 000850205 ns)