summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/timer/timer_heavy.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:19:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:20:02 +0000
commit58daab21cd043e1dc37024a7f99b396788372918 (patch)
tree96771e43bb69f7c1c2b0b4f7374cb74d7866d0cb /ml/dlib/dlib/timer/timer_heavy.h
parentReleasing debian version 1.43.2-1. (diff)
downloadnetdata-58daab21cd043e1dc37024a7f99b396788372918.tar.xz
netdata-58daab21cd043e1dc37024a7f99b396788372918.zip
Merging upstream version 1.44.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ml/dlib/dlib/timer/timer_heavy.h')
-rw-r--r--ml/dlib/dlib/timer/timer_heavy.h392
1 files changed, 392 insertions, 0 deletions
diff --git a/ml/dlib/dlib/timer/timer_heavy.h b/ml/dlib/dlib/timer/timer_heavy.h
new file mode 100644
index 000000000..693b91ad9
--- /dev/null
+++ b/ml/dlib/dlib/timer/timer_heavy.h
@@ -0,0 +1,392 @@
+// Copyright (C) 2005 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_TIMER_KERNEl_1_
+#define DLIB_TIMER_KERNEl_1_
+
+#include "../threads.h"
+#include "../algs.h"
+#include "../misc_api.h"
+#include "timer_abstract.h"
+
+namespace dlib
+{
+
+ template <
+ typename T
+ >
+ class timer_heavy
+ {
+ /*!
+ WHAT THIS OBJECT REPRESENTS
+ This is an implementation of the timer_abstract.h interface. It is very
+ simple and uses only one thread which is always alive in a timer_heavy.
+ The reason this object exists is for historical reasons. Originally, the
+ dlib::timer was a multi-implementation component and the timer_heavy was
+ its first implementation. It was superseded later by the more efficient
+ dlib::timer. However, timer_heavy is still around so that
+ dlib::timer::kernel_1a has something to refer to. This way, old client
+ code which somehow depends on the same thread always calling a timer action
+ function isn't going to be disrupted.
+
+
+ INITIAL VALUE
+ - running == false
+ - delay == 1000
+ - ao == a pointer to the action_object()
+ - af == a pointer to the action_function()
+ - m == a mutex that locks everything in this class
+ - s == a signaler for mutex m
+ - stop_running == false
+
+ CONVENTION
+ - running && !stop_running == is_running()
+ - delay == delay_time()
+ - *ao == action_object()
+ - af == action_function()
+
+ - if (running) then
+ - there is a thread running
+ - if (is_running()) then
+ - next_time_to_run == the time when the next execution of the action
+ function should occur. (the time is given by ts.get_timestamp())
+
+ - stop_running is used to tell the thread to quit. If it is
+ set to true then the thread should end.
+ !*/
+
+ public:
+
+ typedef void (T::*af_type)();
+
+ timer_heavy(
+ T& ao_,
+ af_type af_
+ );
+
+ virtual ~timer_heavy(
+ );
+
+ void clear(
+ );
+
+ af_type action_function (
+ ) const;
+
+ const T& action_object (
+ ) const;
+
+ T& action_object (
+ );
+
+ bool is_running (
+ ) const;
+
+ unsigned long delay_time (
+ ) const;
+
+ void set_delay_time (
+ unsigned long milliseconds
+ );
+
+ void start (
+ );
+
+ void stop (
+ );
+
+ void stop_and_wait (
+ );
+
+ private:
+
+ void thread (
+ );
+ /*!
+ requires
+ - is run in its own thread
+ ensures
+ - calls the action function for the given timer object in the manner
+ specified by timer_kernel_abstract.h
+ !*/
+
+ // data members
+ T& ao;
+ const af_type af;
+ unsigned long delay;
+ mutex m;
+ signaler s;
+
+ bool running;
+ bool stop_running;
+ timestamper ts;
+ uint64 next_time_to_run;
+
+ // restricted functions
+ timer_heavy(const timer_heavy<T>&); // copy constructor
+ timer_heavy<T>& operator=(const timer_heavy<T>&); // assignment operator
+
+ };
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+ // member function definitions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ timer_heavy<T>::
+ timer_heavy(
+ T& ao_,
+ af_type af_
+ ) :
+ ao(ao_),
+ af(af_),
+ delay(1000),
+ s(m),
+ running(false),
+ stop_running(false)
+ {
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ timer_heavy<T>::
+ ~timer_heavy(
+ )
+ {
+ stop_and_wait();
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ void timer_heavy<T>::
+ clear(
+ )
+ {
+ m.lock();
+ stop_running = true;
+ delay = 1000;
+ s.broadcast();
+ m.unlock();
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ typename timer_heavy<T>::af_type timer_heavy<T>::
+ action_function (
+ ) const
+ {
+ return af;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ const T& timer_heavy<T>::
+ action_object (
+ ) const
+ {
+ return ao;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ T& timer_heavy<T>::
+ action_object (
+ )
+ {
+ return ao;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ bool timer_heavy<T>::
+ is_running (
+ ) const
+ {
+ auto_mutex M(m);
+ return running && !stop_running;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ unsigned long timer_heavy<T>::
+ delay_time (
+ ) const
+ {
+ auto_mutex M(m);
+ return delay;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ void timer_heavy<T>::
+ set_delay_time (
+ unsigned long milliseconds
+ )
+ {
+ m.lock();
+
+ // if (is_running()) then we should adjust next_time_to_run
+ if (running && !stop_running)
+ {
+ next_time_to_run -= delay*1000;
+ next_time_to_run += milliseconds*1000;
+ }
+
+ delay = milliseconds;
+ s.broadcast();
+ m.unlock();
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ void timer_heavy<T>::
+ start (
+ )
+ {
+ auto_mutex M(m);
+
+ // if (is_running() == false) then reset the countdown to the next call
+ // to the action_function()
+ if ( (running && !stop_running) == false)
+ next_time_to_run = ts.get_timestamp() + delay*1000;
+
+ stop_running = false;
+ if (running == false)
+ {
+ running = true;
+
+ // start the thread
+ if (create_new_thread<timer_heavy,&timer_heavy::thread>(*this) == false)
+ {
+ running = false;
+ throw dlib::thread_error("error creating new thread in timer_heavy::start");
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ void timer_heavy<T>::
+ stop (
+ )
+ {
+ m.lock();
+ stop_running = true;
+ s.broadcast();
+ m.unlock();
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ void timer_heavy<T>::
+ thread (
+ )
+ {
+ auto_mutex M(m);
+ unsigned long delay_remaining;
+ uint64 current_time = ts.get_timestamp();
+
+ if (current_time < next_time_to_run)
+ delay_remaining = static_cast<unsigned long>((next_time_to_run-current_time)/1000);
+ else
+ delay_remaining = 0;
+
+ while (stop_running == false)
+ {
+ if (delay_remaining > 0)
+ s.wait_or_timeout(delay_remaining);
+
+ if (stop_running)
+ break;
+
+ current_time = ts.get_timestamp();
+ if (current_time < next_time_to_run)
+ {
+ // then we woke up too early so we should keep waiting
+ delay_remaining = static_cast<unsigned long>((next_time_to_run-current_time)/1000);
+
+ // rounding might make this be zero anyway. So if it is
+ // then we will say we have hit the next time to run.
+ if (delay_remaining > 0)
+ continue;
+ }
+
+ // call the action function
+ m.unlock();
+ (ao.*af)();
+ m.lock();
+
+ current_time = ts.get_timestamp();
+ next_time_to_run = current_time + delay*1000;
+ delay_remaining = delay;
+ }
+ running = false;
+ stop_running = false;
+ s.broadcast();
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename T
+ >
+ void timer_heavy<T>::
+ stop_and_wait (
+ )
+ {
+ m.lock();
+ if (running)
+ {
+ // make the running thread terminate
+ stop_running = true;
+
+ s.broadcast();
+ // wait for the thread to quit
+ while (running)
+ s.wait();
+ }
+ m.unlock();
+ }
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_TIMER_KERNEl_1_
+