Skip to content

Commit

Permalink
optimize timemanager
Browse files Browse the repository at this point in the history
  • Loading branch information
BestUO committed Jun 11, 2024
1 parent 3b06606 commit 2642d54
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 119 deletions.
7 changes: 3 additions & 4 deletions tools/rbtree/rbtreewrap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ class RBTreeWrap
}

template <typename R>
std::tuple<bool, R> GetTopObjKeyByFunction(std::function<R(const T*)> f)
std::tuple<bool, R> GetTopObjIf(std::function<R(const T*)> f)
{
auto top = rb_first(&m_rbtree);
if (top)
Expand All @@ -439,7 +439,7 @@ class RBTreeWrap
return std::make_tuple(false, R());
}

std::tuple<bool, T*> GetTopObjByFunction(std::function<bool(const T*)> f)
std::tuple<bool, T*> GetTopObjIf(std::function<bool(const T*)> f)
{
auto top = rb_first(&m_rbtree);
if (top)
Expand All @@ -452,8 +452,7 @@ class RBTreeWrap
return std::make_tuple(false, nullptr);
}

std::tuple<bool, T*> GetTopObjByFunctionAndDelete(
std::function<bool(const T*)> f)
std::tuple<bool, T*> GetTopObjIfAndDelete(std::function<bool(const T*)> f)
{
auto top = rb_first(&m_rbtree);
if (top)
Expand Down
160 changes: 45 additions & 115 deletions tools/timermanager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ class TimerManager
T key;
std::string additional = "";
std::chrono::milliseconds interval = std::chrono::milliseconds(0);
bool runInMainThread = true;
bool need_remove = false;
bool operator<(const TimerElement& t) const
{
return alarm < t.alarm;
Expand All @@ -442,14 +442,12 @@ class TimerManager
std::function<void()>&& _fun,
const T& _key,
const std::string& _additional,
std::chrono::milliseconds _interval,
bool _runinmainthread)
std::chrono::milliseconds _interval)
: alarm(_alarm)
, fun(std::move(_fun))
, key(std::move(_key))
, additional(std::move(_additional))
, interval(_interval)
, runInMainThread(_runinmainthread)
{ }
~TimerElement()
{
Expand All @@ -468,8 +466,7 @@ class TimerManager
const T& key,
const std::string& additional,
std::function<void()>&& fun,
std::chrono::milliseconds interval = std::chrono::milliseconds(0),
bool runinmainthread = true)
std::chrono::milliseconds interval = std::chrono::milliseconds(0))
{
TimerElement* element = nullptr;
if (!__stop)
Expand All @@ -479,21 +476,12 @@ class TimerManager
std::move(fun),
std::move(key),
std::move(additional),
interval,
runinmainthread);
interval);

std::lock_guard<std::mutex> lck(__mutex);
if (!__stop)
{
__timerQueue.AddObj(std::move(*element));
element->iter = __key2element.emplace(key, element);
__cv.notify_one();
}
else
{
ObjectPool<TimerElement>::GetInstance()->PutObject(element);
element = nullptr;
}
element->iter = __key2element.emplace(key, element);
__timer_queue.AddObj(std::move(*element));
__cv.notify_one();
}
return element;
}
Expand All @@ -503,46 +491,37 @@ class TimerManager
DeleteModel deletemodel = DeleteModel::ANY)
{
std::lock_guard<std::mutex> lck(__mutex);
__timerQueue.ExecuteAll([&](TimerElement* element) {
if (element->key == key && element->additional == additional)
auto members = __key2element.equal_range(key);
for (auto member = members.first; member != members.second; member++)
{
auto elementptr = member->second;
if (elementptr->additional == additional)
{
__timerQueue.DeleteObj((rb_node*)element);
__key2element.erase(element->iter);
ObjectPool<TimerElement>::GetInstance()->PutObject(
(TimerElement*)element);
elementptr->need_remove = true;
if (deletemodel == DeleteModel::ANY)
return true;
break;
}
return false;
});
}
__cv.notify_one();
}

void DeleteAlarm(const T& key)
void DeleteAlarm(TimerElement* elementptr)
{
// makesure element is available, if not sure, please use
// deleteAlarm(key, additional, DeleteModel::ANY)
std::lock_guard<std::mutex> lck(__mutex);
__timerQueue.ExecuteAll([&](TimerElement* element) {
if (element->key == key)
{
__timerQueue.DeleteObj((rb_node*)element);
__key2element.erase(element->iter);
ObjectPool<TimerElement>::GetInstance()->PutObject(
(TimerElement*)element);
}
return false;
});
elementptr->need_remove = true;
__cv.notify_one();
}

void DeleteAlarm(TimerElement* element)
void DeleteAlarm(const T& key)
{
// makesure element is available, if not sure, please use
// deleteAlarm(key, additional, DeleteModel::ANY)
std::lock_guard<std::mutex> lck(__mutex);
__timerQueue.DeleteObj((rb_node*)element);
__key2element.erase(element->iter);
ObjectPool<TimerElement>::GetInstance()->PutObject(
(TimerElement*)element);
auto members = __key2element.equal_range(key);
for (auto member = members.first; member != members.second; member++)
{
member->second->need_remove = true;
}
__cv.notify_one();
}

Expand All @@ -555,13 +534,12 @@ class TimerManager
__timerThread.join();
}
std::unique_lock<std::mutex> lck(__mutex);
auto timerQueue(std::move(__timerQueue));
auto timerQueue(std::move(__timer_queue));
lck.unlock();
timerQueue.ExecuteAll([&](TimerElement* element) {
timerQueue.DeleteObj((rb_node*)element);
__key2element.erase(element->iter);
ObjectPool<TimerElement>::GetInstance()->PutObject(
(TimerElement*)element);
ObjectPool<TimerElement>::GetInstance()->PutObject(element);
return false;
});
}
Expand All @@ -578,7 +556,7 @@ class TimerManager

private:
std::atomic<bool> __stop = {true};
rbtreewrap::v3::RBTreeWrap<TimerElement> __timerQueue;
rbtreewrap::v3::RBTreeWrap<TimerElement> __timer_queue;
std::thread __timerThread;
std::condition_variable __cv;
std::mutex __mutex;
Expand Down Expand Up @@ -609,7 +587,7 @@ class TimerManager
bool flag;
TIMETYPE::time_point timepoint;
std::unique_lock<std::mutex> lck(__mutex);
std::tie(flag, timepoint) = __timerQueue.GetTopObjKeyByFunction(
std::tie(flag, timepoint) = __timer_queue.GetTopObjIf(
std::function<TIMETYPE::time_point(const TimerElement*)>(
[](const TimerElement* e) -> TIMETYPE::time_point {
return e->alarm;
Expand All @@ -629,47 +607,24 @@ class TimerManager
{
if (element)
{
if (element->fun)
if (!element->need_remove && element->fun)
{
if (element->runInMainThread)
element->fun();
if (element->interval > std::chrono::milliseconds(0))
{
element->fun();
if (element->interval > std::chrono::milliseconds(0))
{
element->alarm = TIMETYPE::now() + element->interval;
std::lock_guard<std::mutex> lck(__mutex);
element->iter
= __key2element.emplace(element->key, element);
__timerQueue.AddObj(std::move(*element));
}
else
ObjectPool<TimerElement>::GetInstance()->PutObject(
element);
}
else
{
std::thread tmp([this, element = element]() {
element->fun();
if (element->interval > std::chrono::milliseconds(0))
{
element->alarm
= TIMETYPE::now() + element->interval;
std::lock_guard<std::mutex> lck(__mutex);
element->iter
= __key2element.emplace(element->key, element);
__timerQueue.AddObj(std::move(*element));
}
else
ObjectPool<TimerElement>::GetInstance()->PutObject(
element);
});
tmp.detach();
element->alarm = TIMETYPE::now() + element->interval;
std::lock_guard<std::mutex> lck(__mutex);
__timer_queue.DeleteObj((rb_node*)element);
__timer_queue.AddObj(std::move(*element));
return;
}
}
else
{
ObjectPool<TimerElement>::GetInstance()->PutObject(element);
std::lock_guard<std::mutex> lck(__mutex);
__timer_queue.DeleteObj((rb_node*)element);
__key2element.erase(element->iter);
}
ObjectPool<TimerElement>::GetInstance()->PutObject(element);
}
}

Expand All @@ -678,40 +633,15 @@ class TimerManager
bool flag;
TimerElement* element;
std::lock_guard<std::mutex> lck(__mutex);
std::tie(flag, element) = __timerQueue.GetTopObjByFunctionAndDelete(
[](const TimerElement* e) {
return TIMETYPE::now() > e->alarm;
});
std::tie(flag, element)
= __timer_queue.GetTopObjIf([](const TimerElement* e) {
return TIMETYPE::now() > e->alarm;
});
if (flag)
{
__key2element.erase(element->iter);
return element;
}
else
return nullptr;
}

void AddAlarmNoLock(std::chrono::milliseconds alarm,
const T& key,
const std::string& additional,
std::function<void()>&& fun,
std::chrono::milliseconds interval = std::chrono::milliseconds(0),
bool runinmainthread = true)
{
if (!__stop)
{
auto element = ObjectPool<TimerElement>::GetInstance()->GetObject();
element->alarm = TIMETYPE::now() + alarm;
element->fun = std::move(fun);
element->key = std::move(key);
element->additional = std::move(additional);
element->interval = interval;
element->runInMainThread = runinmainthread;

__timerQueue.addObj(std::move(*element));
__cv.notify_one();
}
}
};
} // namespace v3

Expand Down

0 comments on commit 2642d54

Please sign in to comment.