]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1306] Added statistic collect
authorFrancis Dupont <fdupont@isc.org>
Sun, 6 Sep 2020 13:58:58 +0000 (15:58 +0200)
committerTomek Mrugalski <thomson@klub.com.pl>
Thu, 22 Oct 2020 17:19:48 +0000 (19:19 +0200)
src/lib/util/tests/thread_pool_unittest.cc
src/lib/util/thread_pool.h

index c39f61e785496dcbbc1b6e752df014251cffc0a3..48213853475d7bec3d80dd2fcd4792282ee2e69a 100644 (file)
@@ -450,6 +450,11 @@ TEST_F(ThreadPoolTest, startAndStop) {
     ASSERT_EQ(thread_pool.count(), 0);
     // the thread count should be 0
     ASSERT_EQ(thread_pool.size(), 0);
+
+    /// statistics
+    std::cout << "stat10: " << thread_pool.getQueueStat(10) << std::endl;
+    std::cout << "stat100: " << thread_pool.getQueueStat(100) << std::endl;
+    std::cout << "stat1000: " << thread_pool.getQueueStat(1000) << std::endl;
 }
 
 /// @brief test ThreadPool max queue size
@@ -526,4 +531,16 @@ TEST_F(ThreadPoolTest, addFront) {
     EXPECT_EQ(thread_pool.count(), items_count);
 }
 
+/// @brief test ThreadPool get queue statistics.
+TEST_F(ThreadPoolTest, getQueueStat) {
+    ThreadPool<CallBack> thread_pool;
+    EXPECT_THROW(thread_pool.getQueueStat(0), InvalidParameter);
+    EXPECT_THROW(thread_pool.getQueueStat(1), InvalidParameter);
+    EXPECT_THROW(thread_pool.getQueueStat(-10), InvalidParameter);
+    EXPECT_THROW(thread_pool.getQueueStat(10000), InvalidParameter);
+    EXPECT_NO_THROW(thread_pool.getQueueStat(10));
+    EXPECT_NO_THROW(thread_pool.getQueueStat(100));
+    EXPECT_NO_THROW(thread_pool.getQueueStat(1000));
+}
+
 }  // namespace
index 07cc230211a654c134e1d25dfb73e6d0c6531843..b1e8ca3e4a6f95b87afcf0785edd991b586fce43 100644 (file)
@@ -12,6 +12,7 @@
 #include <boost/shared_ptr.hpp>
 
 #include <atomic>
+#include <cmath>
 #include <condition_variable>
 #include <list>
 #include <mutex>
@@ -28,6 +29,16 @@ namespace util {
 /// @tparam Container a 'queue like' container
 template <typename WorkItem, typename Container = std::deque<boost::shared_ptr<WorkItem>>>
 struct ThreadPool {
+    /// @brief Rounding value for 10 packet statistic.
+    static const double CEXP10;
+
+    /// @brief Rounding value for 100 packet statistic.
+    static const double CEXP100;
+
+    /// @brief Rounding value for 1000 packet statistic.
+    static const double CEXP1000;
+
+    /// @brief Type of shared pointers to work items.
     typedef typename boost::shared_ptr<WorkItem> WorkItemPtr;
 
     /// @brief Constructor
@@ -120,6 +131,15 @@ struct ThreadPool {
         return (threads_.size());
     }
 
+    /// @brief get queue length statistic
+    ///
+    /// @param which select the statistic (10, 100 or 1000)
+    /// @return the queue length statistic
+    /// @throw InvalidParameter if which is not 10 and 100 and 1000.
+    double getQueueStat(size_t which) {
+        return (queue_.getQueueStat(which));
+    }
+
 private:
     /// @brief start all the threads
     ///
@@ -173,7 +193,9 @@ private:
         /// @brief Constructor
         ///
         /// Creates the thread pool queue in 'disabled' state
-        ThreadPoolQueue() : enabled_(false), max_queue_size_(0) {
+        ThreadPoolQueue()
+            : enabled_(false), max_queue_size_(0),
+              stat10(0.), stat100(0.), stat1000(0.) {
         }
 
         /// @brief Destructor
@@ -263,6 +285,7 @@ private:
         /// If the queue is 'enabled', this function returns the first element in
         /// the queue or blocks the calling thread if there are no work items
         /// available.
+        /// Before a work item is returned statistics are updated.
         ///
         /// @return the first work item from the queue or an empty element.
         Item pop() {
@@ -272,6 +295,10 @@ private:
             if (!enabled_) {
                 return (Item());
             }
+            size_t length = queue_.size();
+            stat10 = stat10 * CEXP10 + (1 - CEXP10) * length;
+            stat100 = stat100 * CEXP100 + (1 - CEXP100) * length;
+            stat1000 = stat1000 * CEXP1000 + (1 - CEXP1000) * length;
             Item item = queue_.front();
             queue_.pop_front();
             return (item);
@@ -287,6 +314,26 @@ private:
             return (queue_.size());
         }
 
+        /// @brief  get queue length statistic
+        ///
+        /// @param which select the statistic (10, 100 or 1000)
+        /// @return the queue length statistic
+        /// @throw InvalidParameter if which is not 10 and 100 and 1000.
+        double getQueueStat(size_t which) {
+            std::lock_guard<std::mutex> lock(mutex_);
+            switch (which) {
+            case 10:
+                return (stat10);
+            case 100:
+                return (stat100);
+            case 1000:
+                return (stat1000);
+            default:
+                isc_throw(InvalidParameter, "supported statistic for "
+                          << "10/100/1000 only, not " << which);
+            }
+        }
+
         /// @brief clear remove all work items
         ///
         /// Removes all queued work items
@@ -342,6 +389,15 @@ private:
         /// @brief maximum number of work items in the queue
         /// (0 means unlimited)
         size_t max_queue_size_;
+
+        /// @brief queue length statistic for 10 packets
+        double stat10;
+
+        /// @brief queue length statistic for 100 packets
+        double stat100;
+
+        /// @brief queue length statistic for 1000 packets
+        double stat1000;
     };
 
     /// @brief run function of each thread
@@ -365,6 +421,18 @@ private:
     ThreadPoolQueue<WorkItemPtr, Container> queue_;
 };
 
+/// Initialize the 10 packet rounding to exp(-.1)
+template <typename W, typename C>
+    const double ThreadPool<W, C>::CEXP10 = std::exp(-.1);
+
+/// Initialize the 100 packet rounding to exp(-.01)
+template <typename W, typename C>
+const double ThreadPool<W, C>::CEXP100 = std::exp(-.01);
+
+/// Initialize the 1000 packet rounding to exp(-.1)
+template <typename W, typename C>
+const double ThreadPool<W, C>::CEXP1000 = std::exp(-.001);
+
 }  // namespace util
 }  // namespace isc