-/* Copyright (c) 2010, 2013-2017. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2010-2017. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#ifndef SMPI_KEYVALS_HPP_INCLUDED
#define SMPI_KEYVALS_HPP_INCLUDED
-#include "private.h"
-#include <unordered_map>
-#include <xbt/ex.hpp>
-
-namespace simgrid{
-namespace smpi{
+#include "smpi/smpi.h"
+#include "xbt/ex.hpp"
+#include <unordered_map>
-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;
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<int, void*> attributes_;
+ protected:
+ std::unordered_map<int, void*>* attributes();
public:
// Each subclass should have two members, as we want to separate the ones for Win, Comm, and Datatypes :
// static std::unordered_map<int, smpi_key_elem> keyvals_;
template <typename T> int attr_get(int keyval, void* attr_value, int* flag);
template <typename T> int attr_put(int keyval, void* attr_value);
template <typename T> static int call_deleter(T* obj, smpi_key_elem elem, int keyval, void * value, int* flag);
+ template <typename T> void cleanup_attr();
};
template <typename T> int Keyval::keyval_create(smpi_copy_fn copy_fn, smpi_delete_fn delete_fn, int* keyval, void* extra_state){
return MPI_SUCCESS;
}
-//specialized in smpi_keyvals.cpp
-template <typename T> int Keyval::call_deleter(T* obj, smpi_key_elem elem, int keyval, void * value, int* flag){
- return MPI_SUCCESS;
-}
-
template <typename T> 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<T>(keyval, &value, &flag)==MPI_SUCCESS){
int ret = call_deleter<T>((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;
}
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<void**>(attr_value) = attributes_.at(keyval);
+ *static_cast<void**>(attr_value) = attributes()->at(keyval);
*flag=1;
}
catch (const std::out_of_range& oor) {
return MPI_ERR_ARG;
elem->refcount++;
void * value = nullptr;
- int flag;
+ int flag=0;
this->attr_get<T>(keyval, &value, &flag);
if(flag!=0){
int ret = call_deleter<T>((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 <typename T> void Keyval::cleanup_attr(){
+ if (not 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>((T*)this, elem, it.first,it.second,&flag);
+ }
+ }catch(const std::out_of_range& oor) {
+ //already deleted, not a problem;
+ flag=0;
+ }
+ }
+ }
+}
+
}
}