100.00% Lines (9/9) 100.00% Functions (3/3)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 4   // Distributed under the Boost Software License, Version 1.0. (See accompanying
5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/boostorg/url 7   // Official repository: https://github.com/boostorg/url
8   // 8   //
9   9  
10   #include <boost/url/detail/config.hpp> 10   #include <boost/url/detail/config.hpp>
11   #include <boost/url/grammar/detail/recycled.hpp> 11   #include <boost/url/grammar/detail/recycled.hpp>
12   #include <cstdlib> 12   #include <cstdlib>
13   #include <utility> 13   #include <utility>
14   #include <atomic> 14   #include <atomic>
15   15  
16   #ifdef BOOST_URL_REPORT 16   #ifdef BOOST_URL_REPORT
17   # ifdef _MSC_VER 17   # ifdef _MSC_VER
18   # include <intrin.h> 18   # include <intrin.h>
19   # endif 19   # endif
20   #endif 20   #endif
21   21  
22   namespace boost { 22   namespace boost {
23   namespace urls { 23   namespace urls {
24   namespace grammar { 24   namespace grammar {
25   namespace detail { 25   namespace detail {
26   26  
27   struct all_reports 27   struct all_reports
28   { 28   {
29   // current count 29   // current count
30   std::atomic<std::size_t> count = {0}; 30   std::atomic<std::size_t> count = {0};
31   31  
32   // current bytes 32   // current bytes
33   std::atomic<std::size_t> bytes = {0}; 33   std::atomic<std::size_t> bytes = {0};
34   34  
35   // highest total ptr count 35   // highest total ptr count
36   std::atomic<std::size_t> count_max = {0}; 36   std::atomic<std::size_t> count_max = {0};
37   37  
38   // highest total bytes 38   // highest total bytes
39   std::atomic<std::size_t> bytes_max = {0}; 39   std::atomic<std::size_t> bytes_max = {0};
40   40  
41   // largest single allocation 41   // largest single allocation
42   std::atomic<std::size_t> alloc_max = {0}; 42   std::atomic<std::size_t> alloc_max = {0};
43   43  
HITCBC 44   78 ~all_reports() 44   78 ~all_reports()
45   { 45   {
46   // breakpoint here to view report 46   // breakpoint here to view report
47   #ifdef BOOST_URL_REPORT 47   #ifdef BOOST_URL_REPORT
48   # ifdef _MSC_VER 48   # ifdef _MSC_VER
49   if(count_max > 0) 49   if(count_max > 0)
50   ::__debugbreak(); 50   ::__debugbreak();
51   # endif 51   # endif
52   #endif 52   #endif
HITCBC 53   78 } 53   78 }
54   }; 54   };
55   55  
56   static all_reports all_reports_; 56   static all_reports all_reports_;
57   } // detail 57   } // detail
58   58  
59   namespace implementation_defined { 59   namespace implementation_defined {
60   void 60   void
HITCBC 61   1 recycled_add_impl( 61   1 recycled_add_impl(
62   std::size_t n) noexcept 62   std::size_t n) noexcept
63   { 63   {
HITCBC 64   1 auto& a = detail::all_reports_; 64   1 auto& a = detail::all_reports_;
65   65  
66   // LCOV_EXCL_START 66   // LCOV_EXCL_START
67   /* 67   /*
68   * We can't guarantee coverage 68   * We can't guarantee coverage
69   * exercise of this path. 69   * exercise of this path.
70   */ 70   */
71   std::size_t new_count = ++a.count; 71   std::size_t new_count = ++a.count;
72   std::size_t old_count_max = a.count_max; 72   std::size_t old_count_max = a.count_max;
73   while ( 73   while (
74   old_count_max < new_count && 74   old_count_max < new_count &&
75   !a.count_max.compare_exchange_weak( 75   !a.count_max.compare_exchange_weak(
76   old_count_max, new_count)) 76   old_count_max, new_count))
77   {} 77   {}
78   78  
79   std::size_t new_bytes = a.bytes.fetch_add(n) + n; 79   std::size_t new_bytes = a.bytes.fetch_add(n) + n;
80   std::size_t old_bytes_max = a.bytes_max; 80   std::size_t old_bytes_max = a.bytes_max;
81   while ( 81   while (
82   old_bytes_max < new_bytes && 82   old_bytes_max < new_bytes &&
83   !a.bytes_max.compare_exchange_weak( 83   !a.bytes_max.compare_exchange_weak(
84   old_bytes_max, new_bytes)) 84   old_bytes_max, new_bytes))
85   {} 85   {}
86   86  
87   std::size_t old_alloc_max = a.alloc_max; 87   std::size_t old_alloc_max = a.alloc_max;
88   while ( 88   while (
89   old_alloc_max < n && 89   old_alloc_max < n &&
90   !a.alloc_max.compare_exchange_weak( 90   !a.alloc_max.compare_exchange_weak(
91   old_alloc_max, n)) 91   old_alloc_max, n))
92   {} 92   {}
93   // LCOV_EXCL_STOP 93   // LCOV_EXCL_STOP
HITCBC 94   1 } 94   1 }
95   95  
96   void 96   void
HITCBC 97   1 recycled_remove_impl( 97   1 recycled_remove_impl(
98   std::size_t n) noexcept 98   std::size_t n) noexcept
99   { 99   {
HITCBC 100   1 detail::all_reports_.count--; 100   1 detail::all_reports_.count--;
HITCBC 101   1 detail::all_reports_.bytes-=n; 101   1 detail::all_reports_.bytes-=n;
HITCBC 102   1 } 102   1 }
103   } // implementation_defined 103   } // implementation_defined
104   } // grammar 104   } // grammar
105   } // urls 105   } // urls
106   } // boost 106   } // boost