diff --git a/src/LDDState.h b/src/LDDState.h index aa8f5d795f5f433db8710e4db9d8539c1d00ac1e..59ba7ef0242a7b7c669ec95127f0c042ef854516 100755 --- a/src/LDDState.h +++ b/src/LDDState.h @@ -39,6 +39,8 @@ class LDDState { bool isDeadLock() {return m_blocage;} void setVisited() {m_visited=true;} bool isVisited() {return m_visited;} + void setCompletedSucc() {m_completed=true;} + bool isCompletedSucc() {return m_completed;} vector<int> getMarkedPlaces(set<int>& lplacesAP); vector<int> getUnmarkedPlaces(set<int>& lplacesAP); @@ -46,6 +48,7 @@ class LDDState { private: bool m_virtual = false; bool m_visited=false; + bool m_completed=false; }; diff --git a/src/ModelCheckBaseMT.h b/src/ModelCheckBaseMT.h index af8a2d5f8cf867eb840945edff6f7bbe6b10c73b..0215fc2fa62f72e0a40f867ba9fb1347f7f1acd4 100644 --- a/src/ModelCheckBaseMT.h +++ b/src/ModelCheckBaseMT.h @@ -4,7 +4,7 @@ class ModelCheckBaseMT : public CommonSOG { public: ModelCheckBaseMT(const NewNet &R, int BOUND,int nbThread); - virtual LDDState * buildInitialMetaState()=0; + virtual LDDState * getInitialMetaState()=0; virtual void buildSucc(LDDState *agregate)=0; void loadNet(); virtual ~ModelCheckBaseMT(); diff --git a/src/ModelCheckLace.cpp b/src/ModelCheckLace.cpp index 1b98ada04aab3b49c62c38a06e55af7e773735f4..301fb01cbf7f1734a19ca381ba7c7161cd28598a 100644 --- a/src/ModelCheckLace.cpp +++ b/src/ModelCheckLace.cpp @@ -156,7 +156,7 @@ TASK_3 (Set, fire_obs_lace,MDD, State, Set*, observable, vector<TransSylvan>*, t #define fire_obs_lace(state,obser,tb) CALL(fire_obs_lace, state, obser,tb) -LDDState * ModelCheckLace::buildInitialMetaState() +LDDState * ModelCheckLace::getInitialMetaState() { LDDState *initalAggregate=new LDDState; diff --git a/src/ModelCheckLace.h b/src/ModelCheckLace.h index e85c30a6b4374bd6896ce94c3b82544c4c8308ac..f418a7eb6e428d7cf0bb6b8d2efa91ea6486b28a 100644 --- a/src/ModelCheckLace.h +++ b/src/ModelCheckLace.h @@ -4,7 +4,7 @@ class ModelCheckLace : public ModelCheckBaseMT { public: ModelCheckLace(const NewNet &R, int BOUND,int nbThread); - LDDState * buildInitialMetaState(); + LDDState * getInitialMetaState(); void buildSucc(LDDState *agregate); private: void preConfigure(); diff --git a/src/ModelCheckerTh.cpp b/src/ModelCheckerTh.cpp index 271348c27c0d2b4133b347f722b143cacbbdc90a..4fc0d3ecf4de2c65d7fcfc6838a079d050070b7d 100644 --- a/src/ModelCheckerTh.cpp +++ b/src/ModelCheckerTh.cpp @@ -105,23 +105,14 @@ void ModelCheckerTh::preConfigure() -LDDState * ModelCheckerTh::buildInitialMetaState() +LDDState * ModelCheckerTh::getInitialMetaState() { ComputeTh_Succ(); - LDDState *c=new LDDState; - MDD initial_meta_state=Accessible_epsilon(m_initialMarking); - ldd_refs_push(initial_meta_state); - c->m_lddstate=initial_meta_state; - m_graph->setInitialState(c); - m_graph->insert(c); - Set fire=firable_obs(initial_meta_state); - int j=0; - for(auto it=fire.begin(); it!=fire.end(); it++,j++) - m_st[j%m_nb_thread].push(couple_th(c,*it)); - pthread_barrier_wait(&m_barrier_threads); - pthread_barrier_wait(&m_barrier_builder); - c->setVisited(); - return c; + while (!m_finish_initial); + LDDState *initial_metastate=m_graph->getInitialState(); + while (!initial_metastate->isCompletedSucc()); + initial_metastate->setVisited(); + return initial_metastate; } void ModelCheckerTh::buildSucc(LDDState *agregate) @@ -129,65 +120,159 @@ void ModelCheckerTh::buildSucc(LDDState *agregate) if (!agregate->isVisited()) { agregate->setVisited(); - Set fire=firable_obs(agregate->getLDDValue()); - int j=0; - for(auto it=fire.begin(); it!=fire.end(); it++,j++) - m_st[j%m_nb_thread].push(couple_th(agregate,*it)); - pthread_barrier_wait(&m_barrier_threads); - pthread_barrier_wait(&m_barrier_builder); - //Wait for all threads to finish their work - + while (!agregate->isCompletedSucc()); } } void * ModelCheckerTh::Compute_successors() { int id_thread; - int nb_it=0,nb_failed=0,max_succ=0; + pthread_mutex_lock(&m_mutex); id_thread=m_id_thread++; pthread_mutex_unlock(&m_mutex); - LDDState* reached_class=nullptr; + Set fire; + int min_charge=0; + if (id_thread==0) + { + LDDState *c=new LDDState; + + MDD Complete_meta_state(Accessible_epsilon(m_initialMarking)); + ldd_refs_push(Complete_meta_state); + MDD canonised_initial=Canonize(Complete_meta_state,0); + ldd_refs_push(canonised_initial); + fire=firable_obs(Complete_meta_state); + + + c->m_lddstate=canonised_initial; + + m_st[0].push(Pair(couple(c,Complete_meta_state),fire)); + m_graph->setInitialState(c); + m_graph->insert(c); + //m_graph->nbMarking+=bdd_pathcount(c->m_lddstate); + m_charge[0]=1; + m_finish_initial=true; + + } + + LDDState* reached_class; + do { - pthread_barrier_wait(&m_barrier_threads); + while (!m_st[id_thread].empty()) { - couple_th elt=m_st[id_thread].top(); + m_terminaison[id_thread]=false; + pthread_spin_lock(&m_spin_stack[id_thread]); + Pair e=m_st[id_thread].top(); + //pthread_spin_lock(&m_accessible); m_st[id_thread].pop(); - LDDState *aggregate=elt.first; - MDD meta_state=aggregate->getLDDValue(); - int transition=elt.second; - MDD complete_state=Accessible_epsilon(get_successor(meta_state,transition)); - reached_class=new LDDState; - reached_class->m_lddstate=complete_state; - reached_class->setDiv(Set_Div(complete_state)); - reached_class->setDeadLock(Set_Bloc(complete_state)); - pthread_mutex_lock(&m_graph_mutex); - LDDState* pos=m_graph->find(reached_class); - if(!pos) - { - m_graph->addArc(); - m_graph->insert(reached_class); - pthread_mutex_unlock(&m_graph_mutex); - aggregate->Successors.insert(aggregate->Successors.begin(),LDDEdge(reached_class,transition)); - reached_class->Predecessors.insert(reached_class->Predecessors.begin(),LDDEdge(aggregate,transition)); - } - else + + pthread_spin_unlock(&m_spin_stack[id_thread]); + + + m_charge[id_thread]--; + while(!e.second.empty()) { - m_graph->addArc(); - pthread_mutex_unlock(&m_graph_mutex); - aggregate->Successors.insert(aggregate->Successors.begin(),LDDEdge(pos,transition)); - pos->Predecessors.insert(pos->Predecessors.begin(),LDDEdge(aggregate,transition)); - delete reached_class; + int t = *e.second.begin(); + e.second.erase(t); + reached_class=new LDDState(); + if (id_thread) + { + pthread_mutex_lock(&m_supervise_gc_mutex); + m_gc++; + if (m_gc==1) { + pthread_mutex_lock(&m_gc_mutex); + } + pthread_mutex_unlock(&m_supervise_gc_mutex); + } + + + MDD Complete_meta_state=Accessible_epsilon(get_successor(e.first.second,t)); + + ldd_refs_push(Complete_meta_state); + + MDD reduced_meta=Canonize(Complete_meta_state,0); + ldd_refs_push(reduced_meta); + + if (id_thread==0) + { + pthread_mutex_lock(&m_gc_mutex); + // #ifdef DEBUG_GC + // displayMDDTableInfo(); + // #endif // DEBUG_GC + sylvan_gc_seq(); + // #ifdef DEBUG_GC + // displayMDDTableInfo(); + // #endif // DEBUG_GC + pthread_mutex_unlock(&m_gc_mutex); + } + reached_class->m_lddstate=reduced_meta; + //reached_class->m_lddstate=reduced_meta; + //nbnode=bdd_pathcount(reached_class->m_lddstate); + + //pthread_spin_lock(&m_accessible); + pthread_mutex_lock(&m_graph_mutex); + + LDDState* pos=m_graph->find(reached_class); + + if(!pos) + { + // cout<<"not found"<<endl; + //reached_class->blocage=Set_Bloc(Complete_meta_state); + //reached_class->boucle=Set_Div(Complete_meta_state); + + m_graph->addArc(); + m_graph->insert(reached_class); + pthread_mutex_unlock(&m_graph_mutex); + + e.first.first->Successors.insert(e.first.first->Successors.begin(),LDDEdge(reached_class,t)); + reached_class->Predecessors.insert(reached_class->Predecessors.begin(),LDDEdge(e.first.first,t)); + //pthread_mutex_lock(&m_mutex); + fire=firable_obs(Complete_meta_state); + //if (max_succ<fire.size()) max_succ=fire.size(); + //pthread_mutex_unlock(&m_mutex); + min_charge= minCharge(); + //m_min_charge=(m_min_charge+1) % m_nb_thread; + pthread_spin_lock(&m_spin_stack[min_charge]); + m_st[min_charge].push(Pair(couple(reached_class,Complete_meta_state),fire)); + pthread_spin_unlock(&m_spin_stack[min_charge]); + m_charge[min_charge]++; + } + else + { + m_graph->addArc(); + pthread_mutex_unlock(&m_graph_mutex); + + e.first.first->Successors.insert(e.first.first->Successors.begin(),LDDEdge(pos,t)); + pos->Predecessors.insert(pos->Predecessors.begin(),LDDEdge(e.first.first,t)); + delete reached_class; + + } + if (id_thread) + { + pthread_mutex_lock(&m_supervise_gc_mutex); + m_gc--; + if (m_gc==0) pthread_mutex_unlock(&m_gc_mutex); + pthread_mutex_unlock(&m_supervise_gc_mutex); + } } - + e.first.first->setCompletedSucc(); } - pthread_barrier_wait(&m_barrier_builder); + m_terminaison[id_thread]=true; + + + } - while (!m_finish); - cout<<"exit thread i"<<id_thread<<endl; + while (isNotTerminated()); + + + + + + + } @@ -208,12 +293,22 @@ void ModelCheckerTh::ComputeTh_Succ() m_id_thread=0; pthread_mutex_init(&m_mutex, NULL); - //pthread_mutex_init(&m_gc_mutex,NULL); + pthread_mutex_init(&m_gc_mutex,NULL); pthread_mutex_init(&m_graph_mutex,NULL); - //pthread_mutex_init(&m_supervise_gc_mutex,NULL); - pthread_barrier_init(&m_barrier_threads, NULL, m_nb_thread+1); - pthread_barrier_init(&m_barrier_builder, NULL, m_nb_thread+1); + pthread_mutex_init(&m_supervise_gc_mutex,NULL); + /* pthread_barrier_init(&m_barrier_threads, NULL, m_nb_thread+1); + pthread_barrier_init(&m_barrier_builder, NULL, m_nb_thread+1);*/ + for (int i=0; i<m_nb_thread; i++) + { + pthread_spin_init(&m_spin_stack[i], NULL); + m_charge[i]=0; + m_terminaison[i]=false; + } + + + + for (int i=0; i<m_nb_thread; i++) { if ((rc = pthread_create(&m_list_thread[i], NULL,threadHandler,this))) @@ -231,8 +326,8 @@ void ModelCheckerTh::ComputeTh_Succ() } ModelCheckerTh::~ModelCheckerTh() { m_finish=true; - pthread_barrier_wait(&m_barrier_threads); - pthread_barrier_wait(&m_barrier_builder); + /* pthread_barrier_wait(&m_barrier_threads); + pthread_barrier_wait(&m_barrier_builder); */ for (int i = 0; i < m_nb_thread; i++) { cout<<"thread "<<i<<endl; @@ -240,3 +335,31 @@ ModelCheckerTh::~ModelCheckerTh() { } } + +int ModelCheckerTh::minCharge() +{ + int pos=0; + int min_charge=m_charge[0]; + for (int i=1; i<m_nb_thread; i++) + { + if (m_charge[i]<min_charge) + { + min_charge=m_charge[i]; + pos=i; + } + } + return pos; + +} + +bool ModelCheckerTh::isNotTerminated() +{ + bool res=true; + int i=0; + while (i<m_nb_thread && res) + { + res=m_terminaison[i]; + i++; + } + return !res; +} diff --git a/src/ModelCheckerTh.h b/src/ModelCheckerTh.h index 4619d242b9a1fca312e628e4a9ed4dfb9683a21c..8f7c37eaa2e1214a635aa79cc4018536dba30c50 100644 --- a/src/ModelCheckerTh.h +++ b/src/ModelCheckerTh.h @@ -9,26 +9,30 @@ class ModelCheckerTh : public ModelCheckBaseMT public: ModelCheckerTh(const NewNet &R, int BOUND,int nbThread); ~ModelCheckerTh(); - LDDState * buildInitialMetaState(); + LDDState * getInitialMetaState(); void buildSucc(LDDState *agregate); static void *threadHandler(void *context); void *Compute_successors(); void ComputeTh_Succ(); private: void preConfigure(); - - pile_t m_st[128]; + bool isNotTerminated(); + int minCharge(); + pile m_st[128]; + int m_charge[128]; + bool m_terminaison[128]; int m_id_thread; pthread_mutex_t m_mutex; pthread_mutex_t m_graph_mutex; - //pthread_mutex_t m_gc_mutex; - //pthread_mutex_t m_supervise_gc_mutex; + pthread_mutex_t m_gc_mutex; + pthread_mutex_t m_supervise_gc_mutex; - pthread_barrier_t m_barrier_threads,m_barrier_builder; - //unsigned int m_gc; + //pthread_barrier_t m_barrier_builder; + unsigned int m_gc; bool m_finish=false; - + bool m_finish_initial=false; pthread_mutex_t m_mutex_stack[128]; pthread_t m_list_thread[128]; + pthread_spinlock_t m_spin_stack[128]; }; #endif diff --git a/src/SogKripkeTh.cpp b/src/SogKripkeTh.cpp index ab4d48a843ef133cfcdcc8f251210272dc95ade1..5345637baec86cce711a94744f83fa1b433cdd73 100644 --- a/src/SogKripkeTh.cpp +++ b/src/SogKripkeTh.cpp @@ -33,7 +33,7 @@ SogKripkeTh::SogKripkeTh(const spot::bdd_dict_ptr& dict_ptr,ModelCheckBaseMT *bu state* SogKripkeTh::get_init_state() const { // cout<<__func__<<endl; - return new SogKripkeStateTh(m_builder->buildInitialMetaState());//new SpotSogState(); + return new SogKripkeStateTh(m_builder->getInitialMetaState());//new SpotSogState(); } // Allows to print state label representing its id