src: Use std::chrono instead of gettimeofday and clock_gettime

This commit is contained in:
Tatsuhiro Tsujikawa 2013-09-16 17:36:24 +09:00
parent 04457aae62
commit 0a649e2499
3 changed files with 54 additions and 76 deletions

View File

@ -164,11 +164,10 @@ void print_nv(nghttp2_nv *nva, size_t nvlen)
void print_timer() void print_timer()
{ {
timeval tv; auto millis = get_timer();
get_timer(&tv);
printf("%s[%3ld.%03ld]%s", printf("%s[%3ld.%03ld]%s",
ansi_esc("\033[33m"), ansi_esc("\033[33m"),
(long int)tv.tv_sec, tv.tv_usec/1000, (long int)(millis.count()/1000), (long int)(millis.count()%1000),
ansi_escend()); ansi_escend());
} }
@ -438,45 +437,23 @@ int on_data_send_callback
return 0; return 0;
} }
int64_t time_delta(const timeval& a, const timeval& b)
{
int64_t res = (a.tv_sec - b.tv_sec) * 1000;
res += (a.tv_usec - b.tv_usec) / 1000;
return res;
}
namespace { namespace {
timeval base_tv; std::chrono::steady_clock::time_point base_tv;
} // namespace } // namespace
void reset_timer() void reset_timer()
{ {
get_time(&base_tv); base_tv = std::chrono::steady_clock::now();
} }
void get_timer(timeval* tv) std::chrono::milliseconds get_timer()
{ {
get_time(tv); return time_delta(std::chrono::steady_clock::now(), base_tv);
tv->tv_usec -= base_tv.tv_usec;
tv->tv_sec -= base_tv.tv_sec;
if(tv->tv_usec < 0) {
tv->tv_usec += 1000000;
--tv->tv_sec;
}
} }
int get_time(timeval *tv) std::chrono::steady_clock::time_point get_time()
{ {
int rv; return std::chrono::steady_clock::now();
#ifdef HAVE_CLOCK_GETTIME
timespec ts;
rv = clock_gettime(CLOCK_MONOTONIC, &ts);
tv->tv_sec = ts.tv_sec;
tv->tv_usec = ts.tv_nsec/1000;
#else // !HAVE_CLOCK_GETTIME
rv = gettimeofday(tv, 0);
#endif // !HAVE_CLOCK_GETTIME
return rv;
} }
} // namespace nghttp2 } // namespace nghttp2

View File

@ -31,7 +31,9 @@
#include <cstdlib> #include <cstdlib>
#include <sys/time.h> #include <sys/time.h>
#include <poll.h> #include <poll.h>
#include <map> #include <map>
#include <chrono>
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
@ -74,13 +76,20 @@ int on_data_send_callback
// Returns difference between |a| and |b| in milliseconds, assuming // Returns difference between |a| and |b| in milliseconds, assuming
// |a| is more recent than |b|. // |a| is more recent than |b|.
int64_t time_delta(const timeval& a, const timeval& b); template<typename TimePoint>
std::chrono::milliseconds time_delta(const TimePoint& a, const TimePoint& b)
{
return std::chrono::duration_cast<std::chrono::milliseconds>(a - b);
}
// Resets timer
void reset_timer(); void reset_timer();
void get_timer(timeval *tv); // Returns the duration since timer reset.
std::chrono::milliseconds get_timer();
int get_time(timeval *tv); // Returns current time point.
std::chrono::steady_clock::time_point get_time();
void print_timer(); void print_timer();

View File

@ -50,6 +50,7 @@
#include <vector> #include <vector>
#include <sstream> #include <sstream>
#include <tuple> #include <tuple>
#include <chrono>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
@ -111,28 +112,21 @@ struct Config {
}; };
} // namespace } // namespace
namespace { enum StatStage {
struct RequestStat { STAT_INITIAL,
timeval on_syn_stream_time; STAT_ON_REQUEST,
timeval on_syn_reply_time; STAT_ON_RESPONSE,
timeval on_complete_time; STAT_ON_COMPLETE
RequestStat()
{
on_syn_stream_time.tv_sec = -1;
on_syn_stream_time.tv_usec = -1;
on_syn_reply_time.tv_sec = -1;
on_syn_reply_time.tv_usec = -1;
on_complete_time.tv_sec = -1;
on_complete_time.tv_usec = -1;
}
}; };
} // namespace
namespace { namespace {
void record_time(timeval *tv) struct RequestStat {
{ std::chrono::steady_clock::time_point on_request_time;
get_time(tv); std::chrono::steady_clock::time_point on_response_time;
} std::chrono::steady_clock::time_point on_complete_time;
StatStage stage;
RequestStat():stage(STAT_INITIAL) {}
};
} // namespace } // namespace
namespace { namespace {
@ -318,31 +312,29 @@ struct Request {
} }
} }
void record_syn_stream_time() void record_request_time()
{ {
record_time(&stat.on_syn_stream_time); stat.stage = STAT_ON_REQUEST;
stat.on_request_time = get_time();
} }
void record_syn_reply_time() void record_response_time()
{ {
record_time(&stat.on_syn_reply_time); stat.stage = STAT_ON_RESPONSE;
stat.on_response_time = get_time();
} }
void record_complete_time() void record_complete_time()
{ {
record_time(&stat.on_complete_time); stat.stage = STAT_ON_COMPLETE;
stat.on_complete_time = get_time();
} }
}; };
} // namespace } // namespace
namespace { namespace {
struct SessionStat { struct SessionStat {
timeval on_handshake_time; std::chrono::steady_clock::time_point on_handshake_time;
SessionStat()
{
on_handshake_time.tv_sec = -1;
on_handshake_time.tv_usec = -1;
}
}; };
} // namespace } // namespace
@ -821,7 +813,7 @@ struct HttpClient {
} }
void record_handshake_time() void record_handshake_time()
{ {
record_time(&stat.on_handshake_time); stat.on_handshake_time = get_time();
} }
}; };
} // namespace } // namespace
@ -1026,7 +1018,7 @@ void check_stream_id(nghttp2_session *session, int32_t stream_id,
stream_id); stream_id);
assert(req); assert(req);
client->streams[stream_id] = req; client->streams[stream_id] = req;
req->record_syn_stream_time(); req->record_request_time();
} }
} // namespace } // namespace
@ -1101,7 +1093,7 @@ int on_frame_recv_callback2
// If this is the HTTP Upgrade with OPTIONS method to avoid POST, // If this is the HTTP Upgrade with OPTIONS method to avoid POST,
// req is nullptr. // req is nullptr.
if(req) { if(req) {
req->record_syn_reply_time(); req->record_response_time();
} }
} }
check_response_header(session, frame, user_data); check_response_header(session, frame, user_data);
@ -1141,23 +1133,23 @@ void print_stats(const HttpClient& client)
std::cout << " Status: " << req->status << std::endl; std::cout << " Status: " << req->status << std::endl;
std::cout << " Delta (ms) from handshake(HEADERS):" std::cout << " Delta (ms) from handshake(HEADERS):"
<< std::endl; << std::endl;
if(req->stat.on_syn_reply_time.tv_sec >= 0) { if(req->stat.stage >= STAT_ON_RESPONSE) {
std::cout << " SYN_REPLY: " std::cout << " response HEADERS: "
<< time_delta(req->stat.on_syn_reply_time, << time_delta(req->stat.on_response_time,
client.stat.on_handshake_time) client.stat.on_handshake_time).count()
<< "(" << "("
<< time_delta(req->stat.on_syn_reply_time, << time_delta(req->stat.on_response_time,
req->stat.on_syn_stream_time) req->stat.on_request_time).count()
<< ")" << ")"
<< std::endl; << std::endl;
} }
if(req->stat.on_complete_time.tv_sec >= 0) { if(req->stat.stage >= STAT_ON_COMPLETE) {
std::cout << " Completed: " std::cout << " Completed: "
<< time_delta(req->stat.on_complete_time, << time_delta(req->stat.on_complete_time,
client.stat.on_handshake_time) client.stat.on_handshake_time).count()
<< "(" << "("
<< time_delta(req->stat.on_complete_time, << time_delta(req->stat.on_complete_time,
req->stat.on_syn_stream_time) req->stat.on_request_time).count()
<< ")" << ")"
<< std::endl; << std::endl;
} }