From 4c7305058b18e8ea8ab794d9d571a54e9ee0ea80 Mon Sep 17 00:00:00 2001 From: Petr Rockai <me@mornfall.net> Date: Tue, 25 Jun 2019 10:22:13 +0000 Subject: [PATCH] MC: Make task_queue (and hence the weaver) more flexible. --- divine/mc/search.hpp | 50 ++++++++++++------------ divine/mc/t-search.hpp | 17 +++++---- divine/mc/t-weaver.hpp | 51 ++++++++++++------------- divine/mc/weaver.hpp | 87 ++++++++++++++++++------------------------ 4 files changed, 96 insertions(+), 109 deletions(-) diff --git a/divine/mc/search.hpp b/divine/mc/search.hpp index 44d51d660..bbdf52a56 100644 --- a/divine/mc/search.hpp +++ b/divine/mc/search.hpp @@ -19,41 +19,40 @@ #pragma once #include <divine/mc/weaver.hpp> -namespace divine::mc +namespace divine::mc::task { template< typename State, typename Label > - struct GraphTasks + struct Edge { - struct Edge - { - State from, to; - Label label; - bool isnew; - Edge( State f, State t, Label l, bool n ) - : from( f ), to( t ), label( l ), isnew( n ) - {} - }; - - struct Expand - { - State from; - Expand( State s ) : from( s ) {} - }; + State from, to; + Label label; + bool isnew; + Edge( State f, State t, Label l, bool n ) + : from( f ), to( t ), label( l ), isnew( n ) + {} + }; - struct Start {}; - using TQ_ = TaskQueue< GraphTasks< State, Label >, Start, Expand, Edge >; + template< typename State > + struct Expand + { + State from; + Expand( State s ) : from( s ) {} }; +} +namespace divine::mc +{ template< typename State, typename Label > - using GraphTQ = typename GraphTasks< State, Label >::TQ_; + using GraphTQ = task_queue< task::Start, task::Expand< State >, task::Edge< State, Label > >; - template< typename TQ > - struct Search : TQ::Skel + template< typename State, typename Label > + struct Search : GraphTQ< State, Label >::skeleton { - using Edge = typename TQ::Tasks::Edge; - using Expand = typename TQ::Tasks::Expand; + using TQ = GraphTQ< State, Label >; + using Edge = task::Edge< State, Label >; + using Expand = task::Expand< State >; - using TQ::Skel::run; + using TQ::skeleton::run; void run( TQ &tq, Edge e ) { @@ -61,5 +60,4 @@ namespace divine::mc tq.template add< Expand >( e.to ); } }; - } diff --git a/divine/mc/t-search.hpp b/divine/mc/t-search.hpp index b601cb366..d97865f51 100644 --- a/divine/mc/t-search.hpp +++ b/divine/mc/t-search.hpp @@ -26,15 +26,19 @@ namespace divine::t_mc { enum Label { Red, Black }; - using TQ = mc::GraphTQ< int, Label >; - struct Base : TQ::Skel + using TQ = mc::GraphTQ< int, Label >; + using Edge = mc::task::Edge< int, Label >; + using Expand = mc::task::Expand< int >; + + + struct Base : TQ::skeleton { brq::concurrent_hash_set< int > _states; - using TQ::Skel::run; + using TQ::skeleton::run; - void run( TQ &tq, typename TQ::Tasks::Start ) + void run( TQ &tq, mc::task::Start ) { _states.insert( 1 ); tq.add< Expand >( 1 ); @@ -126,13 +130,10 @@ namespace divine::t_mc struct Search { - using Edge = TQ::Tasks::Edge; - using Expand = TQ::Tasks::Expand; - template< typename B > auto weave( B builder ) { - return mc::Weaver< TQ >().extend( mc::Search< TQ >(), builder ); + return mc::Weaver< TQ >().extend( mc::Search< int, Label >(), builder ); } TEST( fixed ) diff --git a/divine/mc/t-weaver.hpp b/divine/mc/t-weaver.hpp index 16dc53d58..aaa5f784a 100644 --- a/divine/mc/t-weaver.hpp +++ b/divine/mc/t-weaver.hpp @@ -22,57 +22,56 @@ namespace divine::t_mc { - struct Tasks + struct task1 { - struct T1 - { - int i; - T1( int i ) : i( i ) {} - }; + int i; + task1( int i ) : i( i ) {} + }; - struct T2 - { - int j; - T2( int j ) : j( j ) {} - }; + struct task2 + { + int j; + task2( int j ) : j( j ) {} }; - using TQ = mc::TaskQueue< Tasks, Tasks::T1, Tasks::T2 >; + using tq = mc::task_queue< task1, task2 >; - struct Machine1 : TQ::Skel + struct machine1 : tq::skeleton { - using TQ::Skel::run; - void run( TQ &tq, Tasks::T1 t ) + using tq::skeleton::run; + + void run( tq &q, task1 t ) { if ( t.i < 10 ) - tq.add< T2 >( t.i + 1 ); + q.add< task2 >( t.i + 1 ); } }; - struct Machine2 : TQ::Skel + struct machine2 : tq::skeleton { - using TQ::Skel::run; - void run( TQ &tq, T2 t ) + using tq::skeleton::run; + + void run( tq &q, task2 t ) { - tq.add< T1 >( t.j + 1 ); + q.add< task1 >( t.j + 1 ); } }; - struct Counter : Tasks + struct counter { int t1 = 0, t2 = 0; - void run( TQ &, T1 ) { ++t1; } - void run( TQ &, T2 ) { ++t2; } + void run( tq &, task1 ) { ++t1; } + void run( tq &, task2 ) { ++t2; } }; struct Weave { TEST( basic ) { - mc::Weaver< TQ, Machine1, Machine2, Counter > weaver; - weaver.add< Tasks::T1 >( 3 ); + mc::Weaver< tq, machine1, machine2, counter > weaver; + weaver.add< task1 >( 3 ); weaver.run(); - auto &ctr = weaver.machine< Counter >(); + auto &ctr = weaver.machine< counter >(); ASSERT_EQ( ctr.t1, 5 ); ASSERT_EQ( ctr.t2, 4 ); } diff --git a/divine/mc/weaver.hpp b/divine/mc/weaver.hpp index 3bd43d804..bfb3f136c 100644 --- a/divine/mc/weaver.hpp +++ b/divine/mc/weaver.hpp @@ -19,76 +19,65 @@ #pragma once #include <deque> -namespace divine::mc +namespace divine::mc::task { + struct Start {}; +} - template< typename... > struct MachineSkel; - - template< typename TS, typename TQ, typename Task, typename... Tasks > - struct MachineSkel< TS, TQ, Task, Tasks... > : MachineSkel< TS, TQ, Tasks... > - { - using MachineSkel< TS, TQ, Tasks... >::run; - void run( TQ &, Task ) {} - }; +namespace divine::mc +{ + template< typename... > struct task_queue; - template< typename TS, typename TQ > - struct MachineSkel< TS, TQ > : TS + template<> + struct task_queue<> { - void run(); + void clear(); + template< typename P > bool process_next( P ) { return false; } }; - template< typename TaskStruct, typename... TaskList > - struct TaskQueue + template< typename task, typename... tasks > + struct task_queue< task, tasks... > : task_queue< tasks... > { - using TQ = TaskQueue< TaskStruct, TaskList... >; - using Tasks = TaskStruct; - - template< typename TS > - struct ExtendTS : TaskStruct, TS {}; + using next = task_queue< tasks... >; + using tq = task_queue< task, tasks... >; + std::deque< task > _queue; - template< typename TS, typename... Extra > - using Extend = TaskQueue< ExtendTS< TS >, Extra..., TaskList... >; + template< typename... ex > + using extend = task_queue< ex..., tasks... >; - using Queues = std::tuple< std::deque< TaskList > ... >; - Queues _queues; - - template< typename Task, typename... Args > + template< typename T, typename... Args > void add( Args... args ) { - std::get< std::deque< Task > >( _queues ).emplace_back( args... ); + if constexpr ( std::is_convertible_v< T, task > ) + _queue.emplace_back( args... ); + else + next::template add< T >( args... ); } - template< int i = 0 > void clear() { - if constexpr ( i < std::tuple_size_v< Queues > ) - { - std::get< i >( _queues ).clear(); - return clear< i + 1 >(); - } + _queue.clear(); + next::clear(); } - template< int i = 0, typename P > + template< typename P > bool process_next( P process ) { - if constexpr ( i < std::tuple_size_v< Queues > ) + if ( _queue.empty() ) + return next::process_next( process ); + else { - auto &q = std::get< i >( _queues ); - - if ( !q.empty() ) - { - process( q.front() ); - q.pop_front(); - return true; - } - - return process_next< i + 1 >( process ); + process( _queue.front() ); + _queue.pop_front(); + return true; } - else - return false; } - using Skel = MachineSkel< TaskStruct, TQ, TaskList... >; + struct skeleton + { + template< typename T > + void run( tq &, const T & ) {} + }; }; template< typename TQ, typename... Machines > @@ -213,12 +202,12 @@ namespace divine::mc void run() /* TODO parallel */ { auto process = [&]( auto t ) { process_task< 0 >( t ); }; - while ( _queue.template process_next< 0 >( process ) ); + while ( _queue.process_next( process ) ); } void start() { - add< typename TQ::Tasks::Start >(); + add< task::Start >(); run(); } }; -- GitLab