35 #define DAL_STORED_OBJECT_DEBUG_NOISY 2 
   37 #if DAL_STORED_OBJECT_DEBUG 
   39   static bool dal_static_stored_tab_valid__ = 
true;
 
   41   #define STORED_ASSERT(test, message) GMM_ASSERT1(test, message); 
   42   #define ON_STORED_DEBUG(expression) expression; 
   44   static std::map <const static_stored_object *, std::string> _created_objects;
 
   45   static std::map <const static_stored_object *, std::string> _added_objects;
 
   46   static std::map <const static_stored_object *, std::string> _deleted_objects;
 
   49   void stored_debug_created(
const static_stored_object *o,
 
   50                             const std::string &name) {
 
   51     if (dal_static_stored_tab_valid__) {
 
   52       _created_objects[o] = name;
 
   53 #   if DAL_STORED_OBJECT_DEBUG_NOISY > 1 
   54       cout << 
"Created " << name << 
" : " << o << endl;
 
   58   void stored_debug_added(
const static_stored_object *o) {
 
   59     if (dal_static_stored_tab_valid__) {
 
   60       auto it = _created_objects.find(o);
 
   61       if (it == _created_objects.end()) {
 
   62         _added_objects[o] = 
"";
 
   63 #   if DAL_STORED_OBJECT_DEBUG_NOISY > 0 
   64         cout << 
"Adding an unknown object " << o << 
" of type " 
   65              << 
typeid(*o).name() << 
" add DAL_STORED_OBJECT_DEBUG_CREATED" 
   66           "(o, name)  in its constructor" << endl;
 
   69         _added_objects[o] = it->second;
 
   70         _created_objects.erase(it);
 
   71 #   if DAL_STORED_OBJECT_DEBUG_NOISY > 1 
   72         cout << 
"Added " << it->second << 
" : " << o << endl;
 
   75       if (_deleted_objects.size()) {
 
   76         cout << endl << 
"Number of stored objects: " << _added_objects.size()
 
   77              << endl << 
"Number of unstored created objects: " 
   78              << _created_objects.size() << endl
 
   79              << 
"Number of undestroyed object: " 
   80              << _deleted_objects.size() << endl;
 
   81         for (
auto &x : _deleted_objects)
 
   82           cout << 
"UNDESTROYED OBJECT " << x.second << 
" : " << x.first << endl;
 
   87   void stored_debug_deleted(
const static_stored_object *o) {
 
   88     if (dal_static_stored_tab_valid__) {
 
   89       auto it = _added_objects.find(o);
 
   90       if (it == _added_objects.end()) {
 
   91         cout << 
"Deleting an unknown object ! " << o << endl;
 
   92         _deleted_objects[o] = 
"";
 
   94         _deleted_objects[o] = it->second;
 
   95         _added_objects.erase(it);
 
   96 #   if DAL_STORED_OBJECT_DEBUG_NOISY > 1 
   97         cout << 
"Deleted " << it->second << 
" : " << o << endl;
 
  103   void stored_debug_destroyed(
const static_stored_object *o,
 
  104                               const std::string &name) {
 
  105     if (dal_static_stored_tab_valid__) {
 
  106       auto it = _deleted_objects.find(o);
 
  107       if (it == _deleted_objects.end()) {
 
  108         it = _created_objects.find(o);
 
  109         if (it == _created_objects.end()) {
 
  110           it = _added_objects.find(o);
 
  111           if (it == _added_objects.end()) {
 
  112             cout << 
"Destroy an unknown object ! " << o << 
" name given : " 
  115             _added_objects.erase(it);
 
  116             cout << 
"Destroy a non deleted object !! " << o << 
" name given : " 
  120 #   if DAL_STORED_OBJECT_DEBUG_NOISY > 1 
  121           cout << 
"Destroy an unadded object " << it->second << 
" : " 
  124           _created_objects.erase(it);
 
  127 #   if DAL_STORED_OBJECT_DEBUG_NOISY > 1 
  128         cout << 
"Destroy " << it->second << 
" : " << o << 
" name given : " 
  131         _deleted_objects.erase(it);
 
  138   #define STORED_ASSERT(test, message) 
  139   #define ON_STORED_DEBUG(expression) 
  144   pstatic_stored_object_key key_of_stored_object(pstatic_stored_object o, 
size_t thread){
 
  146     STORED_ASSERT(dal_static_stored_tab_valid__, 
"Too late to do that");
 
  147     auto it = stored_keys.find(o);
 
  148     if (it != stored_keys.end()) 
return it->second;
 
  153   pstatic_stored_object_key key_of_stored_object_other_threads(pstatic_stored_object o){
 
  157       auto key = key_of_stored_object(o,thread);
 
  163   pstatic_stored_object_key key_of_stored_object(pstatic_stored_object o){
 
  167                           key_of_stored_object_other_threads(o) : nullptr;
 
  173     ON_STORED_DEBUG(
if (!dal_static_stored_tab_valid__) 
return false)
 
  174     return  (stored_keys.find(o) != stored_keys.end());
 
  179     ON_STORED_DEBUG(
if (!dal_static_stored_tab_valid__) 
return nullptr)
 
  180     return stored_objects.search_stored_object(k);
 
  183   pstatic_stored_object search_stored_object_on_all_threads(pstatic_stored_object_key k){
 
  185     ON_STORED_DEBUG(
if (!dal_static_stored_tab_valid__) 
return nullptr)
 
  186     auto p = stored_objects.search_stored_object(k);
 
  189     for(
size_t thread = 0; thread < singleton<stored_object_tab>::num_threads(); ++thread){
 
  192       p = other_objects.search_stored_object(k);
 
  198   std::pair<stored_object_tab::iterator, stored_object_tab::iterator>
 
  199     iterators_of_object(pstatic_stored_object o){
 
  202       ON_STORED_DEBUG(
if (!dal_static_stored_tab_valid__) 
continue;)
 
  203       auto it = stored_objects.iterator_of_object_(o);
 
  204       if (it != stored_objects.end()) 
return {it, stored_objects.end()};
 
  214       ON_STORED_DEBUG(
if (!dal_static_stored_tab_valid__) 
continue;)
 
  215       auto& stored_keys = stored_objects.stored_keys_;
 
  217       GMM_ASSERT1(stored_objects.size() == stored_keys.size(),
 
  218                   "keys and objects tables don't match");
 
  219       for (
auto &&pair : stored_keys){
 
  220         auto itos = iterators_of_object(pair.first);
 
  221         GMM_ASSERT1(itos.first != itos.second, 
"Key without object is found");
 
  223       for (
auto &&pair : stored_objects){
 
  224         auto itos = iterators_of_object(pair.second.p);
 
  225         GMM_ASSERT1(itos.first != itos.second, 
"Object has key but cannot be found");
 
  231                       pstatic_stored_object o2) {
 
  232     bool dep_added = 
false;
 
  235       ON_STORED_DEBUG(
if (!dal_static_stored_tab_valid__) 
return)
 
  236       if ((dep_added = stored_objects.add_dependency_(o1,o2))) 
break;
 
  238     GMM_ASSERT1(dep_added, 
"Failed to add dependency between " << o1
 
  239                 << 
" of type " << 
typeid(*o1).name() << 
" and " << o2
 
  240                 << 
" of type "  << 
typeid(*o2).name() << 
". ");
 
  242     bool dependent_added = 
false;
 
  245       if ((dependent_added = stored_objects.add_dependent_(o1,o2))) 
break;
 
  247     GMM_ASSERT1(dependent_added, 
"Failed to add dependent between " << o1
 
  248                 << 
" of type " << 
typeid(*o1).name() << 
" and " << o2
 
  249                 << 
" of type "  << 
typeid(*o2).name() << 
". ");
 
  257     bool dep_deleted = 
false;
 
  260       ON_STORED_DEBUG(
if (!dal_static_stored_tab_valid__) 
return false)
 
  261       if ((dep_deleted = stored_objects.del_dependency_(o1,o2))) 
break;
 
  263     GMM_ASSERT1(dep_deleted, 
"Failed to delete dependency between " << o1 << 
" of type " 
  264                 << 
typeid(*o1).name() << 
" and " << o2 << 
" of type " 
  265                 << 
typeid(*o2).name() << 
". ");
 
  267     bool dependent_deleted = 
false;
 
  268     bool dependent_empty = 
false;
 
  271       dependent_deleted = stored_objects.del_dependent_(o1,o2);
 
  272       if (dependent_deleted){
 
  273         dependent_empty = stored_objects.has_dependent_objects(o2);
 
  277     GMM_ASSERT1(dependent_deleted, 
"Failed to delete dependent between " << o1 << 
" of type " 
  278                 << 
typeid(*o1).name() << 
" and " << o2 << 
" of type " 
  279                 << 
typeid(*o2).name() << 
". ");
 
  281     return dependent_empty;
 
  286     STORED_ASSERT(dal_static_stored_tab_valid__, 
"Too late to add an object");
 
  288     stored_objects.add_stored_object(k,o,perm);
 
  291   void basic_delete(std::list<pstatic_stored_object> &to_delete){
 
  294     ON_STORED_DEBUG(
if (!dal_static_stored_tab_valid__) 
return)
 
  295     stored_objects_this_thread.basic_delete_(to_delete);
 
  297     if (!to_delete.empty()){ 
 
  301         stored_objects.basic_delete_(to_delete);
 
  302         if (to_delete.empty()) 
break;
 
  306         if (!to_delete.empty()) GMM_WARNING1(
"Not all objects were deleted");
 
  308     else{GMM_ASSERT1(to_delete.empty(), 
"Could not delete objects");}
 
  312                           bool ignore_unstored) {
 
  316     ON_STORED_DEBUG(
if (dal_static_stored_tab_valid__) 
return);
 
  318     std::list<pstatic_stored_object>::iterator it, itnext;
 
  319     for (it = to_delete.begin(); it != to_delete.end(); it = itnext) {
 
  320       itnext = it; itnext++;
 
  322       auto itos = iterators_of_object(*it);
 
  323       if (itos.first == itos.second) {
 
  324         if (ignore_unstored) to_delete.erase(it);
 
  326             GMM_WARNING1(
"This object is (already?) not stored : "<< it->get()
 
  327             << 
" typename: " << 
typeid(*it->get()).name()
 
  328             << 
"(which could happen in multithreaded code and is OK)");
 
  330           GMM_ASSERT1(
false, 
"This object is not stored : " << it->get()
 
  331           << 
" typename: " << 
typeid(*it->get()).name());
 
  334       else itos.first->second.valid = 
false;
 
  337     for (
auto &&pobj : to_delete) {
 
  339         auto itos = iterators_of_object(pobj);
 
  340         GMM_ASSERT1(itos.first != itos.second, 
"An object disapeared !");
 
  341         itos.first->second.valid = 
false;
 
  342         auto second_dep = itos.first->second.dependencies;
 
  343         for (
const auto &pdep : second_dep) {
 
  345             auto itods = iterators_of_object(pdep);
 
  346             if (itods.first->second.perm == AUTODELETE_STATIC_OBJECT
 
  347                 && itods.first->second.valid) {
 
  348               itods.first->second.valid = 
false;
 
  349               to_delete.push_back(pdep);
 
  353         for (
auto &&pdep : itos.first->second.dependent_object) {
 
  354           auto itods = iterators_of_object(pdep);
 
  355           if (itods.first != itods.second) {
 
  356             GMM_ASSERT1(itods.first->second.perm != PERMANENT_STATIC_OBJECT,
 
  357             "Trying to delete a permanent object " << pdep);
 
  358             if (itods.first->second.valid) {
 
  359               itods.first->second.valid = 
false;
 
  360               to_delete.push_back(itods.first->second.p);
 
  366     basic_delete(to_delete);
 
  370     std::list<pstatic_stored_object> to_delete;
 
  371     to_delete.push_back(o);
 
  377     std::list<pstatic_stored_object> to_delete;
 
  380       ON_STORED_DEBUG(
if (!dal_static_stored_tab_valid__) 
continue;)
 
  381       if (perm == PERMANENT_STATIC_OBJECT) perm = STRONG_STATIC_OBJECT;
 
  382       for (
auto &&pair : stored_objects){
 
  383         if (pair.second.perm >= perm) to_delete.push_back(pair.second.p);
 
  392       ON_STORED_DEBUG(
if (!dal_static_stored_tab_valid__) 
continue;)
 
  393       if (stored_keys.begin() == stored_keys.end())
 
  394         ost << 
"No static stored objects" << endl;
 
  395       else ost << 
"Static stored objects" << endl;
 
  396       for (
const auto &t : stored_keys)
 
  397         ost << 
"Object: " << t.first << 
" typename: " 
  398             << 
typeid(*(t.first)).name() << endl;
 
  403     long num_objects = 0;
 
  406       ON_STORED_DEBUG(
if (!dal_static_stored_tab_valid__) 
continue;)
 
  407       num_objects += stored_keys.size();
 
  417       locks_{}, stored_keys_{}{
 
  418       ON_STORED_DEBUG(dal_static_stored_tab_valid__ = 
true;)
 
  421   stored_object_tab::~stored_object_tab(){
 
  422     ON_STORED_DEBUG(dal_static_stored_tab_valid__ = 
false;)
 
  425   pstatic_stored_object
 
  426   stored_object_tab::search_stored_object(pstatic_stored_object_key k)
 const{
 
  427     auto guard = locks_.get_lock();
 
  428     auto it = find(enr_static_stored_object_key(k));
 
  429     return (it != end()) ? it->second.p : 
nullptr;
 
  432   bool stored_object_tab::add_dependency_(pstatic_stored_object o1,
 
  433                                           pstatic_stored_object o2){
 
  434     auto guard = locks_.get_lock();
 
  435     auto it = stored_keys_.find(o1);
 
  436     if (it == stored_keys_.end()) 
return false;
 
  437     auto ito1 = find(it->second);
 
  438     GMM_ASSERT1(ito1 != end(), 
"Object has a key, but cannot be found");
 
  439     ito1->second.dependencies.insert(o2);
 
  443   void stored_object_tab::add_stored_object(pstatic_stored_object_key k,
 
  444     pstatic_stored_object o,  permanence perm){
 
  445     DAL_STORED_OBJECT_DEBUG_ADDED(o.get());
 
  446     auto guard = locks_.get_lock();
 
  447     GMM_ASSERT1(stored_keys_.find(o) == stored_keys_.end(),
 
  448       "This object has already been stored, possibly with another key");
 
  450     insert(std::make_pair(enr_static_stored_object_key(k),
 
  451                           enr_static_stored_object(o, perm)));
 
  453     GMM_ASSERT2(stored_keys_.size() == size() && t != 
size_t(-1),
 
  454       "stored_keys are not consistent with stored_object tab");
 
  457   bool stored_object_tab::add_dependent_(pstatic_stored_object o1,
 
  458     pstatic_stored_object o2){
 
  459     auto guard = locks_.get_lock();
 
  460     auto it = stored_keys_.find(o2);
 
  461     if (it == stored_keys_.end()) 
return false;
 
  462     auto ito2 = find(it->second);
 
  463     GMM_ASSERT1(ito2 != end(), 
"Object has a key, but cannot be found");
 
  464     ito2->second.dependent_object.insert(o1);
 
  468   bool stored_object_tab::del_dependency_(pstatic_stored_object o1,
 
  469                                           pstatic_stored_object o2){
 
  470     auto guard = locks_.get_lock();
 
  471     auto it1 = stored_keys_.find(o1);
 
  472     if (it1 == stored_keys_.end()) 
return false;
 
  473     auto ito1 = find(it1->second);
 
  474     GMM_ASSERT1(ito1 != end(), 
"Object has a key, but cannot be found");
 
  475     ito1->second.dependencies.erase(o2);
 
  479   stored_object_tab::iterator stored_object_tab
 
  480     ::iterator_of_object_(pstatic_stored_object o){
 
  481     auto itk = stored_keys_.find(o);
 
  482     if (itk == stored_keys_.end()) 
return end();
 
  483     auto ito = find(itk->second);
 
  484     GMM_ASSERT1(ito != end(), 
"Object has a key, but is not stored");
 
  488   bool stored_object_tab::del_dependent_(pstatic_stored_object o1,
 
  489                                          pstatic_stored_object o2){
 
  490     auto guard = locks_.get_lock();
 
  491     auto it2 = stored_keys_.find(o2);
 
  492     if (it2 == stored_keys_.end()) 
return false;
 
  493     auto ito2 = find(it2->second);
 
  494     GMM_ASSERT1(ito2 != end(), 
"Object has a key, but cannot be found");
 
  495     ito2->second.dependent_object.erase(o1);
 
  499   bool stored_object_tab::exists_stored_object(pstatic_stored_object o)
 const{
 
  500     auto guard = locks_.get_lock();
 
  501     return (stored_keys_.find(o) != stored_keys_.end());
 
  504   bool stored_object_tab::has_dependent_objects(pstatic_stored_object o)
 const{
 
  505     auto guard = locks_.get_lock();
 
  506     auto it = stored_keys_.find(o);
 
  507     GMM_ASSERT1(it != stored_keys_.end(), 
"Object is not stored");
 
  508     auto ito = find(it->second);
 
  509     GMM_ASSERT1(ito != end(), 
"Object has a key, but cannot be found");
 
  510     return ito->second.dependent_object.empty();
 
  513   void stored_object_tab::basic_delete_(std::list<pstatic_stored_object> &to_delete){
 
  514     auto guard = locks_.get_lock();
 
  515     for (
auto it = to_delete.begin(); it != to_delete.end();){
 
  516       DAL_STORED_OBJECT_DEBUG_DELETED(it->get());
 
  517       auto itk = stored_keys_.find(*it);
 
  519       if (itk != stored_keys_.end()){
 
  520           ito = find(itk->second);
 
  521           stored_keys_.erase(itk);
 
  525         it = to_delete.erase(it);
 
static size_type this_thread()
this thread number according to the threading policy of the singleton
 
static T & instance()
Instance from the current thread.
 
static size_type num_threads()
number of threads this singleton is distributed on.
 
A simple singleton implementation.
 
Stores interdependent getfem objects.
 
void del_stored_objects(std::list< pstatic_stored_object > &to_delete, bool ignore_unstored)
Delete a list of objects and their dependencies.
 
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
 
void test_stored_objects(void)
Test the validity of the whole global storage.
 
void add_dependency(pstatic_stored_object o1, pstatic_stored_object o2)
Add a dependency, object o1 will depend on object o2.
 
bool del_dependency(pstatic_stored_object o1, pstatic_stored_object o2)
remove a dependency.
 
size_t nb_stored_objects(void)
Return the number of stored objects (for debugging purpose).
 
void list_stored_objects(std::ostream &ost)
Show a list of stored objects (for debugging purpose).
 
void del_stored_object(const pstatic_stored_object &o, bool ignore_unstored)
Delete an object and the object which depend on it.
 
pstatic_stored_object search_stored_object(pstatic_stored_object_key k)
Gives a pointer to an object from a key pointer.
 
bool exists_stored_object(pstatic_stored_object o)
Test if an object is stored.
 
bool me_is_multithreaded_now()
is the program running in the parallel section
 
Pointer to a key with a coherent order.
 
Pointer to an object with the dependencies.
 
stored_object_tab()
STATIC_STORED_TAB ----------------------------------------------------—.