BVB Source Codes

mars Show sp_collector.cpp Source code

Return Download mars: download sp_collector.cpp Source code - Download mars Source code - Type:.cpp
  1. //
  2. //  sp_collector.cpp
  3. //
  4. //  Copyright (c) 2002, 2003 Peter Dimov
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10.  
  11. #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
  12.  
  13. #include <boost/assert.hpp>
  14. #include <boost/shared_ptr.hpp>
  15. #include <boost/detail/lightweight_mutex.hpp>
  16. #include <cstdlib>
  17. #include <map>
  18. #include <deque>
  19. #include <iostream>
  20.  
  21. typedef std::map< void const *, std::pair<void *, size_t> > map_type;
  22.  
  23. static map_type & get_map()
  24. {
  25.     static map_type m;
  26.     return m;
  27. }
  28.  
  29. typedef mars_boost::detail::lightweight_mutex mutex_type;
  30.  
  31. static mutex_type & get_mutex()
  32. {
  33.     static mutex_type m;
  34.     return m;
  35. }
  36.  
  37. static void * init_mutex_before_main = &get_mutex();
  38.  
  39. namespace
  40. {
  41.     class X;
  42.  
  43.     struct count_layout
  44.     {
  45.         mars_boost::detail::sp_counted_base * pi;
  46.         int id;
  47.     };
  48.  
  49.     struct shared_ptr_layout
  50.     {
  51.         X * px;
  52.         count_layout pn;
  53.     };
  54. }
  55.  
  56. // assume 4 byte alignment for pointers when scanning
  57. size_t const pointer_align = 4;
  58.  
  59. typedef std::map<void const *, long> map2_type;
  60.  
  61. static void scan_and_count(void const * area, size_t size, map_type const & m, map2_type & m2)
  62. {
  63.     unsigned char const * p = static_cast<unsigned char const *>(area);
  64.  
  65.     for(size_t n = 0; n + sizeof(shared_ptr_layout) <= size; p += pointer_align, n += pointer_align)
  66.     {
  67.         shared_ptr_layout const * q = reinterpret_cast<shared_ptr_layout const *>(p);
  68.  
  69.         if(q->pn.id == mars_boost::detail::shared_count_id && q->pn.pi != 0 && m.count(q->pn.pi) != 0)
  70.         {
  71.             ++m2[q->pn.pi];
  72.         }
  73.     }
  74. }
  75.  
  76. typedef std::deque<void const *> open_type;
  77.  
  78. static void scan_and_mark(void const * area, size_t size, map2_type & m2, open_type & open)
  79. {
  80.     unsigned char const * p = static_cast<unsigned char const *>(area);
  81.  
  82.     for(size_t n = 0; n + sizeof(shared_ptr_layout) <= size; p += pointer_align, n += pointer_align)
  83.     {
  84.         shared_ptr_layout const * q = reinterpret_cast<shared_ptr_layout const *>(p);
  85.  
  86.         if(q->pn.id == mars_boost::detail::shared_count_id && q->pn.pi != 0 && m2.count(q->pn.pi) != 0)
  87.         {
  88.             open.push_back(q->pn.pi);
  89.             m2.erase(q->pn.pi);
  90.         }
  91.     }
  92. }
  93.  
  94. static void find_unreachable_objects_impl(map_type const & m, map2_type & m2)
  95. {
  96.     // scan objects for shared_ptr members, compute internal counts
  97.  
  98.     {
  99.         std::cout << "... " << m.size() << " objects in m.\n";
  100.  
  101.         for(map_type::const_iterator i = m.begin(); i != m.end(); ++i)
  102.         {
  103.             mars_boost::detail::sp_counted_base const * p = static_cast<mars_boost::detail::sp_counted_base const *>(i->first);
  104.  
  105.             BOOST_ASSERT(p->use_count() != 0); // there should be no inactive counts in the map
  106.  
  107.             m2[ i->first ];
  108.  
  109.             scan_and_count(i->second.first, i->second.second, m, m2);
  110.         }
  111.  
  112.         std::cout << "... " << m2.size() << " objects in m2.\n";
  113.     }
  114.  
  115.     // mark reachable objects
  116.  
  117.     {
  118.         open_type open;
  119.  
  120.         for(map2_type::iterator i = m2.begin(); i != m2.end(); ++i)
  121.         {
  122.             mars_boost::detail::sp_counted_base const * p = static_cast<mars_boost::detail::sp_counted_base const *>(i->first);
  123.             if(p->use_count() != i->second) open.push_back(p);
  124.         }
  125.  
  126.         std::cout << "... " << open.size() << " objects in open.\n";
  127.  
  128.         for(open_type::iterator j = open.begin(); j != open.end(); ++j)
  129.         {
  130.             m2.erase(*j);
  131.         }
  132.  
  133.         while(!open.empty())
  134.         {
  135.             void const * p = open.front();
  136.             open.pop_front();
  137.  
  138.             map_type::const_iterator i = m.find(p);
  139.             BOOST_ASSERT(i != m.end());
  140.  
  141.             scan_and_mark(i->second.first, i->second.second, m2, open);
  142.         }
  143.     }
  144.  
  145.     // m2 now contains the unreachable objects
  146. }
  147.  
  148. std::size_t find_unreachable_objects(bool report)
  149. {
  150.     map2_type m2;
  151.  
  152. #ifdef BOOST_HAS_THREADS
  153.  
  154.     // This will work without the #ifdef, but some compilers warn
  155.     // that lock is not referenced
  156.  
  157.     mutex_type::scoped_lock lock(get_mutex());
  158.  
  159. #endif
  160.  
  161.     map_type const & m = get_map();
  162.  
  163.     find_unreachable_objects_impl(m, m2);
  164.  
  165.     if(report)
  166.     {
  167.         for(map2_type::iterator j = m2.begin(); j != m2.end(); ++j)
  168.         {
  169.             map_type::const_iterator i = m.find(j->first);
  170.             BOOST_ASSERT(i != m.end());
  171.             std::cout << "Unreachable object at " << i->second.first << ", " << i->second.second << " bytes long.\n";
  172.         }
  173.     }
  174.  
  175.     return m2.size();
  176. }
  177.  
  178. typedef std::deque< mars_boost::shared_ptr<X> > free_list_type;
  179.  
  180. static void scan_and_free(void * area, size_t size, map2_type const & m2, free_list_type & free)
  181. {
  182.     unsigned char * p = static_cast<unsigned char *>(area);
  183.  
  184.     for(size_t n = 0; n + sizeof(shared_ptr_layout) <= size; p += pointer_align, n += pointer_align)
  185.     {
  186.         shared_ptr_layout * q = reinterpret_cast<shared_ptr_layout *>(p);
  187.  
  188.         if(q->pn.id == mars_boost::detail::shared_count_id && q->pn.pi != 0 && m2.count(q->pn.pi) != 0 && q->px != 0)
  189.         {
  190.             mars_boost::shared_ptr<X> * ppx = reinterpret_cast< mars_boost::shared_ptr<X> * >(p);
  191.             free.push_back(*ppx);
  192.             ppx->reset();
  193.         }
  194.     }
  195. }
  196.  
  197. void free_unreachable_objects()
  198. {
  199.     free_list_type free;
  200.  
  201.     {
  202.         map2_type m2;
  203.  
  204. #ifdef BOOST_HAS_THREADS
  205.  
  206.         mutex_type::scoped_lock lock(get_mutex());
  207.  
  208. #endif
  209.  
  210.         map_type const & m = get_map();
  211.  
  212.         find_unreachable_objects_impl(m, m2);
  213.  
  214.         for(map2_type::iterator j = m2.begin(); j != m2.end(); ++j)
  215.         {
  216.             map_type::const_iterator i = m.find(j->first);
  217.             BOOST_ASSERT(i != m.end());
  218.             scan_and_free(i->second.first, i->second.second, m2, free);
  219.         }
  220.     }
  221.  
  222.     std::cout << "... about to free " << free.size() << " objects.\n";
  223. }
  224.  
  225. // debug hooks
  226.  
  227. namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost
  228. {
  229.  
  230. void sp_scalar_constructor_hook(void *)
  231. {
  232. }
  233.  
  234. void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn)
  235. {
  236. #ifdef BOOST_HAS_THREADS
  237.  
  238.     mutex_type::scoped_lock lock(get_mutex());
  239.  
  240. #endif
  241.  
  242.     get_map()[pn] = std::make_pair(px, size);
  243. }
  244.  
  245. void sp_scalar_destructor_hook(void *)
  246. {
  247. }
  248.  
  249. void sp_scalar_destructor_hook(void *, std::size_t, void * pn)
  250. {
  251. #ifdef BOOST_HAS_THREADS
  252.  
  253.     mutex_type::scoped_lock lock(get_mutex());
  254.  
  255. #endif
  256.  
  257.     get_map().erase(pn);
  258. }
  259.  
  260. void sp_array_constructor_hook(void *)
  261. {
  262. }
  263.  
  264. void sp_array_destructor_hook(void *)
  265. {
  266. }
  267.  
  268. } // namespace mars_boost
  269.  
  270. #endif // defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
  271.  
downloadsp_collector.cpp Source code - Download mars Source code
Related Source Codes/Software:
Hero - Elegant transition library for iOS & tvOS 2017-06-09
deep-photo-styletransfer - Code and data for paper "Deep Photo Style Transfer... 2017-06-09
mastodon - A GNU Social-compatible microblogging server ... 2017-06-09
plyr - A simple HTML5, YouTube and Vimeo player ... 2017-06-08
prepack - Prepack is a partial evaluator for JavaScript. Pre... 2017-06-08
Public-APIs - 2017-06-09
lottie-ios - An iOS library to natively render After Effects ve... 2017-06-09
Awesome-Hacking - A collection of various awesome lists for hackers,... 2017-06-09
algorithms - Minimal examples of data structures and algorithms... 2017-06-10
lectures - Oxford Deep NLP 2017 course 2017-06-10
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top