Skip to content

Commit

Permalink
Update taskflow to 3.6.0 (#93)
Browse files Browse the repository at this point in the history
Fixed potential data-race issues induced by incorrect memory order.

Co-authored-by: Alex A. Yermoshenko <ermoshenko@devoler.com>
  • Loading branch information
doterax and Alex A. Yermoshenko committed Dec 17, 2023
1 parent 5511415 commit 9daa430
Show file tree
Hide file tree
Showing 38 changed files with 14,599 additions and 2,694 deletions.
78 changes: 78 additions & 0 deletions lib/taskflow/algorithm/critical.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#pragma once

#include "../core/task.hpp"

/**
@file critical.hpp
@brief critical include file
*/

namespace tf {

// ----------------------------------------------------------------------------
// CriticalSection
// ----------------------------------------------------------------------------

/**
@class CriticalSection
@brief class to create a critical region of limited workers to run tasks
tf::CriticalSection is a warpper over tf::Semaphore and is specialized for
limiting the maximum concurrency over a set of tasks.
A critical section starts with an initial count representing that limit.
When a task is added to the critical section,
the task acquires and releases the semaphore internal to the critical section.
This design avoids explicit call of tf::Task::acquire and tf::Task::release.
The following example creates a critical section of one worker and adds
the five tasks to the critical section.
@code{.cpp}
tf::Executor executor(8); // create an executor of 8 workers
tf::Taskflow taskflow;
// create a critical section of 1 worker
tf::CriticalSection critical_section(1);
tf::Task A = taskflow.emplace([](){ std::cout << "A" << std::endl; });
tf::Task B = taskflow.emplace([](){ std::cout << "B" << std::endl; });
tf::Task C = taskflow.emplace([](){ std::cout << "C" << std::endl; });
tf::Task D = taskflow.emplace([](){ std::cout << "D" << std::endl; });
tf::Task E = taskflow.emplace([](){ std::cout << "E" << std::endl; });
critical_section.add(A, B, C, D, E);
executor.run(taskflow).wait();
@endcode
*/
class CriticalSection : public Semaphore {

public:

/**
@brief constructs a critical region of a limited number of workers
*/
explicit CriticalSection(size_t max_workers = 1);

/**
@brief adds a task into the critical region
*/
template <typename... Tasks>
void add(Tasks...tasks);
};

inline CriticalSection::CriticalSection(size_t max_workers) :
Semaphore {max_workers} {
}

template <typename... Tasks>
void CriticalSection::add(Tasks... tasks) {
(tasks.acquire(*this), ...);
(tasks.release(*this), ...);
}


} // end of namespace tf. ---------------------------------------------------


Loading

0 comments on commit 9daa430

Please sign in to comment.