Skip to content

Commit

Permalink
Merge pull request #1396 from Barenboim/master
Browse files Browse the repository at this point in the history
Optimize named timer lock logic.
  • Loading branch information
Barenboim authored Oct 17, 2023
2 parents 5b9be7a + 1e2da01 commit 2acb462
Showing 1 changed file with 72 additions and 68 deletions.
140 changes: 72 additions & 68 deletions src/factory/WFTaskFactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <utility>
#include <string>
#include <mutex>
#include <atomic>
#include "list.h"
#include "rbtree.h"
#include "WFGlobal.h"
Expand Down Expand Up @@ -175,26 +176,27 @@ class __WFNamedTimerTask : public __WFTimerTask
{
public:
__WFNamedTimerTask(time_t seconds, long nanoseconds,
__NamedTimerMap::TimerList *timers,
CommScheduler *scheduler,
timer_callback_t&& cb) :
__WFTimerTask(seconds, nanoseconds, scheduler, std::move(cb))
__WFTimerTask(seconds, nanoseconds, scheduler, std::move(cb)),
flag_(false)
{
dispatched_ = false;
node_.task = this;
}

void push_to(__NamedTimerMap::TimerList *timers)
{
timers->push_back(&node_);
timers_ = timers;
}

virtual ~__WFNamedTimerTask()
{
if (!dispatched_)
if (node_.task)
{
__timer_map.mutex_.lock();
std::lock_guard<std::mutex> lock(__timer_map.mutex_);
if (node_.task)
timers_->del(&node_, &__timer_map.root_);

__timer_map.mutex_.unlock();
}
}

Expand All @@ -203,57 +205,55 @@ class __WFNamedTimerTask : public __WFTimerTask
virtual void handle(int state, int error);

private:
bool dispatched_;
struct __timer_node node_;
__NamedTimerMap::TimerList *timers_;
std::atomic<bool> flag_;
std::mutex mutex_;
friend class __NamedTimerMap;
};

void __WFNamedTimerTask::dispatch()
{
int ret;

__timer_map.mutex_.lock();
mutex_.lock();
ret = this->scheduler->sleep(this);
if (ret < 0)
{
if (node_.task)
timers_->del(&node_, &__timer_map.root_);
}
else
{
if (!node_.task)
this->cancel();
}
if (ret >= 0 && flag_.exchange(true))
this->cancel();

dispatched_ = true;
__timer_map.mutex_.unlock();
mutex_.unlock();
if (ret < 0)
this->__WFTimerTask::handle(SS_STATE_ERROR, errno);
this->handle(SS_STATE_ERROR, errno);
}

void __WFNamedTimerTask::handle(int state, int error)
{
__timer_map.mutex_.lock();
if (node_.task)
timers_->del(&node_, &__timer_map.root_);
{
std::lock_guard<std::mutex> lock(__timer_map.mutex_);
if (node_.task)
{
timers_->del(&node_, &__timer_map.root_);
node_.task = NULL;
}
}

__timer_map.mutex_.unlock();
this->state = state;
this->error = error;
this->subtask_done();
mutex_.lock();
mutex_.unlock();
this->__WFTimerTask::handle(state, error);
}

WFTimerTask *__NamedTimerMap::create(const std::string& name,
time_t seconds, long nanoseconds,
CommScheduler *scheduler,
timer_callback_t&& cb)
{
TimerList *timers;
std::lock_guard<std::mutex> lock(mutex_);
timers = __get_object_list<TimerList>(name, &root_, true);
return new __WFNamedTimerTask(seconds, nanoseconds, timers,
scheduler, std::move(cb));
auto *task = new __WFNamedTimerTask(seconds, nanoseconds, scheduler,
std::move(cb));
mutex_.lock();
task->push_to(__get_object_list<TimerList>(name, &root_, true));
mutex_.unlock();
return task;
}

void __NamedTimerMap::cancel(const std::string& name, size_t max)
Expand All @@ -272,7 +272,7 @@ void __NamedTimerMap::cancel(const std::string& name, size_t max)

node = list_entry(timers->head.next, struct __timer_node, list);
list_del(&node->list);
if (node->task->dispatched_)
if (node->task->flag_.exchange(true))
node->task->cancel();

node->task = NULL;
Expand Down Expand Up @@ -344,45 +344,47 @@ static class __NamedCounterMap
class __WFNamedCounterTask : public WFCounterTask
{
public:
__WFNamedCounterTask(unsigned int target_value,
__NamedCounterMap::CounterList *counters,
counter_callback_t&& cb) :
__WFNamedCounterTask(unsigned int target_value, counter_callback_t&& cb) :
WFCounterTask(1, std::move(cb))
{
node_.target_value = target_value;
node_.task = this;
counters->push_back(&node_);
counters_ = counters;
}

virtual ~__WFNamedCounterTask()
void push_to(__NamedCounterMap::CounterList *counters)
{
if (this->value != 0)
__counter_map.remove(counters_, &node_);
counters->push_back(&node_);
counters_ = counters;
}

virtual void count()
{
__counter_map.count(counters_, &node_);
}

virtual ~__WFNamedCounterTask()
{
if (this->value != 0)
__counter_map.remove(counters_, &node_);
}

private:
struct __counter_node node_;
__NamedCounterMap::CounterList *counters_;
};

WFCounterTask *__NamedCounterMap::create(const std::string& name,
unsigned int target_value,
counter_callback_t&& cb)
unsigned int target_value,
counter_callback_t&& cb)
{
CounterList *counters;

if (target_value == 0)
return new WFCounterTask(0, std::move(cb));

std::lock_guard<std::mutex> lock(mutex_);
counters = __get_object_list<CounterList>(name, &root_, true);
return new __WFNamedCounterTask(target_value, counters, std::move(cb));
auto *task = new __WFNamedCounterTask(target_value, std::move(cb));
mutex_.lock();
task->push_to(__get_object_list<CounterList>(name, &root_, true));
mutex_.unlock();
return task;
}

void __NamedCounterMap::count_n_locked(CounterList *counters, unsigned int n,
Expand Down Expand Up @@ -509,35 +511,35 @@ static class __NamedConditionalMap
class __WFNamedCondtional : public WFConditional
{
public:
__WFNamedCondtional(SubTask *task, void **msgbuf,
__NamedConditionalMap::ConditionalList *conds) :
__WFNamedCondtional(SubTask *task, void **msgbuf) :
WFConditional(task, msgbuf)
{
node_.cond = this;
conds->push_back(&node_);
conds_ = conds;
}

__WFNamedCondtional(SubTask *task,
__NamedConditionalMap::ConditionalList *conds) :
__WFNamedCondtional(SubTask *task) :
WFConditional(task)
{
node_.cond = this;
conds->push_back(&node_);
conds_ = conds;
}

virtual ~__WFNamedCondtional()
void push_to(__NamedConditionalMap::ConditionalList *conds)
{
if (!this->flag)
__conditional_map.remove(conds_, &node_);
conds->push_back(&node_);
conds_ = conds;
}

virtual void signal(void *msg)
{
__conditional_map.signal(conds_, &node_, msg);
}

virtual ~__WFNamedCondtional()
{
if (!this->flag)
__conditional_map.remove(conds_, &node_);
}

private:
struct __conditional_node node_;
__NamedConditionalMap::ConditionalList *conds_;
Expand All @@ -546,19 +548,21 @@ class __WFNamedCondtional : public WFConditional
WFConditional *__NamedConditionalMap::create(const std::string& name,
SubTask *task, void **msgbuf)
{
ConditionalList *conds;
std::lock_guard<std::mutex> lock(mutex_);
conds = __get_object_list<ConditionalList>(name, &root_, true);
return new __WFNamedCondtional(task, msgbuf, conds);
auto *cond = new __WFNamedCondtional(task, msgbuf);
mutex_.lock();
cond->push_to(__get_object_list<ConditionalList>(name, &root_, true));
mutex_.unlock();
return cond;
}

WFConditional *__NamedConditionalMap::create(const std::string& name,
SubTask *task)
{
ConditionalList *conds;
std::lock_guard<std::mutex> lock(mutex_);
conds = __get_object_list<ConditionalList>(name, &root_, true);
return new __WFNamedCondtional(task, conds);
auto *cond = new __WFNamedCondtional(task);
mutex_.lock();
cond->push_to(__get_object_list<ConditionalList>(name, &root_, true));
mutex_.unlock();
return cond;
}

void __NamedConditionalMap::signal_max_locked(ConditionalList *conds,
Expand Down

0 comments on commit 2acb462

Please sign in to comment.