From 79343a8a093630f1c0696f135c6e3bef0c23da28 Mon Sep 17 00:00:00 2001 From: Haomai Wang Date: Sun, 1 May 2016 08:32:24 +0800 Subject: [PATCH] Event: replace ceph_clock_now with coarse_real_clock reduce cpu utilization on real clock latency Signed-off-by: Haomai Wang --- src/msg/async/Event.cc | 63 +++++++++++++----------------------------- src/msg/async/Event.h | 10 ++++--- 2 files changed, 25 insertions(+), 48 deletions(-) diff --git a/src/msg/async/Event.cc b/src/msg/async/Event.cc index 0a34cfe2cbab..469ba4b0d90c 100644 --- a/src/msg/async/Event.cc +++ b/src/msg/async/Event.cc @@ -229,20 +229,7 @@ uint64_t EventCenter::create_time_event(uint64_t microseconds, EventCallbackRef ldout(cct, 10) << __func__ << " id=" << id << " trigger after " << microseconds << "us"<< dendl; EventCenter::TimeEvent event; - utime_t expire; - struct timeval tv; - - if (microseconds < 5) { - tv.tv_sec = 0; - tv.tv_usec = microseconds; - } else { - expire = ceph_clock_now(cct); - expire.copy_to_timeval(&tv); - tv.tv_sec += microseconds / 1000000; - tv.tv_usec += microseconds % 1000000; - } - expire.set_from_timeval(&tv); - + clock_type::time_point expire = clock_type::now() + std::chrono::microseconds(microseconds); event.id = id; event.time_cb = ctxt; time_events[expire].push_back(event); @@ -260,8 +247,7 @@ void EventCenter::delete_time_event(uint64_t id) if (id >= time_event_next_id) return ; - for (map >::iterator it = time_events.begin(); - it != time_events.end(); ++it) { + for (auto it = time_events.begin(); it != time_events.end(); ++it) { for (list::iterator j = it->second.begin(); j != it->second.end(); ++j) { if (j->id == id) { @@ -290,9 +276,8 @@ void EventCenter::wakeup() int EventCenter::process_time_events() { int processed = 0; - time_t now = time(NULL); - utime_t cur = ceph_clock_now(cct); - ldout(cct, 10) << __func__ << " cur time is " << cur << dendl; + clock_type::time_point now = clock_type::now(); + ldout(cct, 10) << __func__ << " cur time is " << now << dendl; time_lock.Lock(); /* If the system clock is moved to the future, and then set back to the @@ -303,18 +288,14 @@ int EventCenter::process_time_events() * events to be processed ASAP when this happens: the idea is that * processing events earlier is less dangerous than delaying them * indefinitely, and practice suggests it is. */ - bool clock_skewed = false; - if (now < last_time) { - clock_skewed = true; - } + bool clock_skewed = now < last_time; last_time = now; - map >::iterator prev; + map >::iterator prev; list need_process; - for (map >::iterator it = time_events.begin(); - it != time_events.end(); ) { + for (auto it = time_events.begin(); it != time_events.end(); ) { prev = it; - if (cur >= it->first || clock_skewed) { + if (now >= it->first || clock_skewed) { need_process.splice(need_process.end(), it->second); ++it; time_events.erase(prev); @@ -341,39 +322,33 @@ int EventCenter::process_events(int timeout_microseconds) struct timeval tv; int numevents; bool trigger_time = false; + auto now = clock_type::now(); - utime_t now = ceph_clock_now(cct);; // If exists external events, don't block if (external_num_events.read()) { tv.tv_sec = 0; tv.tv_usec = 0; next_time = now; } else { - utime_t period, shortest; - now.copy_to_timeval(&tv); - if (timeout_microseconds > 0) { - tv.tv_sec += timeout_microseconds / 1000000; - tv.tv_usec += timeout_microseconds % 1000000; - } - shortest.set_from_timeval(&tv); + clock_type::time_point shortest; + shortest = now + std::chrono::microseconds(timeout_microseconds); Mutex::Locker l(time_lock); - map >::iterator it = time_events.begin(); - if (it != time_events.end() && shortest >= it->first) { + auto it = time_events.begin(); + if (it != time_events.end() && shortest > it->first) { ldout(cct, 10) << __func__ << " shortest is " << shortest << " it->first is " << it->first << dendl; shortest = it->first; trigger_time = true; if (shortest > now) { - period = shortest - now; - period.copy_to_timeval(&tv); + timeout_microseconds = std::chrono::duration_cast( + shortest - now).count(); } else { - tv.tv_sec = 0; - tv.tv_usec = 0; + shortest = now; + timeout_microseconds = 0; } - } else { - tv.tv_sec = timeout_microseconds / 1000000; - tv.tv_usec = timeout_microseconds % 1000000; } + tv.tv_sec = timeout_microseconds / 1000000; + tv.tv_usec = timeout_microseconds % 1000000; next_time = shortest; } diff --git a/src/msg/async/Event.h b/src/msg/async/Event.h index 126a36c3120b..4618c156b0d9 100644 --- a/src/msg/async/Event.h +++ b/src/msg/async/Event.h @@ -42,6 +42,7 @@ #include "include/atomic.h" #include "include/Context.h" #include "include/unordered_map.h" +#include "common/ceph_time.h" #include "common/WorkQueue.h" #include "net_handler.h" @@ -85,6 +86,7 @@ class EventDriver { * EventCenter maintain a set of file descriptor and handle registered events. */ class EventCenter { + using clock_type = ceph::coarse_mono_clock; struct FileEvent { int mask; EventCallbackRef read_cb; @@ -107,10 +109,10 @@ class EventCenter { deque external_events; vector file_events; EventDriver *driver; - map > time_events; + map > time_events; uint64_t time_event_next_id; - time_t last_time; // last time process time event - utime_t next_time; // next wake up time + clock_type::time_point last_time; // last time process time event + clock_type::time_point next_time; // next wake up time int notify_receive_fd; int notify_send_fd; NetHandler net; @@ -136,7 +138,7 @@ class EventCenter { notify_receive_fd(-1), notify_send_fd(-1), net(c), owner(0), notify_handler(NULL), already_wakeup(0) { - last_time = time(NULL); + last_time = clock_type::now(); } ~EventCenter(); ostream& _event_prefix(std::ostream *_dout); -- 2.47.3