blob: d57418959a5b450f862c0b998ef2ae8962632e8c [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include <gtest/gtest.h>
#include "butil/build_config.h"
#if defined(OS_LINUX)
#include <syscall.h> // SYS_clock_gettime
#include <unistd.h> // syscall
#endif
#include "butil/time.h"
#include "butil/macros.h"
#include "butil/logging.h"
namespace {
TEST(BaiduTimeTest, diff_between_gettimeofday_and_REALTIME) {
long t1 = butil::gettimeofday_us();
timespec time;
clock_gettime(CLOCK_REALTIME, &time);
long t2 = butil::timespec_to_microseconds(time);
LOG(INFO) << "t1=" << t1 << " t2=" << t2;
}
const char* clock_desc[] = {
"CLOCK_REALTIME", //0
"CLOCK_MONOTONIC", //1
"CLOCK_PROCESS_CPUTIME_ID", //2
"CLOCK_THREAD_CPUTIME_ID", //3
"CLOCK_MONOTONIC_RAW", //4
"CLOCK_REALTIME_COARSE", //5
"CLOCK_MONOTONIC_COARSE", //6
"CLOCK_BOOTTIME", //7
"CLOCK_REALTIME_ALARM", //8
"CLOCK_BOOTTIME_ALARM", //9
"CLOCK_SGI_CYCLE", //10
"CLOCK_TAI" //11
};
TEST(BaiduTimeTest, cost_of_timer) {
printf("sizeof(time_t)=%lu\n", sizeof(time_t));
butil::Timer t1, t2;
timespec ts;
const size_t N = 200000;
t1.start();
for (size_t i = 0; i < N; ++i) {
t2.stop();
}
t1.stop();
printf("Timer::stop() takes %" PRId64 "ns\n", t1.n_elapsed() / N);
t1.start();
for (size_t i = 0; i < N; ++i) {
clock();
}
t1.stop();
printf("clock() takes %" PRId64 "ns\n", t1.n_elapsed() / N);
long s = 0;
t1.start();
for (size_t i = 0; i < N; ++i) {
s += butil::cpuwide_time_ns();
}
t1.stop();
printf("cpuwide_time() takes %" PRId64 "ns\n", t1.n_elapsed() / N);
t1.start();
for (size_t i = 0; i < N; ++i) {
s += butil::gettimeofday_us();
}
t1.stop();
printf("gettimeofday_us takes %" PRId64 "ns\n", t1.n_elapsed() / N);
t1.start();
for (size_t i = 0; i < N; ++i) {
time(NULL);
}
t1.stop();
printf("time(NULL) takes %" PRId64 "ns\n", t1.n_elapsed() / N);
t1.start();
for (size_t i = 0; i < N; ++i) {
s += butil::monotonic_time_ns();
}
t1.stop();
printf("monotonic_time_ns takes %" PRId64 "ns s=%ld\n", t1.n_elapsed() / N, s);
for (size_t i = 0; i < arraysize(clock_desc); ++i) {
#if defined(OS_LINUX)
if (0 == syscall(SYS_clock_gettime, (clockid_t)i, &ts)) {
t1.start();
for (size_t j = 0; j < N; ++j) {
syscall(SYS_clock_gettime, (clockid_t)i, &ts);
}
t1.stop();
printf("sys clock_gettime(%s) takes %" PRId64 "ns\n",
clock_desc[i], t1.n_elapsed() / N);
}
#endif
if (0 == clock_gettime((clockid_t)i, &ts)) {
t1.start();
for (size_t j = 0; j < N; ++j) {
clock_gettime((clockid_t)i, &ts);
}
t1.stop();
printf("glibc clock_gettime(%s) takes %" PRId64 "ns\n",
clock_desc[i], t1.n_elapsed() / N);
}
}
}
TEST(BaiduTimeTest, timespec) {
timespec ts1 = { 0, -1 };
butil::timespec_normalize(&ts1);
ASSERT_EQ(999999999L, ts1.tv_nsec);
ASSERT_EQ(-1, ts1.tv_sec);
timespec ts2 = { 0, 1000000000L };
butil::timespec_normalize(&ts2);
ASSERT_EQ(0L, ts2.tv_nsec);
ASSERT_EQ(1L, ts2.tv_sec);
timespec ts3 = { 0, 999999999L };
butil::timespec_normalize(&ts3);
ASSERT_EQ(999999999L, ts3.tv_nsec);
ASSERT_EQ(0, ts3.tv_sec);
timespec ts4 = { 0, 1L };
butil::timespec_add(&ts4, ts3);
ASSERT_EQ(0, ts4.tv_nsec);
ASSERT_EQ(1L, ts4.tv_sec);
timespec ts5 = { 0, 999999999L };
butil::timespec_minus(&ts5, ts3);
ASSERT_EQ(0, ts5.tv_nsec);
ASSERT_EQ(0, ts5.tv_sec);
timespec ts6 = { 0, 999999998L };
butil::timespec_minus(&ts6, ts3);
ASSERT_EQ(999999999L, ts6.tv_nsec);
ASSERT_EQ(-1L, ts6.tv_sec);
timespec ts7 = butil::nanoseconds_from(ts3, 1L);
ASSERT_EQ(0, ts7.tv_nsec);
ASSERT_EQ(1L, ts7.tv_sec);
timespec ts8 = butil::nanoseconds_from(ts3, -1000000000L);
ASSERT_EQ(999999999L, ts8.tv_nsec);
ASSERT_EQ(-1L, ts8.tv_sec);
timespec ts9 = butil::microseconds_from(ts3, 1L);
ASSERT_EQ(999L, ts9.tv_nsec);
ASSERT_EQ(1L, ts9.tv_sec);
timespec ts10 = butil::microseconds_from(ts3, -1000000L);
ASSERT_EQ(999999999L, ts10.tv_nsec);
ASSERT_EQ(-1L, ts10.tv_sec);
timespec ts11 = butil::milliseconds_from(ts3, 1L);
ASSERT_EQ(999999L, ts11.tv_nsec);
ASSERT_EQ(1L, ts11.tv_sec);
timespec ts12 = butil::milliseconds_from(ts3, -1000L);
ASSERT_EQ(999999999L, ts12.tv_nsec);
ASSERT_EQ(-1L, ts12.tv_sec);
timespec ts13 = butil::seconds_from(ts3, 1L);
ASSERT_EQ(999999999L, ts13.tv_nsec);
ASSERT_EQ(1, ts13.tv_sec);
timespec ts14 = butil::seconds_from(ts3, -1L);
ASSERT_EQ(999999999L, ts14.tv_nsec);
ASSERT_EQ(-1L, ts14.tv_sec);
}
TEST(BaiduTimeTest, every_many_us) {
butil::EveryManyUS every_10ms(10000L);
size_t i = 0;
const long start_time = butil::gettimeofday_ms();
while (1) {
if (every_10ms) {
printf("enter this branch at %" PRId64 "ms\n",
butil::gettimeofday_ms() - start_time);
if (++i >= 10) {
break;
}
}
}
}
TEST(BaiduTimeTest, timer_auto_start) {
butil::Timer t(butil::Timer::STARTED);
usleep(100);
t.stop();
printf("Cost %" PRId64 "us\n", t.u_elapsed());
}
} // namespace