35 #define DAL_STORED_OBJECT_DEBUG_NOISY 2 37 static bool dal_static_stored_tab_valid__ =
true;
39 #if DAL_STORED_OBJECT_DEBUG 40 static std::map <const static_stored_object *, std::string> _created_objects;
41 static std::map <const static_stored_object *, std::string> _added_objects;
42 static std::map <const static_stored_object *, std::string> _deleted_objects;
45 void stored_debug_created(
const static_stored_object *o,
46 const std::string &name) {
47 if (dal_static_stored_tab_valid__) {
48 _created_objects[o] = name;
49 # if DAL_STORED_OBJECT_DEBUG_NOISY > 1 50 cout <<
"Created " << name <<
" : " << o << endl;
54 void stored_debug_added(
const static_stored_object *o) {
55 if (dal_static_stored_tab_valid__) {
56 auto it = _created_objects.find(o);
57 if (it == _created_objects.end()) {
58 _added_objects[o] =
"";
59 # if DAL_STORED_OBJECT_DEBUG_NOISY > 0 60 cout <<
"Adding an unknown object " << o <<
" of type " 61 <<
typeid(*o).name() <<
" add DAL_STORED_OBJECT_DEBUG_CREATED" 62 "(o, name) in its constructor" << endl;
65 _added_objects[o] = it->second;
66 _created_objects.erase(it);
67 # if DAL_STORED_OBJECT_DEBUG_NOISY > 1 68 cout <<
"Added " << it->second <<
" : " << o << endl;
71 if (_deleted_objects.size()) {
72 cout << endl <<
"Number of stored objects: " << _added_objects.size()
73 << endl <<
"Number of unstored created objects: " 74 << _created_objects.size() << endl
75 <<
"Number of undestroyed object: " 76 << _deleted_objects.size() << endl;
77 for (
auto &x : _deleted_objects)
78 cout <<
"UNDESTROYED OBJECT " << x.second <<
" : " << x.first << endl;
83 void stored_debug_deleted(
const static_stored_object *o) {
84 if (dal_static_stored_tab_valid__) {
85 auto it = _added_objects.find(o);
86 if (it == _added_objects.end()) {
87 cout <<
"Deleting an unknown object ! " << o << endl;
88 _deleted_objects[o] =
"";
90 _deleted_objects[o] = it->second;
91 _added_objects.erase(it);
92 # if DAL_STORED_OBJECT_DEBUG_NOISY > 1 93 cout <<
"Deleted " << it->second <<
" : " << o << endl;
99 void stored_debug_destroyed(
const static_stored_object *o,
100 const std::string &name) {
101 if (dal_static_stored_tab_valid__) {
102 auto it = _deleted_objects.find(o);
103 if (it == _deleted_objects.end()) {
104 it = _created_objects.find(o);
105 if (it == _created_objects.end()) {
106 it = _added_objects.find(o);
107 if (it == _added_objects.end()) {
108 cout <<
"Destroy an unknown object ! " << o <<
" name given : " 111 _added_objects.erase(it);
112 cout <<
"Destroy a non deleted object !! " << o <<
" name given : " 116 # if DAL_STORED_OBJECT_DEBUG_NOISY > 1 117 cout <<
"Destroy an unadded object " << it->second <<
" : " 120 _created_objects.erase(it);
123 # if DAL_STORED_OBJECT_DEBUG_NOISY > 1 124 cout <<
"Destroy " << it->second <<
" : " << o <<
" name given : " 127 _deleted_objects.erase(it);
143 pstatic_stored_object_key key_of_stored_object(pstatic_stored_object o,
size_t thread)
145 stored_object_tab::stored_key_tab& stored_keys
147 GMM_ASSERT1(dal_static_stored_tab_valid__,
"Too late to do that");
148 stored_object_tab::stored_key_tab::iterator it = stored_keys.find(o);
149 if (it != stored_keys.end())
return it->second;
154 pstatic_stored_object_key key_of_stored_object_other_threads(pstatic_stored_object o)
156 for(
size_t thread = 0; thread<getfem::num_threads();thread++)
158 if (thread == this_thread())
continue;
159 pstatic_stored_object_key key = key_of_stored_object(o,thread);
165 pstatic_stored_object_key key_of_stored_object(pstatic_stored_object o)
167 pstatic_stored_object_key key = key_of_stored_object(o,this_thread());
169 else return (num_threads() > 1) ? key_of_stored_object_other_threads(o) : 0;
175 stored_object_tab::stored_key_tab& stored_keys
177 if (dal_static_stored_tab_valid__) {
178 return (stored_keys.find(o) != stored_keys.end());
187 if (dal_static_stored_tab_valid__) {
188 pstatic_stored_object p = stored_objects.search_stored_object(k);
194 std::pair<stored_object_tab::iterator, stored_object_tab::iterator> iterators_of_object(
195 pstatic_stored_object o)
197 for(
size_t thread=0; thread < num_threads(); ++thread)
201 if (!dal_static_stored_tab_valid__)
continue;
202 stored_object_tab::iterator it = stored_objects.iterator_of_object_(o);
203 if (it != stored_objects.end())
return {it, stored_objects.end()};
212 for(
size_t thread = 0; thread < num_threads(); ++thread)
216 if (!dal_static_stored_tab_valid__)
continue;
217 stored_object_tab::stored_key_tab& stored_keys = stored_objects.stored_keys_;
219 GMM_ASSERT1(stored_objects.size() == stored_keys.size(),
220 "keys and objects tables don't match");
221 for (stored_object_tab::stored_key_tab::iterator it = stored_keys.begin();
222 it != stored_keys.end(); ++it)
224 auto itos = iterators_of_object(it->first);
225 GMM_ASSERT1(itos.first != itos.second,
"Key without object is found");
227 for (stored_object_tab::iterator it = stored_objects.begin();
228 it != stored_objects.end(); ++it)
230 auto itos = iterators_of_object(it->second.p);
231 GMM_ASSERT1(itos.first != itos.second,
"Object has key but cannot be found");
237 pstatic_stored_object o2) {
238 bool dep_added =
false;
239 for(
size_t thread=0; thread < num_threads(); ++thread)
243 if (!dal_static_stored_tab_valid__)
return;
244 if ((dep_added = stored_objects.add_dependency_(o1,o2)))
break;
246 GMM_ASSERT1(dep_added,
"Failed to add dependency between " << o1
247 <<
" of type " <<
typeid(*o1).name() <<
" and " << o2
248 <<
" of type " <<
typeid(*o2).name() <<
". ");
250 bool dependent_added =
false;
251 for(
size_t thread=0; thread < num_threads(); ++thread)
255 if ((dependent_added = stored_objects.add_dependent_(o1,o2)))
break;
257 GMM_ASSERT1(dependent_added,
"Failed to add dependent between " << o1
258 <<
" of type " <<
typeid(*o1).name() <<
" and " << o2
259 <<
" of type " <<
typeid(*o2).name() <<
". ");
267 pstatic_stored_object o2)
269 bool dep_deleted =
false;
270 for(
size_t thread=0; thread < num_threads(); ++thread)
274 if (!dal_static_stored_tab_valid__)
return false;
275 if ((dep_deleted = stored_objects.del_dependency_(o1,o2)))
break;
277 GMM_ASSERT1(dep_deleted,
"Failed to delete dependency between " << o1 <<
" of type " 278 <<
typeid(*o1).name() <<
" and " << o2 <<
" of type " <<
typeid(*o2).name() <<
". ");
280 bool dependent_deleted =
false;
281 bool dependent_empty =
false;
282 for(
size_t thread=0; thread < num_threads(); ++thread)
286 dependent_deleted = stored_objects.del_dependent_(o1,o2);
287 if (dependent_deleted)
289 dependent_empty = stored_objects.has_dependent_objects(o2);
293 GMM_ASSERT1(dependent_deleted,
"Failed to delete dependent between " << o1 <<
" of type " 294 <<
typeid(*o1).name() <<
" and " << o2 <<
" of type " <<
typeid(*o2).name() <<
". ");
296 return dependent_empty;
302 GMM_ASSERT1(dal_static_stored_tab_valid__,
"Too late to add an object");
305 if (dal_static_stored_tab_valid__)
306 stored_objects.add_stored_object(k,o,perm);
309 void basic_delete(std::list<pstatic_stored_object> &to_delete) {
313 if (dal_static_stored_tab_valid__) {
315 stored_objects_this_thread.basic_delete_(to_delete);
317 if (!to_delete.empty())
319 for(
size_t thread=0; thread < num_threads(); ++thread)
321 if (thread == this_thread())
continue;
324 stored_objects.basic_delete_(to_delete);
325 if (to_delete.empty())
break;
328 if (me_is_multithreaded_now())
330 if (!to_delete.empty()) GMM_WARNING1(
"Not all objects were deleted");
334 GMM_ASSERT1(to_delete.empty(),
"Could not delete objects");
340 bool ignore_unstored)
342 getfem::omp_guard lock;
343 GMM_NOPERATION(lock);
347 if (dal_static_stored_tab_valid__) {
349 std::list<pstatic_stored_object>::iterator it, itnext;
350 for (it = to_delete.begin(); it != to_delete.end(); it = itnext) {
351 itnext = it; itnext++;
353 auto itos = iterators_of_object(*it);
354 if (itos.first == itos.second) {
358 if (me_is_multithreaded_now()) {
359 GMM_WARNING1(
"This object is (already?) not stored : "<< it->get()
360 <<
" typename: " <<
typeid(*it->get()).name()
361 <<
"(which could happen in multithreaded code and is OK)");
363 GMM_ASSERT1(
false,
"This object is not stored : " << it->get()
364 <<
" typename: " <<
typeid(*it->get()).name());
368 itos.first->second.valid =
false;
371 for (pstatic_stored_object pobj : to_delete) {
373 auto itos = iterators_of_object(pobj);
374 GMM_ASSERT1(itos.first != itos.second,
"An object disapeared !");
375 itos.first->second.valid =
false;
376 auto second_dep = itos.first->second.dependencies;
377 for (
const pstatic_stored_object pdep : second_dep) {
379 auto itods = iterators_of_object(pdep);
380 if (itods.first->second.perm == AUTODELETE_STATIC_OBJECT
381 && itods.first->second.valid) {
382 itods.first->second.valid =
false;
383 to_delete.push_back(pdep);
387 for (pstatic_stored_object
388 pdep : itos.first->second.dependent_object) {
389 auto itods = iterators_of_object(pdep);
390 if (itods.first != itods.second) {
391 GMM_ASSERT1(itods.first->second.perm != PERMANENT_STATIC_OBJECT,
392 "Trying to delete a permanent object " << pdep);
393 if (itods.first->second.valid) {
394 itods.first->second.valid =
false;
395 to_delete.push_back(itods.first->second.p);
401 basic_delete(to_delete);
408 std::list<pstatic_stored_object> to_delete;
409 to_delete.push_back(o);
416 std::list<pstatic_stored_object> to_delete;
417 for(
size_t thread=0; thread<getfem::num_threads();thread++)
421 if (!dal_static_stored_tab_valid__)
continue;
422 if (perm == PERMANENT_STATIC_OBJECT) perm = STRONG_STATIC_OBJECT;
423 stored_object_tab::iterator it;
424 for (it = stored_objects.begin(); it != stored_objects.end(); ++it)
425 if (it->second.perm >= perm)
426 to_delete.push_back(it->second.p);
433 for(
size_t thread=0; thread<getfem::num_threads();thread++)
435 stored_object_tab::stored_key_tab& stored_keys
437 if (!dal_static_stored_tab_valid__)
continue;
438 if (stored_keys.begin() == stored_keys.end())
439 ost <<
"No static stored objects" << endl;
440 else ost <<
"Static stored objects" << endl;
441 for (
const auto &t : stored_keys)
442 ost <<
"Object: " << t.first <<
" typename: " 443 <<
typeid(*(t.first)).name() << endl;
450 for(
size_t thread=0;thread<getfem::num_threads(); ++thread)
452 stored_object_tab::stored_key_tab& stored_keys
454 if (!dal_static_stored_tab_valid__)
continue;
455 num_objects+=stored_keys.size();
468 locks_(), stored_keys_()
469 { dal_static_stored_tab_valid__ =
true; }
471 stored_object_tab::~stored_object_tab()
472 { dal_static_stored_tab_valid__ =
false; }
474 pstatic_stored_object
475 stored_object_tab::search_stored_object(pstatic_stored_object_key k)
const 477 getfem::local_guard guard = locks_.get_lock();
479 return (it != end()) ? it->second.p : 0;
482 bool stored_object_tab::add_dependency_(pstatic_stored_object o1,
483 pstatic_stored_object o2)
485 getfem::local_guard guard = locks_.get_lock();
486 stored_key_tab::const_iterator it = stored_keys_.find(o1);
487 if (it == stored_keys_.end())
return false;
488 iterator ito1 = find(it->second);
489 GMM_ASSERT1(ito1 != end(),
"Object has a key, but cannot be found");
490 ito1->second.dependencies.insert(o2);
494 void stored_object_tab::add_stored_object(pstatic_stored_object_key k,
495 pstatic_stored_object o, permanence perm)
497 DAL_STORED_OBJECT_DEBUG_ADDED(o.get());
498 getfem::local_guard guard = locks_.get_lock();
499 GMM_ASSERT1(stored_keys_.find(o) == stored_keys_.end(),
500 "This object has already been stored, possibly with another key");
504 size_t t = this_thread();
505 GMM_ASSERT2(stored_keys_.size() == size() && t != size_t(-1),
506 "stored_keys are not consistent with stored_object tab");
509 bool stored_object_tab::add_dependent_(pstatic_stored_object o1,
510 pstatic_stored_object o2)
512 getfem::local_guard guard = locks_.get_lock();
513 stored_key_tab::const_iterator it = stored_keys_.find(o2);
514 if (it == stored_keys_.end())
return false;
515 iterator ito2 = find(it->second);
516 GMM_ASSERT1(ito2 != end(),
"Object has a key, but cannot be found");
517 ito2->second.dependent_object.insert(o1);
521 bool stored_object_tab::del_dependency_(pstatic_stored_object o1,
522 pstatic_stored_object o2)
524 getfem::local_guard guard = locks_.get_lock();
525 stored_key_tab::const_iterator it1 = stored_keys_.find(o1);
526 if (it1 == stored_keys_.end())
return false;
527 iterator ito1 = find(it1->second);
528 GMM_ASSERT1(ito1 != end(),
"Object has a key, but cannot be found");
529 ito1->second.dependencies.erase(o2);
533 stored_object_tab::iterator stored_object_tab::iterator_of_object_(pstatic_stored_object o)
535 stored_key_tab::const_iterator itk = stored_keys_.find(o);
536 if (itk == stored_keys_.end())
return end();
537 iterator ito = find(itk->second);
538 GMM_ASSERT1(ito != end(),
"Object has a key, but is not stored");
542 bool stored_object_tab::del_dependent_(pstatic_stored_object o1,
543 pstatic_stored_object o2)
545 getfem::local_guard guard = locks_.get_lock();
546 stored_key_tab::const_iterator it2 = stored_keys_.find(o2);
547 if (it2 == stored_keys_.end())
return false;
548 iterator ito2 = find(it2->second);
549 GMM_ASSERT1(ito2 != end(),
"Object has a key, but cannot be found");
550 ito2->second.dependent_object.erase(o1);
554 bool stored_object_tab::exists_stored_object(pstatic_stored_object o)
const 556 getfem::local_guard guard = locks_.get_lock();
557 return (stored_keys_.find(o) != stored_keys_.end());
560 bool stored_object_tab::has_dependent_objects(pstatic_stored_object o)
const 562 getfem::local_guard guard = locks_.get_lock();
563 stored_key_tab::const_iterator it = stored_keys_.find(o);
564 GMM_ASSERT1(it != stored_keys_.end(),
"Object is not stored");
565 const_iterator ito = find(it->second);
566 GMM_ASSERT1(ito != end(),
"Object has a key, but cannot be found");
567 return ito->second.dependent_object.empty();
572 void stored_object_tab::basic_delete_
573 (std::list<pstatic_stored_object> &to_delete)
575 getfem::local_guard guard = locks_.get_lock();
576 std::list<pstatic_stored_object>::iterator it;
577 for (it = to_delete.begin(); it != to_delete.end(); )
579 DAL_STORED_OBJECT_DEBUG_DELETED(it->get());
580 stored_key_tab::iterator itk = stored_keys_.find(*it);
581 stored_object_tab::iterator ito = end();
582 if (itk != stored_keys_.end())
584 ito = find(itk->second);
585 stored_keys_.erase(itk);
590 it = to_delete.erase(it);
Pointer to a key with a coherent order.
void test_stored_objects(void)
Test the validity of the whole global storage.
Stores interdependent getfem objects.
stored_object_tab()
STATIC_STORED_TAB ----------------------------------------------------—.
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.
static T & instance()
Instance from the current thread.
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
A simple singleton implementation.
bool del_dependency(pstatic_stored_object o1, pstatic_stored_object o2)
remove a dependency.
void add_dependency(pstatic_stored_object o1, pstatic_stored_object o2)
Add a dependency, object o1 will depend on object o2.
void del_stored_objects(std::list< pstatic_stored_object > &to_delete, bool ignore_unstored)
Delete a list of objects and their dependencies.
Pointer to an object with the dependencies.
bool exists_stored_object(pstatic_stored_object o)
Test if an object is stored.
size_t nb_stored_objects(void)
Return the number of stored objects (for debugging purpose).