int data_order = 0;
const Reflection::ClassBase *ordered_data = nullptr;
const Reflection::ClassBase *unordered_data = nullptr;
+ for_common_deps(node1, node2, [&](const Reflection::ClassBase *type, int flags1, int flags2){
+ bool unbuffered = (flags1|flags2)&System::UNBUFFERED;
+ flags1 &= ~System::UNBUFFERED;
+ flags2 &= ~System::UNBUFFERED;
+
+ int order = 0;
+ // Read-only access to fresh data comes after any writes
+ if(flags1==System::READ_FRESH && (flags2&System::WRITE))
+ order = 1;
+ else if(flags2==System::READ_FRESH && (flags1&System::WRITE))
+ order = -1;
+ // Reads can happen concurrently to other access with buffering
+ else if(!(flags1&flags2&System::WRITE) && !unbuffered)
+ order = 0;
+ // Chained updates always come after non-chained writes
+ else if(flags1==System::CHAINED_UPDATE && (flags2==System::WRITE || flags2==System::UPDATE))
+ order = 1;
+ else if(flags2==System::CHAINED_UPDATE && (flags1==System::WRITE || flags1==System::UPDATE))
+ order = -1;
+ else
+ unordered_data = type;
+
+ if(order && data_order && order!=data_order)
+ throw scheduling_error(format("Ambiguous data ordering between %s and %s, accessing %s and %s",
+ node1.type->get_name(), node2.type->get_name(), ordered_data->get_name(), type->get_name()));
+
+ data_order = order;
+ ordered_data = type;
+ });
+
+ if(!data_order && unordered_data)
+ throw scheduling_error(format("Ambiguous data ordering between %s and %s, accessing %s",
+ node1.type->get_name(), node2.type->get_name(), unordered_data->get_name()));
+
+ return data_order;
+}
+
+template<typename F>
+void SystemScheduler::for_common_deps(const GraphNode &node1, const GraphNode &node2, const F &func)
+{
for(const System::Dependency &d1: node1.system->get_dependencies())
{
int flags1 = d1.get_flags()&System::DATA_MASK;
else
continue;
- bool unbuffered = (flags1|flags2)&System::UNBUFFERED;
- flags1 &= ~System::UNBUFFERED;
- flags2 &= ~System::UNBUFFERED;
-
- int order = 0;
- // Read-only access to fresh data comes after any writes
- if(flags1==System::READ_FRESH && (flags2&System::WRITE))
- order = 1;
- else if(flags2==System::READ_FRESH && (flags1&System::WRITE))
- order = -1;
- // Reads can happen concurrently to other access with buffering
- else if(!(flags1&flags2&System::WRITE) && !unbuffered)
- order = 0;
- // Chained updates always come after non-chained writes
- else if(flags1==System::CHAINED_UPDATE && (flags2==System::WRITE || flags2==System::UPDATE))
- order = 1;
- else if(flags2==System::CHAINED_UPDATE && (flags1==System::WRITE || flags1==System::UPDATE))
- order = -1;
- else
- unordered_data = common_type;
-
- if(order && data_order && order!=data_order)
- throw scheduling_error(format("Ambiguous data ordering between %s and %s, accessing %s and %s",
- node1.type->get_name(), node2.type->get_name(), ordered_data->get_name(), common_type->get_name()));
-
- data_order = order;
- ordered_data = common_type;
+ func(common_type, flags1, flags2);
}
}
-
- if(!data_order && unordered_data)
- throw scheduling_error(format("Ambiguous data ordering between %s and %s, accessing %s",
- node1.type->get_name(), node2.type->get_name(), unordered_data->get_name()));
-
- return data_order;
}
void SystemScheduler::run(Time::TimeDelta dt)