@@ -175,7 +175,10 @@ Timer::Timer(const MPI_Comm mpi_communicator, const bool sync_lap_times_)
175175void
176176Timer::start ()
177177{
178- if (running == false )
178+ // Make sure only one thread at a time starts or resets the timer
179+ std::lock_guard<std::mutex> lock (mutex);
180+
181+ if (is_running () == false )
179182 ++n_timed_laps;
180183
181184 running = true ;
@@ -195,47 +198,57 @@ Timer::start()
195198void
196199Timer::stop ()
197200{
198- if (running)
199- {
200- running = false ;
201+ // Make sure only one thread at a time stops the timer
202+ std::lock_guard<std::mutex> lock (mutex);
201203
202- wall_times.last_lap_time =
203- wall_clock_type::now () - wall_times.current_lap_start_time ;
204- cpu_times.last_lap_time =
205- cpu_clock_type::now () - cpu_times.current_lap_start_time ;
204+ AssertThrow (is_running () == true ,
205+ ExcMessage (
206+ " This timer is not running and hence cannot be stopped." ));
206207
207- last_lap_wall_time_data =
208- Utilities::MPI::min_max_avg (internal::TimerImplementation::to_seconds (
209- wall_times.last_lap_time ),
210- mpi_communicator);
211- if (sync_lap_times)
212- {
213- wall_times.last_lap_time =
214- internal::TimerImplementation::from_seconds<
215- decltype (wall_times)::duration_type>(last_lap_wall_time_data.max );
216- cpu_times.last_lap_time = internal::TimerImplementation::from_seconds<
217- decltype (cpu_times)::duration_type>(
218- Utilities::MPI::min_max_avg (
219- internal::TimerImplementation::to_seconds (
220- cpu_times.last_lap_time ),
221- mpi_communicator)
222- .max );
223- }
224- wall_times.accumulated_time += wall_times.last_lap_time ;
225- cpu_times.accumulated_time += cpu_times.last_lap_time ;
226- accumulated_wall_time_data =
208+ running = false ;
209+
210+ wall_times.last_lap_time =
211+ wall_clock_type::now () - wall_times.current_lap_start_time ;
212+ cpu_times.last_lap_time =
213+ cpu_clock_type::now () - cpu_times.current_lap_start_time ;
214+
215+ last_lap_wall_time_data =
216+ Utilities::MPI::min_max_avg (internal::TimerImplementation::to_seconds (
217+ wall_times.last_lap_time ),
218+ mpi_communicator);
219+ if (sync_lap_times)
220+ {
221+ wall_times.last_lap_time = internal::TimerImplementation::from_seconds<
222+ decltype (wall_times)::duration_type>(last_lap_wall_time_data.max );
223+ cpu_times.last_lap_time = internal::TimerImplementation::from_seconds<
224+ decltype (cpu_times)::duration_type>(
227225 Utilities::MPI::min_max_avg (internal::TimerImplementation::to_seconds (
228- wall_times.accumulated_time ),
229- mpi_communicator);
226+ cpu_times.last_lap_time ),
227+ mpi_communicator)
228+ .max );
230229 }
230+ wall_times.accumulated_time += wall_times.last_lap_time ;
231+ cpu_times.accumulated_time += cpu_times.last_lap_time ;
232+ accumulated_wall_time_data =
233+ Utilities::MPI::min_max_avg (internal::TimerImplementation::to_seconds (
234+ wall_times.accumulated_time ),
235+ mpi_communicator);
236+ }
237+
238+
239+
240+ bool
241+ Timer::is_running () const
242+ {
243+ return running;
231244}
232245
233246
234247
235248double
236249Timer::cpu_time () const
237250{
238- if (running )
251+ if (is_running () )
239252 {
240253 const double running_time = internal::TimerImplementation::to_seconds (
241254 cpu_clock_type::now () - cpu_times.current_lap_start_time +
@@ -264,7 +277,7 @@ double
264277Timer::wall_time () const
265278{
266279 wall_clock_type::duration current_elapsed_wall_time;
267- if (running )
280+ if (is_running () )
268281 current_elapsed_wall_time = wall_clock_type::now () -
269282 wall_times.current_lap_start_time +
270283 wall_times.accumulated_time ;
@@ -435,7 +448,13 @@ TimerOutput::enter_subsection(const std::string §ion_name)
435448 sections[section_name] = Timer (mpi_communicator, false );
436449 }
437450 else
438- sections[section_name].start ();
451+ {
452+ Assert (sections[section_name].is_running () == false ,
453+ ExcMessage (" Cannot enter the already active section <" +
454+ section_name + " >." ));
455+
456+ sections[section_name].start ();
457+ }
439458
440459 active_sections.push_back (section_name);
441460}
@@ -465,6 +484,10 @@ TimerOutput::leave_subsection(const std::string §ion_name)
465484 const std::string actual_section_name =
466485 (section_name.empty () ? active_sections.back () : section_name);
467486
487+ Assert (sections[actual_section_name].is_running () == true ,
488+ ExcMessage (" Cannot leave section <" + actual_section_name +
489+ " >, because it has not been entered." ));
490+
468491 sections[actual_section_name].stop ();
469492
470493 // in case we have to print out something, do that here...
0 commit comments