17#include <dispenso/platform.h>
204void callFunctor(
void* ptr) {
205 (*
static_cast<F*
>(ptr))();
209void destroyFunctor(
void* ptr) {
210 static_cast<F*
>(ptr)->~F();
211 constexpr size_t kFuncSize =
static_cast<size_t>(dispenso::detail::nextPow2(
sizeof(F)));
225 Node& operator=(
const Node&) =
delete;
227 : numIncompletePredecessors_(
other.numIncompletePredecessors_.load()),
228 numPredecessors_(
other.numPredecessors_),
229 invoke_(
other.invoke_),
230 destroy_(
other.destroy_),
231 funcBuffer_(
other.funcBuffer_),
232 dependents_(std::move(
other.dependents_)) {
233 other.funcBuffer_ =
nullptr;
237 destroy_(funcBuffer_);
245 template <
typename...
Ns>
247 ((
void)std::initializer_list<int>{(dependsOnOneNode(
nodes), 0)...});
254 invoke_(funcBuffer_);
255 numIncompletePredecessors_.store(kCompleted, std::memory_order_release);
283 return numPredecessors_;
292 return numIncompletePredecessors_.load(std::memory_order_relaxed) == kCompleted;
302 if (numIncompletePredecessors_.load(std::memory_order_relaxed) == kCompleted) {
303 numIncompletePredecessors_.store(0, std::memory_order_relaxed);
315 numIncompletePredecessors_.store(kCompleted, std::memory_order_relaxed);
320 Node(
F&&
f) : numIncompletePredecessors_(0) {
321 using FNoRef =
typename std::remove_reference<F>::type;
323 constexpr size_t kFuncSize =
static_cast<size_t>(detail::nextPow2(
sizeof(
FNoRef)));
325 new (funcBuffer_)
FNoRef(std::forward<F>(
f));
326 invoke_ = ::detail::callFunctor<FNoRef>;
327 destroy_ = ::detail::destroyFunctor<FNoRef>;
330 void dependsOnOneNode(Node& node) {
331 node.dependents_.emplace_back(
this);
335 static constexpr size_t kCompleted = std::numeric_limits<size_t>::max();
336 mutable std::atomic<size_t> numIncompletePredecessors_;
337 size_t numPredecessors_ = 0;
340 using InvokerType = void (*)(
void* ptr);
343 InvokerType destroy_;
346 std::vector<Node*> dependents_;
349 friend class SubgraphT;
350 friend class ::detail::ExecutorBase;
351 template <
typename G>
352 friend void setAllNodesIncomplete(
const G& graph);
364 :
Node(std::move(
other)), biPropSet_(std::move(
other.biPropSet_)) {}
371 template <
class...
Ns>
373 ((
void)std::initializer_list<int>{(biPropDependsOnOneNode(
nodes), 0)...});
382 return biPropSet_ && biPropSet_ == node.biPropSet_;
388 inline void removeFromBiPropSet() {
389 if (biPropSet_ !=
nullptr) {
390 auto it = std::find(biPropSet_->begin(), biPropSet_->end(),
this);
391 if (it != biPropSet_->end()) {
392 biPropSet_->erase(it);
397 DISPENSO_DLL_ACCESS
void biPropDependsOnOneNode(BiPropNode& node);
399 std::shared_ptr<std::vector<const BiPropNode*>> biPropSet_;
402 friend class SubgraphT;
403 friend class ::detail::ExecutorBase;
417 : graph_(
other.graph_),
418 nodes_(std::move(
other.nodes_)),
419 allocator_(std::move(
other.allocator_)) {}
429 nodes_.push_back(
new (allocator_->alloc()) NodeType(std::forward<T>(
f)));
430 return *nodes_.back();
436 return nodes_.size();
444 return *nodes_[
index];
452 return *nodes_[
index];
461 for (
const N* node : nodes_) {
473 for (
N* node : nodes_) {
485 using PoolPtr = std::unique_ptr<NoLockPoolAllocator, DeallocFunc>;
487 static constexpr size_t kNodeSizeP2 = detail::nextPow2(
sizeof(NodeType));
491 inline void removeNodeFromBiPropSet(Node* ) {}
492 void removeNodeFromBiPropSet(BiPropNode* node) {
493 node->removeFromBiPropSet();
495 void decrementDependentCounters();
496 size_t markNodesWithPredicessors();
497 void removePredecessorDependencies(
size_t numGraphPredecessors);
501 static PoolPtr getAllocator();
502 static void releaseAllocator(NoLockPoolAllocator* ptr);
505#if defined(_WIN32) && !defined(__MINGW32__)
507#pragma warning(disable : 4251)
509 std::vector<N*> nodes_;
512#if defined(_WIN32) && !defined(__MINGW32__)
531 subgraphs_.push_back(SubgraphType(
this));
549 return subgraphs_[0].addNode(std::forward<T>(
f));
555 return subgraphs_[0].numNodes();
563 return subgraphs_[0].node(
index);
571 return subgraphs_[0].node(
index);
581 return subgraphs_.size();
589 return subgraphs_[
index];
597 return subgraphs_[
index];
630 for (
const N* node : subgraph.nodes_) {
643 for (
N* node : subgraph.nodes_) {
653 subgraphs_.push_back(SubgraphType(
this));
660 subgraph.destroyNodes();
665 static constexpr size_t kSubgraphSizeP2 = detail::nextPow2(
sizeof(SubgraphType));
667#if defined(_WIN32) && !defined(__MINGW32__)
669#pragma warning(disable : 4251)
671 std::deque<SubgraphT<N>> subgraphs_;
672#if defined(_WIN32) && !defined(__MINGW32__)
680using Graph = GraphT<Node>;
681using BiPropGraph = GraphT<BiPropNode>;
683using Subgraph = SubgraphT<Node>;
684using BiPropSubgraph = SubgraphT<BiPropNode>;
bool isSameSet(const BiPropNode &node) const
void biPropDependsOn(Ns &... nodes)
void forEachNode(F &&func) const
void forEachNode(F &&func)
void forEachSubgraph(F &&func) const
size_t numSubgraphs() const
void forEachSubgraph(F &&func)
const SubgraphT< N > & subgraph(size_t index) const
const N & node(size_t index) const
SubgraphT< N > & subgraph(size_t index)
bool setIncomplete() const
void setCompleted() const
void forEachDependent(F &&func) const
void forEachDependent(F &&func)
void dependsOn(Ns &... nodes)
size_t numPredecessors() const
const N & node(size_t index) const
void forEachNode(F &&func) const
void forEachNode(F &&func)
detail::OpResult< T > OpResult