CUBRID Engine  latest
thread_daemon.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * thread_daemon - interface for daemon threads
21  */
22 
23 // own header
24 #include "thread_daemon.hpp"
25 
26 // module headers
27 #include "thread_task.hpp"
28 
29 // cubrid headers
30 #include "perf.hpp"
31 
32 namespace cubthread
33 {
35  // daemon statistics
38  static const cubperf::stat_id STAT_LOOP_PAUSE_TIME = 1; // count is same as for execute
40  {
42  "daemon_loop_count", "daemon_execute_time"),
44  "daemon_pause_time")
45  };
46 
48  // daemon implementation
50 
51  daemon::daemon (const looper &loop_pattern_arg, task_without_context *exec_arg, const char *name)
52  : m_waiter ()
53  , m_looper (loop_pattern_arg)
54  , m_func_on_stop ()
55  , m_thread ()
56  , m_name (name)
57  , m_stats (daemon::create_statset ())
58  {
59  m_thread = std::thread (daemon::loop_without_context, this, exec_arg, m_name.c_str ());
60  }
61 
63  {
64  // thread must be stopped
65  stop_execution ();
66 
67  delete &m_stats;
68  }
69 
70  void
72  {
73  m_waiter.wakeup ();
74  }
75 
76  void
78  {
79  // note: this must not be called concurrently
80 
81  if (m_looper.stop ())
82  {
83  // already stopped
84  return;
85  }
86 
87  if (m_func_on_stop)
88  {
89  // to interrupt execution context
90  m_func_on_stop ();
91  }
92 
93  // make sure thread will wakeup
94  wakeup ();
95 
96  // then wait for thread to finish
97  m_thread.join ();
98  }
99 
100  void daemon::pause (void)
101  {
103  }
104 
105  bool
107  {
108  return m_looper.was_woken_up ();
109  }
110 
111  void
113  {
114  m_looper.reset ();
115  }
116 
117  void
119  {
120  std::size_t i = 0;
121 
122  // get daemon stats
123  Daemon_statistics.get_stat_values_with_converted_timers<std::chrono::microseconds> (m_stats, stats_out);
124  i += Daemon_statistics.get_value_count ();
125 
126  // get looper stats
127  m_looper.get_stats (&stats_out[i]);
129 
130  // get waiter stats
131  m_waiter.get_stats (&stats_out[i]);
132  // i += waiter::STAT_COUNT;
133  }
134 
135  bool
137  {
138  return m_waiter.is_running ();
139  }
140 
141  std::size_t
143  {
145  }
146 
147  const char *
148  daemon::get_stat_name (std::size_t stat_index)
149  {
150  assert (stat_index < get_stats_value_count ());
151 
152  // is from daemon?
153  if (stat_index < Daemon_statistics.get_value_count ())
154  {
155  return Daemon_statistics.get_value_name (stat_index);
156  }
157  else
158  {
159  stat_index -= Daemon_statistics.get_value_count ();
160  }
161 
162  // is from looper?
163  if (stat_index < looper::get_stats_value_count ())
164  {
165  return looper::get_stat_name (stat_index);
166  }
167  else
168  {
169  stat_index -= looper::get_stats_value_count ();
170  }
171 
172  // must be from waiter
173  assert (stat_index < waiter::get_stats_value_count ());
174  return waiter::get_stat_name (stat_index);
175  }
176 
179  {
180  return *Daemon_statistics.create_statset ();
181  }
182 
183  void
185  {
187  }
188 
189  void
191  {
192  Daemon_statistics.time (m_stats, STAT_LOOP_PAUSE_TIME);
193  }
194 
195  void
197  {
198  Daemon_statistics.time_and_increment (m_stats, STAT_LOOP_EXECUTE_COUNT_AND_TIME);
199  }
200 
201  void
202  daemon::loop_without_context (daemon *daemon_arg, task_without_context *exec_arg, const char *name)
203  {
204  (void) name; // suppress unused parameter warning
205  // its purpose is to help visualize daemon thread stacks
206 
207  daemon_arg->register_stat_start ();
208 
209  while (!daemon_arg->m_looper.is_stopped ())
210  {
211  // execute task
212  exec_arg->execute ();
213  daemon_arg->register_stat_execute ();
214 
215  // take a break
216  daemon_arg->pause ();
217  daemon_arg->register_stat_pause ();
218  }
219 
220  // retire task
221  exec_arg->retire ();
222  }
223 
224 } // namespace cubthread
virtual void execute(void)=0
static std::size_t get_stats_value_count(void)
void put_to_sleep(waiter &waiter_arg)
void time_and_increment(statset &statsetr, stat_id id, duration d, stat_value incr=1) const
Definition: perf.hpp:340
void get_stats(cubperf::stat_value *stats_out)
generic_value< false > stat_value
Definition: perf_def.hpp:46
static cubperf::statset & create_statset(void)
void register_stat_start(void)
static const cubperf::stat_id STAT_LOOP_EXECUTE_COUNT_AND_TIME
void get_stats(cubperf::stat_value *stats_out)
std::size_t stat_id
Definition: perf_def.hpp:50
void get_stat_values_with_converted_timers(const statset &statsetr, stat_value *output_stats) const
Definition: perf.hpp:403
static const cubperf::statset_definition Daemon_statistics
void stop_execution(void)
std::size_t get_value_count() const
Definition: perf.cpp:149
#define assert(x)
statset * create_statset(void) const
Definition: perf.cpp:131
static const cubperf::stat_id STAT_LOOP_PAUSE_TIME
void time(statset &statsetr, stat_id id, duration d) const
Definition: perf.hpp:293
void register_stat_execute(void)
cubperf::statset & m_stats
void reset_looper(void)
void get_stats(cubperf::stat_value *stats_out)
bool was_woken_up(void) const
static const char * get_stat_name(std::size_t stat_index)
daemon(const looper &loop_pattern_arg, context_manager< Context > *context_manager_arg, task< Context > *exec, const char *name)
static void loop_without_context(daemon *daemon_arg, task_without_context *exec_arg, const char *name)
bool is_stopped(void) const
const char * get_value_name(std::size_t value_index) const
Definition: perf.cpp:155
std::thread m_thread
int i
Definition: dynamic_load.c:954
static std::size_t get_stats_value_count(void)
static const char * get_stat_name(std::size_t stat_index)
static const char * get_stat_name(std::size_t stat_index)
bool was_woken_up(void)
virtual void retire(void)
void register_stat_pause(void)
std::function< void(void)> m_func_on_stop
void reset_timept(time_point &timept)
Definition: perf.hpp:623
static std::size_t get_stats_value_count(void)