summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/profiler.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/profiler.h')
-rw-r--r--src/emu/profiler.h114
1 files changed, 91 insertions, 23 deletions
diff --git a/src/emu/profiler.h b/src/emu/profiler.h
index cff0801f65c..8ea65ac7f07 100644
--- a/src/emu/profiler.h
+++ b/src/emu/profiler.h
@@ -8,11 +8,11 @@
****************************************************************************
- Profiling is scope-based. To start profiling, put a profiler_scope
+ Profiling is scope-based. To start profiling, put a profiler scope
object on the stack. To end profiling, just end the scope:
{
- profiler_scope scope(PROFILER_VIDEO);
+ auto scope = g_profiler.start(PROFILER_VIDEO);
your_work_here();
}
@@ -26,6 +26,17 @@
#pragma once
+#include "emufwd.h"
+
+#include "attotime.h"
+
+#include "eminline.h" // for get_profile_ticks()
+#include "osdcore.h"
+
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+
//**************************************************************************
// CONSTANTS
@@ -83,18 +94,57 @@ DECLARE_ENUM_INCDEC_OPERATORS(profile_type)
class real_profiler_state
{
public:
+ class scope
+ {
+ private:
+ real_profiler_state &m_host;
+ bool m_active;
+
+ public:
+ scope(scope const &) = delete;
+ scope &operator=(scope const &) = delete;
+
+ scope(scope &&that) noexcept : m_host(that.m_host), m_active(that.m_active)
+ {
+ that.m_active = false;
+ }
+
+ scope(real_profiler_state &host, profile_type type) noexcept : m_host(host), m_active(false)
+ {
+ if (m_host.enabled())
+ {
+ m_host.real_start(type);
+ m_active = true;
+ }
+ }
+
+ ~scope()
+ {
+ stop();
+ }
+
+ void stop() noexcept
+ {
+ if (m_active)
+ {
+ m_host.real_stop();
+ m_active = false;
+ }
+ }
+ };
+
// construction/destruction
real_profiler_state();
// getters
- bool enabled() const
+ bool enabled() const noexcept
{
return m_filoptr != nullptr;
}
const char *text(running_machine &machine);
// enable/disable
- void enable(bool state = true)
+ void enable(bool state = true) noexcept
{
if (state != enabled())
{
@@ -103,22 +153,31 @@ public:
}
// start/stop
- void start(profile_type type) { if (enabled()) real_start(type); }
- void stop() { if (enabled()) real_stop(); }
+ [[nodiscard]] auto start(profile_type type) noexcept { return scope(*this, type); }
private:
- void reset(bool enabled);
+ // an entry in the FILO
+ struct filo_entry
+ {
+ int type; // type of entry
+ osd_ticks_t start; // start time
+ };
+
+ void reset(bool enabled) noexcept;
void update_text(running_machine &machine);
//-------------------------------------------------
// real_start - mark the beginning of a
// profiler entry
//-------------------------------------------------
- ATTR_FORCE_INLINE void real_start(profile_type type)
+ ATTR_FORCE_INLINE void real_start(profile_type type) noexcept
{
// fail if we overflow
- if (m_filoptr >= &m_filo[ARRAY_LENGTH(m_filo) - 1])
- throw emu_fatalerror("Profiler FILO overflow (type = %d)\n", type);
+ if (UNEXPECTED(m_filoptr >= &m_filo[std::size(m_filo) - 1]))
+ {
+ std::fprintf(stderr, "Profiler FILO overflow (type = %d)\n", int(type));
+ std::abort();
+ }
// get current tick count
osd_ticks_t curticks = get_profile_ticks();
@@ -137,7 +196,7 @@ private:
//-------------------------------------------------
// real_stop - mark the end of a profiler entry
//-------------------------------------------------
- ATTR_FORCE_INLINE void real_stop()
+ ATTR_FORCE_INLINE void real_stop() noexcept
{
// degenerate scenario
if (UNEXPECTED(m_filoptr <= m_filo))
@@ -156,13 +215,6 @@ private:
m_filoptr->start = curticks;
}
- // an entry in the FILO
- struct filo_entry
- {
- int type; // type of entry
- osd_ticks_t start; // start time
- };
-
// internal state
filo_entry * m_filoptr; // current FILO index
std::string m_text; // profiler text
@@ -177,19 +229,35 @@ private:
class dummy_profiler_state
{
public:
+ class scope
+ {
+ private:
+ dummy_profiler_state &m_host;
+
+ public:
+ scope(scope const &) = delete;
+ scope &operator=(scope const &) = delete;
+ scope(scope &&that) noexcept = default;
+ scope(dummy_profiler_state &host, profile_type type) noexcept : m_host(host) { }
+ ~scope() { m_host.real_stop(); }
+ void stop() noexcept { }
+ };
+
// construction/destruction
dummy_profiler_state();
// getters
- bool enabled() const { return false; }
+ bool enabled() const noexcept { return false; }
const char *text(running_machine &machine) { return ""; }
// enable/disable
- void enable(bool state = true) { }
+ void enable(bool state = true) noexcept { }
// start/stop
- void start(profile_type type) { }
- void stop() { }
+ [[nodiscard]] auto start(profile_type type) noexcept { return scope(*this, type); }
+
+private:
+ void real_stop() noexcept { }
};
@@ -210,4 +278,4 @@ typedef dummy_profiler_state profiler_state;
extern profiler_state g_profiler;
-#endif /* MAME_EMU_PROFILER_H */
+#endif // MAME_EMU_PROFILER_H