-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed potential data-race issues induced by incorrect memory order. Co-authored-by: Alex A. Yermoshenko <[email protected]>
- Loading branch information
Showing
38 changed files
with
14,599 additions
and
2,694 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. --------------------------------------------------- | ||
|
||
|
Oops, something went wrong.