X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/d4f3a012fbbb4484ed74c6cec7b5444ffb15f27f..41846d24bea977a7c671c77cab7c3a2105f65a6c:/src/smpi/smpi_keyvals.hpp diff --git a/src/smpi/smpi_keyvals.hpp b/src/smpi/smpi_keyvals.hpp index 0508f33392..c302a55667 100644 --- a/src/smpi/smpi_keyvals.hpp +++ b/src/smpi/smpi_keyvals.hpp @@ -11,17 +11,13 @@ #include #include -namespace simgrid{ -namespace smpi{ - - -typedef union smpi_delete_fn{ +typedef struct smpi_delete_fn{ MPI_Comm_delete_attr_function *comm_delete_fn; MPI_Type_delete_attr_function *type_delete_fn; MPI_Win_delete_attr_function *win_delete_fn; } smpi_delete_fn; -typedef union smpi_copy_fn{ +typedef struct smpi_copy_fn{ MPI_Comm_copy_attr_function *comm_copy_fn; MPI_Type_copy_attr_function *type_copy_fn; MPI_Win_copy_attr_function *win_copy_fn; @@ -32,11 +28,17 @@ typedef struct s_smpi_key_elem { smpi_delete_fn delete_fn; int refcount; } s_smpi_mpi_key_elem_t; + typedef struct s_smpi_key_elem *smpi_key_elem; +namespace simgrid{ +namespace smpi{ + class Keyval{ - protected: + private: std::unordered_map attributes_; + protected: + std::unordered_map* attributes(); public: // Each subclass should have two members, as we want to separate the ones for Win, Comm, and Datatypes : // static std::unordered_map keyvals_; @@ -47,6 +49,7 @@ class Keyval{ template int attr_get(int keyval, void* attr_value, int* flag); template int attr_put(int keyval, void* attr_value); template static int call_deleter(T* obj, smpi_key_elem elem, int keyval, void * value, int* flag); + template void cleanup_attr(); }; template int Keyval::keyval_create(smpi_copy_fn copy_fn, smpi_delete_fn delete_fn, int* keyval, void* extra_state){ @@ -79,26 +82,21 @@ template int Keyval::keyval_free(int* keyval){ return MPI_SUCCESS; } -//specialized in smpi_keyvals.cpp -template int Keyval::call_deleter(T* obj, smpi_key_elem elem, int keyval, void * value, int* flag){ - return MPI_SUCCESS; -} - template int Keyval::attr_delete(int keyval){ smpi_key_elem elem = T::keyvals_.at(keyval); if(elem==nullptr) return MPI_ERR_ARG; elem->refcount--; void * value = nullptr; - int flag; + int flag=0; if(this->attr_get(keyval, &value, &flag)==MPI_SUCCESS){ int ret = call_deleter((T*)this, elem, keyval,value,&flag); if(ret!=MPI_SUCCESS) return ret; } - if(attributes_.empty()) + if(attributes()->empty()) return MPI_ERR_ARG; - attributes_.erase(keyval); + attributes()->erase(keyval); return MPI_SUCCESS; } @@ -107,12 +105,12 @@ template int Keyval::attr_get(int keyval, void* attr_value, int* fl smpi_key_elem elem = T::keyvals_.at(keyval); if(elem==nullptr) return MPI_ERR_ARG; - if(attributes_.empty()){ + if(attributes()->empty()){ *flag=0; return MPI_SUCCESS; } try { - *static_cast(attr_value) = attributes_.at(keyval); + *static_cast(attr_value) = attributes()->at(keyval); *flag=1; } catch (const std::out_of_range& oor) { @@ -127,17 +125,34 @@ template int Keyval::attr_put(int keyval, void* attr_value){ return MPI_ERR_ARG; elem->refcount++; void * value = nullptr; - int flag; + int flag=0; this->attr_get(keyval, &value, &flag); if(flag!=0){ int ret = call_deleter((T*)this, elem, keyval,value,&flag); if(ret!=MPI_SUCCESS) return ret; } - attributes_.insert({keyval, attr_value}); + attributes()->insert({keyval, attr_value}); return MPI_SUCCESS; } +template void Keyval::cleanup_attr(){ + if(!attributes()->empty()){ + int flag=0; + for(auto it : attributes_){ + try{ + smpi_key_elem elem = T::keyvals_.at(it.first); + if(elem != nullptr){ + call_deleter((T*)this, elem, it.first,it.second,&flag); + } + }catch(const std::out_of_range& oor) { + //already deleted, not a problem; + flag=0; + } + } + } +} + } }