diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f9320561c5a0e2b75f6d3fb2c3f91bd5bcd9d0a..eb31e4d9f2804f346645b15cafe7d2974802cdc5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ set(CMAKE_CXX_EXTENSIONS OFF) # Add compiler flags if(CMAKE_COMPILER_IS_GNUCC) #used flags -Og -DNDEBUG - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -std=c++17 -pthread -Og -DNDEBUG") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -std=c++17 -pthread -DNDEBUG -funswitch-loops -floop-interchange -floop-unroll-and-jam -fpeel-loops -fpredictive-commoning -fsplit-loops -fsplit-paths -fexpensive-optimizations -fcse-follow-jumps -fthread-jumps -finline-functions -finline-small-functions -findirect-inlining -foptimize-strlen -fpartial-inlining -fexpensive-optimizations -falign-functions -falign-jumps -falign-labels -falign-loops -fcaller-saves -fdelete-null-pointer-checks") #-Og endif() diff --git a/src/HybridKripkeState.h b/src/HybridKripkeState.h index 7d1b4b3f7caee717a848e245c10f3a790e3478ee..e43146644de0486cda224461e004233c6e93adf7 100644 --- a/src/HybridKripkeState.h +++ b/src/HybridKripkeState.h @@ -40,7 +40,7 @@ public: } else { memcpy(m_id,e.id,16); - MPI_Send(m_id,16,MPI_BYTE,e.pcontainer, TAG_ASK_STATE, MPI_COMM_WORLD); + MPI_Send(m_id,16,MPI_BYTE,e.pcontainer, TAG_ASK_STATE, MPI_COMM_WORLD); MPI_Status status; //int nbytes; MPI_Probe(MPI_ANY_SOURCE, TAG_ACK_STATE, MPI_COMM_WORLD, &status); @@ -92,36 +92,26 @@ public: MPI_Probe(MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&status); MPI_Get_count(&status, MPI_BYTE, &nbytes); char inmsg[nbytes+1]; - //cout<<"Received bytes : "<<nbytes<<endl; MPI_Recv(inmsg, nbytes, MPI_BYTE,status.MPI_SOURCE,TAG_ACK_SUCC,MPI_COMM_WORLD, &status); uint32_t nb_succ; memcpy(&nb_succ,inmsg,4); - //cout<<"Number of successors "<<nb_succ<<endl; indice=4; - succ_t *succ_elt; + succ_t succ_elt; //printf("List of successors of %.16s\n",m_id); for (uint32_t i=0;i<nb_succ;i++) { - succ_elt=new succ_t; - memcpy(succ_elt->id,inmsg+indice,16); + //succ_elt=new succ_t; + memcpy(succ_elt.id,inmsg+indice,16); indice+=16; - memcpy(&(succ_elt->pcontainer),inmsg+indice,2); + memcpy(&(succ_elt.pcontainer),inmsg+indice,2); indice+=2; - memcpy(&(succ_elt->transition),inmsg+indice,2); + memcpy(&(succ_elt.transition),inmsg+indice,2); indice+=2; - succ_elt->_virtual=false; - m_succ.push_back(*succ_elt); - delete succ_elt; + succ_elt._virtual=false; + m_succ.push_back(succ_elt); + // delete succ_elt; } - - if (m_div) { - succ_t el; - el.id[0]='v'; - el.transition=-1; - el._virtual=true; - //cout<<"yep..."<<endl; - m_succ.push_back(el); - } + if (m_deadlock) { succ_t el; el.id[0]='d'; @@ -130,6 +120,17 @@ public: el.transition=-1; m_succ.push_back(el); } + if (m_div) { + /*succ_t el; + el.id[0]='v'; + el.transition=-1; + el._virtual=true; + m_succ.push_back(el);*/ + succ_t el=e; + el._virtual=false; + el.transition=-1; + m_succ.push_back(el); + } } diff --git a/src/MCHybridSOG.cpp b/src/MCHybridSOG.cpp index c7f6fd7e3cd5f0ba8fb155fc4f5463f4b253afaf..8af0f1aa2bf9bdac749e48a9a969c83a5c35ed76 100644 --- a/src/MCHybridSOG.cpp +++ b/src/MCHybridSOG.cpp @@ -61,7 +61,7 @@ MCHybridSOG::MCHybridSOG ( const NewNet &R,MPI_Comm &comm_world,bool init ) liste_marques[i] =it_places->marking; } m_initialMarking=SylvanWrapper::lddmc_cube ( liste_marques,R.places.size() ); - //#ldd_refs_push ( m_initialMarking ); + //SylvanWrapper::lddmc_refs_push( m_initialMarking ); delete []liste_marques; // place names @@ -93,10 +93,10 @@ MCHybridSOG::MCHybridSOG ( const NewNet &R,MPI_Comm &comm_world,bool init ) } MDD _minus=SylvanWrapper::lddmc_cube ( prec,m_nbPlaces ); - //#ldd_refs_push ( _minus ); + //SylvanWrapper::lddmc_refs_push ( _minus ); MDD _plus=SylvanWrapper::lddmc_cube ( postc,m_nbPlaces ); - //#ldd_refs_push ( _plus ); + // SylvanWrapper::lddmc_refs_push ( _plus ); m_tb_relation.push_back ( TransSylvan ( _minus,_plus ) ); } //sylvan_gc_seq(); @@ -130,7 +130,7 @@ void *MCHybridSOG::doCompute() LDDState *c=new LDDState; MDD Complete_meta_state=Accessible_epsilon ( m_initialMarking ); c->m_lddstate=Complete_meta_state; - //#ldd_refs_push ( Complete_meta_state ); + //SylvanWrapper::lddmc_refs_push ( Complete_meta_state ); // MDD reduced_initialstate=Canonize(Complete_meta_state,0); SylvanWrapper::convert_wholemdd_stringcpp ( Complete_meta_state,*chaine ); @@ -229,23 +229,23 @@ void *MCHybridSOG::doCompute() MDD ldd_reachedclass=Accessible_epsilon ( get_successor ( e.first.second,t ) ); - //#ldd_refs_push ( ldd_reachedclass ); + // SylvanWrapper::lddmc_refs_push ( ldd_reachedclass ); - if ( id_thread==1 ) + //if ( id_thread==1 ) { //displayMDDTableInfo(); - if ( SylvanWrapper::isGCRequired() ) { - m_gc_mutex.lock(); -#ifdef DEBUG_GC - - displayMDDTableInfo(); -#endif // DEBUG_GC - // sylvan_gc_seq(); -#ifdef DEBUG_GC - - displayMDDTableInfo(); -#endif // DEBUG_GC - m_gc_mutex.unlock(); - } + //if ( SylvanWrapper::isGCRequired() ) { + // m_gc_mutex.lock(); +//#ifdef DEBUG_GC + + // SylvanWrapper::displayMDDTableInfo(); +//#endif // DEBUG_GC + //SylvanWrapper::sylvan_gc_seq(); +//#ifdef DEBUG_GC + + // SylvanWrapper::displayMDDTableInfo(); +//#endif // DEBUG_GC + //m_gc_mutex.unlock(); + // } //pthread_spin_unlock(&m_spin_md5); @@ -311,7 +311,7 @@ void *MCHybridSOG::doCompute() #ifndef REDUCE reached=Canonize ( ldd_reachedclass,0 ); -//# ldd_refs_push ( ldd_reachedclass ); + // SylvanWrapper::lddmc_refs_push( reached ); #endif //MDD Reduced=ldd_reachedclass; @@ -401,7 +401,7 @@ void *MCHybridSOG::doCompute() } - + // cout<<"Finnnnnn...."<<endl; } diff --git a/src/MCHybridSOG.h b/src/MCHybridSOG.h index db2b5c5a644b2a49db8d9ff361044d553c7714af..0251407e2fda74efca7076dc3db9a578a169e16f 100644 --- a/src/MCHybridSOG.h +++ b/src/MCHybridSOG.h @@ -111,7 +111,7 @@ private: pthread_spinlock_t m_spin_md5; - bool m_Terminated = false; + volatile bool m_Terminated = false; unsigned long m_size_mess = 0; int m_nbsend = 0, m_nbrecv = 0; diff --git a/src/ModelCheckerTh.cpp b/src/ModelCheckerTh.cpp index 2517e0566eb01525a6ee7679df45eb9066d73d3e..80b1db9525a9d035a203384e75645b27995408b2 100644 --- a/src/ModelCheckerTh.cpp +++ b/src/ModelCheckerTh.cpp @@ -145,10 +145,10 @@ void* ModelCheckerTh::Compute_successors() { reached_class = new LDDState(); reached_class->m_lddstate = reduced_meta; //pthread_spin_lock(&m_accessible); - + m_graph_mutex.lock(); LDDState *pos = m_graph->find(reached_class); if (!pos) { - m_graph_mutex.lock(); + 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)); m_graph_mutex.unlock(); @@ -165,7 +165,7 @@ void* ModelCheckerTh::Compute_successors() { m_charge[min_charge]++; } else { //m_graph_mutex.lock(); - m_graph_mutex.lock(); + e.first.first->Successors.insert(e.first.first->Successors.begin(), LDDEdge(pos, t)); pos->Predecessors.insert(pos->Predecessors.begin(), LDDEdge(e.first.first, t)); m_graph_mutex.unlock(); diff --git a/src/SogKripkeIteratorTh.cpp b/src/SogKripkeIteratorTh.cpp index 7b09c764d8bb9a01c1a0467b35acd5ac881d577d..74b7e603255476e2ff2a546b56ddbcae3fd85902 100644 --- a/src/SogKripkeIteratorTh.cpp +++ b/src/SogKripkeIteratorTh.cpp @@ -13,7 +13,7 @@ SogKripkeIteratorTh::SogKripkeIteratorTh ( const LDDState* lddstate, bdd cnd ) : m_lsucc.push_back ( pair<LDDState*,int> ( &m_deadlock,-1 ) ); } if ( lddstate->isDiv() ) { - m_lsucc.push_back ( pair<LDDState*,int> ( &m_div,-1 ) ); + m_lsucc.push_back ( pair<LDDState*,int> ( (LDDState*)lddstate,-1 ) ); } } diff --git a/src/SylvanCacheWrapper.cpp b/src/SylvanCacheWrapper.cpp index 83680b6dde6bf537993236c159faa4a9d3ca8c95..ebade573860194db1e540cdc001d5e63f0d7b5c3 100644 --- a/src/SylvanCacheWrapper.cpp +++ b/src/SylvanCacheWrapper.cpp @@ -133,8 +133,18 @@ int SylvanCacheWrapper::cache_put(uint64_t a, uint64_t b, uint64_t c, uint64_t r return 1; } +void SylvanCacheWrapper::cache_clear() +{ + // a bit silly, but this works just fine, and does not require writing 0 everywhere... + cache_free(); + cache_create(m_cache_size, m_cache_max); +} - +void SylvanCacheWrapper::cache_free() +{ + munmap(m_cache_table, m_cache_max * sizeof(struct cache_entry)); + munmap(m_cache_status, m_cache_max * sizeof(uint32_t)); +} diff --git a/src/SylvanCacheWrapper.h b/src/SylvanCacheWrapper.h index 3502e6dffc3cfea11d28d7d048e7df861c8dc87b..0e651e286432d22f1224c49822ed9ba90cb4f9bb 100644 --- a/src/SylvanCacheWrapper.h +++ b/src/SylvanCacheWrapper.h @@ -74,6 +74,7 @@ public: static int __attribute__((unused)) cache_put3(uint64_t opid, uint64_t dd, uint64_t d2, uint64_t d3, uint64_t res); static int cache_put(uint64_t a, uint64_t b, uint64_t c, uint64_t res); static int cache_get(uint64_t a, uint64_t b, uint64_t c, uint64_t *res); + static void cache_clear(); private: static size_t m_cache_size; // power of 2 static size_t m_cache_max; @@ -81,6 +82,7 @@ private: static uint32_t* m_cache_status; static uint64_t m_next_opid; static uint64_t cache_hash(uint64_t a, uint64_t b, uint64_t c); + static void cache_free(); }; diff --git a/src/SylvanWrapper.cpp b/src/SylvanWrapper.cpp index 7fdfb8e605d032d3cf5e48ceb13fd65d8c791411..77a128120a3eba5614baa37e7dfd60f88e073cb0 100644 --- a/src/SylvanWrapper.cpp +++ b/src/SylvanWrapper.cpp @@ -381,7 +381,6 @@ MDD SylvanWrapper::lddmc_makenode(uint32_t value, MDD ifeq, MDD ifneq) { if (index == 0) { /* lddmc_refs_push(ifeq); lddmc_refs_push(ifneq);*/ - // sylvan_gc();/*********************************************************************************************/ /*lddmc_refs_pop(1);*/ @@ -634,8 +633,8 @@ MDD SylvanWrapper::lddmc_union_mono(MDD a, MDD b) { /* Access cache */ MDD result; - if (SylvanCacheWrapper::cache_get3(CACHE_LDD_UNION, a, b, 0,&result)) { - // std::cout<<"Cache succeeded!"<<std::endl; + if (SylvanCacheWrapper::cache_get3(CACHE_LDD_UNION, a, b, 0, &result)) { + // std::cout<<"Cache succeeded!"<<std::endl; return result; } @@ -745,8 +744,7 @@ MDD SylvanWrapper::ldd_divide_internal(MDD a, int current_level, int level) { if (a == lddmc_true) return lddmc_true; MDD result; - if (SylvanCacheWrapper::cache_get3(CACHE_MDD_DIVIDE, a, current_level, level, &result)) - { + if (SylvanCacheWrapper::cache_get3(CACHE_MDD_DIVIDE, a, current_level, level, &result)) { return result; } @@ -827,9 +825,9 @@ MDD SylvanWrapper::lddmc_firing_mono(MDD cmark, MDD minus, MDD plus) { MDD _cmark = cmark, _minus = minus, _plus = plus; if (SylvanCacheWrapper::cache_get3(CACHE_LDD_FIRE, cmark, minus, plus, &result)) { - return result; + return result; } - MDD cache_cmark=cmark; + MDD cache_cmark = cmark; mddnode_t n_cmark = GETNODE(_cmark); mddnode_t n_plus = GETNODE(_plus); mddnode_t n_minus = GETNODE(_minus); @@ -860,18 +858,16 @@ MDD SylvanWrapper::lddmc_firing_mono(MDD cmark, MDD minus, MDD plus) { } // so: proj: -2 (end; quantify rest), -1 (end; keep rest), 0 (quantify), 1 (keep) -MDD SylvanWrapper::lddmc_project( const MDD mdd, const MDD proj) -{ +MDD SylvanWrapper::lddmc_project(const MDD mdd, const MDD proj) { if (mdd == lddmc_false) return lddmc_false; // projection of empty is empty if (mdd == lddmc_true) return lddmc_true; // projection of universe is universe... mddnode_t p_node = GETNODE(proj); uint32_t p_val = mddnode_getvalue(p_node); - if (p_val == (uint32_t)-1) return mdd; - if (p_val == (uint32_t)-2) return lddmc_true; // because we always end with true. + if (p_val == (uint32_t) -1) return mdd; + if (p_val == (uint32_t) -2) return lddmc_true; // because we always end with true. MDD result; - if (SylvanCacheWrapper::cache_get3(CACHE_MDD_PROJECT, mdd, proj, 0, &result)) - { + if (SylvanCacheWrapper::cache_get3(CACHE_MDD_PROJECT, mdd, proj, 0, &result)) { return result; } @@ -879,9 +875,9 @@ MDD SylvanWrapper::lddmc_project( const MDD mdd, const MDD proj) if (p_val == 1) // keep { - MDD down = lddmc_project( mddnode_getdown(n), mddnode_getdown(p_node)); + MDD down = lddmc_project(mddnode_getdown(n), mddnode_getdown(p_node)); //lddmc_refs_push(down); - // MDD right = lddmc_refs_sync(SYNC(lddmc_project)); + // MDD right = lddmc_refs_sync(SYNC(lddmc_project)); //lddmc_refs_pop(1); result = lddmc_makenode(mddnode_getvalue(n), down, right); } else // quantify @@ -889,16 +885,13 @@ MDD SylvanWrapper::lddmc_project( const MDD mdd, const MDD proj) if (mddnode_getdown(n) == lddmc_true) // assume lowest level { result = lddmc_true; - } - else - { + } else { int count = 0; result = lddmc_false; - MDD p_down = mddnode_getdown(p_node), _mdd=mdd; - while (1) - { + MDD p_down = mddnode_getdown(p_node), _mdd = mdd; + while (1) { //lddmc_refs_spawn(SPAWN(lddmc_project, mddnode_getdown(n), p_down)); - MDD down= lddmc_project (mddnode_getdown(n), p_down); + MDD down = lddmc_project(mddnode_getdown(n), p_down); result = lddmc_union_mono(result, down); count++; _mdd = mddnode_getright(n); @@ -915,57 +908,282 @@ MDD SylvanWrapper::lddmc_project( const MDD mdd, const MDD proj) return result; } -int SylvanWrapper::isGCRequired() -{ - return (m_g_created>llmsset_get_size(m_nodes)/2); +int SylvanWrapper::isGCRequired() { + return (m_g_created > llmsset_get_size(m_nodes) / 2); } -void SylvanWrapper::convert_wholemdd_stringcpp(MDD cmark,string &res) -{ - typedef pair<string,MDD> Pair_stack; +void SylvanWrapper::convert_wholemdd_stringcpp(MDD cmark, string &res) { + typedef pair<string, MDD> Pair_stack; vector<Pair_stack> local_stack; - unsigned int compteur=0; - MDD explore_mdd=cmark; + unsigned int compteur = 0; + MDD explore_mdd = cmark; string chaine; - res=" "; - local_stack.push_back(Pair_stack(chaine,cmark)); - do - { - Pair_stack element=local_stack.back(); - chaine=element.first; - explore_mdd=element.second; + res = " "; + local_stack.push_back(Pair_stack(chaine, cmark)); + do { + Pair_stack element = local_stack.back(); + chaine = element.first; + explore_mdd = element.second; local_stack.pop_back(); compteur++; - while ( explore_mdd!= lddmc_false && explore_mdd!=lddmc_true) - { + while (explore_mdd != lddmc_false && explore_mdd != lddmc_true) { mddnode_t n_val = GETNODE(explore_mdd); - if (mddnode_getright(n_val)!=lddmc_false) - { - local_stack.push_back(Pair_stack(chaine,mddnode_getright(n_val))); + if (mddnode_getright(n_val) != lddmc_false) { + local_stack.push_back(Pair_stack(chaine, mddnode_getright(n_val))); } unsigned int val = mddnode_getvalue(n_val); - chaine.push_back((unsigned char)(val)+1); - explore_mdd=mddnode_getdown(n_val); + chaine.push_back((unsigned char) (val) + 1); + explore_mdd = mddnode_getdown(n_val); } /*printchaine(&chaine);printf("\n");*/ - res+=chaine; - } - while (local_stack.size()!=0); + res += chaine; + } while (local_stack.size() != 0); //delete chaine; - compteur=(compteur<<1) | 1; - res[1]=(unsigned char)((compteur>>8)+1); - res[0]=(unsigned char)(compteur & 255); + compteur = (compteur << 1) | 1; + res[1] = (unsigned char) ((compteur >> 8) + 1); + res[0] = (unsigned char) (compteur & 255); + +} + +void SylvanWrapper::sylvan_gc_seq() { + if (m_g_created > llmsset_get_size(m_nodes) / 1000) { + cout<<"Cache executed"<<endl; + SylvanCacheWrapper::cache_clear(); + llmsset_clear_data(m_nodes); + ldd_gc_mark_protected(); + llmsset_destroy_unmarked(m_nodes); + sylvan_rehash_all(); + m_g_created = seq_llmsset_count_marked(m_nodes); + } +} + +void SylvanWrapper::sylvan_rehash_all() +{ + // clear hash array + llmsset_clear_hashes_seq(m_nodes); + + // rehash marked nodes + if (llmsset_rehash_seq(m_nodes) != 0) { + fprintf(stderr, "sylvan_gc_rehash error: not all nodes could be rehashed!\n"); + exit(1); + } } +int SylvanWrapper::llmsset_rehash_seq (llmsset2_t dbs) +{ + return llmsset_rehash_par_seq( dbs, 0, dbs->table_size); +} + +int SylvanWrapper::llmsset_rehash_par_seq(llmsset2_t dbs, size_t first, size_t count) +{ + if (count > 512) { + int bad = llmsset_rehash_par_seq(dbs, first + count/2, count - count/2); + return bad + llmsset_rehash_par_seq(dbs, first, count/2); + } else { + int bad = 0; + uint64_t *ptr = dbs->bitmap2 + (first / 64); + uint64_t mask = 0x8000000000000000LL >> (first & 63); + for (size_t k=0; k<count; k++) { + if (*ptr & mask) { + if (llmsset_rehash_bucket(dbs, first+k) == 0) bad++; + } + mask >>= 1; + if (mask == 0) { + ptr++; + mask = 0x8000000000000000LL; + } + } + return bad; + } +} + + +int SylvanWrapper::llmsset_rehash_bucket(const llmsset2_t dbs, uint64_t d_idx) +{ + const uint64_t * const d_ptr = ((uint64_t*)dbs->data) + 2*d_idx; + const uint64_t a = d_ptr[0]; + const uint64_t b = d_ptr[1]; + + uint64_t hash_rehash = 14695981039346656037LLU; + const int custom = is_custom_bucket(dbs, d_idx) ? 1 : 0; + if (custom) hash_rehash = dbs->hash_cb(a, b, hash_rehash); + else hash_rehash = llmsset_hash(a, b, hash_rehash); + const uint64_t step = (((hash_rehash >> 20) | 1) << 3); + const uint64_t new_v = (hash_rehash & MASK_HASH) | d_idx; + int i=0; + + uint64_t idx, last; +#if LLMSSET_MASK + last = idx = hash_rehash & dbs->mask; +#else + last = idx = hash_rehash % dbs->table_size; +#endif + + for (;;) { + volatile uint64_t *bucket = &dbs->table[idx]; + if (*bucket == 0 && cas(bucket, 0, new_v)) return 1; + + // find next idx on probe sequence + idx = (idx & CL_MASK) | ((idx+1) & CL_MASK_R); + if (idx == last) { + if (++i == *(volatile int16_t*)&dbs->threshold) { + // failed to find empty spot in probe sequence + // solution: increase probe sequence length... + __sync_fetch_and_add(&dbs->threshold, 1); + } + + // go to next cache line in probe sequence + hash_rehash += step; + +#if LLMSSET_MASK + last = idx = hash_rehash & dbs->mask; +#else + last = idx = hash_rehash % dbs->table_size; +#endif + } + } +} + + +int SylvanWrapper::is_custom_bucket(const llmsset2_t dbs, uint64_t index) +{ + uint64_t *ptr = dbs->bitmapc + (index/64); + uint64_t mask = 0x8000000000000000LL >> (index&63); + return (*ptr & mask) ? 1 : 0; +} + + + + + + +void SylvanWrapper::llmsset_clear_hashes_seq( llmsset2_t dbs) +{ + // just reallocate... + if (mmap(dbs->table, dbs->max_size * 8, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != (void*)-1) { +#if defined(madvise) && defined(MADV_RANDOM) + madvise(dbs->table, sizeof(uint64_t[dbs->max_size]), MADV_RANDOM); +#endif + } else { + // reallocate failed... expensive fallback + memset(dbs->table, 0, dbs->max_size * 8); + } +} + + + +void SylvanWrapper::llmsset_destroy_unmarked(llmsset2_t dbs) { + if (dbs->destroy_cb == NULL) return; // no custom function + llmsset_destroy(dbs, 0, dbs->table_size); +} + +void SylvanWrapper::llmsset_destroy(llmsset2_t dbs, size_t first, size_t count) { + if (count > 1024) { + size_t split = count / 2; + llmsset_destroy(dbs, first, split); + llmsset_destroy(dbs, first + split, count - split); + + } else { + for (size_t k = first; k < first + count; k++) { + volatile uint64_t *ptr2 = dbs->bitmap2 + (k / 64); + volatile uint64_t *ptrc = dbs->bitmapc + (k / 64); + uint64_t mask = 0x8000000000000000LL >> (k & 63); + +// if not marked but is custom + if ((*ptr2 & mask) == 0 && (*ptrc & mask)) { + uint64_t *d_ptr = ((uint64_t *) dbs->data) + 2 * k; + dbs->destroy_cb(d_ptr[0], d_ptr[1]); + *ptrc &= ~mask; + } + } + } +} + + +void SylvanWrapper::llmsset_clear_data(llmsset2_t dbs) { + if (mmap(dbs->bitmap1, dbs->max_size / (512 * 8), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, 0) != (void *) -1) { + + } else { + + memset(dbs->bitmap1, 0, dbs->max_size / (512 * 8)); + } + + if (mmap(dbs->bitmap2, dbs->max_size / 8, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != + (void *) -1) { + + } else { + memset(dbs->bitmap2, 0, dbs->max_size / 8); + + } + + // forbid first two positions (index 0 and 1) + dbs->bitmap2[0] = 0xc000000000000000LL; + /*LACE_ME; + TOGETHER(llmsset_reset_region);*/ +} + +void SylvanWrapper::ldd_gc_mark_protected() { + ldd_refs_mark_p_par(m_sequentiel_refs->pbegin, m_sequentiel_refs->pcur - m_sequentiel_refs->pbegin); + ldd_refs_mark_r_par(m_sequentiel_refs->rbegin, m_sequentiel_refs->rcur - m_sequentiel_refs->rbegin); +} + +void SylvanWrapper::ldd_refs_mark_r_par(MDD *begin, size_t count) { + if (count < 32) { + while (count) { + ldd_gc_mark_rec(*begin++); + count--; + } + } else { + ldd_refs_mark_r_par(begin, count / 2); + ldd_refs_mark_r_par(begin + (count / 2), count - count / 2); + + } +} + + +void SylvanWrapper::ldd_refs_mark_p_par(const MDD **begin, size_t count) { + if (count < 32) { + while (count) { + ldd_gc_mark_rec(**(begin++)); + count--; + } + } else { + ldd_refs_mark_p_par(begin, count / 2); + ldd_refs_mark_p_par(begin + (count / 2), count - count / 2); + + } +} + +void SylvanWrapper::ldd_gc_mark_rec(MDD mdd) { + if (mdd <= lddmc_true) return; + + if (llmsset_mark(m_nodes, mdd)) { + mddnode_t n = LDD_GETNODE(mdd); + ldd_gc_mark_rec(mddnode_getright(n)); + ldd_gc_mark_rec(mddnode_getdown(n)); + + } +} + +int SylvanWrapper::llmsset_mark(const llmsset2_t dbs, uint64_t index) { + volatile uint64_t *ptr = dbs->bitmap2 + (index / 64); + uint64_t mask = 0x8000000000000000LL >> (index & 63); + for (;;) { + uint64_t v = *ptr; + if (v & mask) return 0; + if (cas(ptr, v, v | mask)) return 1; + } +} size_t SylvanWrapper::m_table_min = 0; diff --git a/src/SylvanWrapper.h b/src/SylvanWrapper.h index 8251052cc87d87b02f2a97d0ccd700c5c45aa8c5..97aeb28dbe46a65304c5679d6e6e5714105efb4e 100644 --- a/src/SylvanWrapper.h +++ b/src/SylvanWrapper.h @@ -240,7 +240,24 @@ public: static MDD lddmc_project( const MDD mdd, const MDD proj); static int isGCRequired(); static void convert_wholemdd_stringcpp(MDD cmark,std::string &res); + static void sylvan_gc_seq(); private: + static int is_custom_bucket(const llmsset2_t dbs, uint64_t index); + static int llmsset_rehash_bucket(const llmsset2_t dbs, uint64_t d_idx); + static int llmsset_rehash_seq (llmsset2_t dbs); + static int llmsset_rehash_par_seq(llmsset2_t dbs, size_t first, size_t count); + static void llmsset_clear_hashes_seq( llmsset2_t dbs); + static void sylvan_rehash_all(); + static void llmsset_destroy(llmsset2_t dbs, size_t first, size_t count); + static void llmsset_destroy_unmarked( llmsset2_t dbs); + static void llmsset_clear_data(llmsset2_t dbs); + static void ldd_gc_mark_protected(); + static void ldd_refs_mark_p_par( const MDD** begin, size_t count); + static void ldd_gc_mark_rec(MDD mdd); + static int llmsset_mark(const llmsset2_t dbs, uint64_t index); + static void ldd_refs_mark_r_par( MDD* begin, size_t count); + + static llmsset2_t m_nodes; static size_t m_table_min, m_table_max, m_cache_min, m_cache_max; static volatile int m_gc; @@ -255,6 +272,8 @@ private: static uint32_t m_g_created; + + }; diff --git a/src/main.cpp b/src/main.cpp index 87dc1b30a3d496d632a3229d820dcf2fbb5c3021..c0948776fb20e0b77aff46c7bee8d21d5d1b86ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -382,6 +382,7 @@ int main(int argc, char **argv) { }*/ } } - MPI_Finalize(); + MPI_Finalize(); + exit(0); return (EXIT_SUCCESS); }