More efficient device error logging

This commit is contained in:
AJR 2016-06-20 14:31:08 -04:00
parent 224b0dd8ea
commit 7f3699e69d
6 changed files with 44 additions and 15 deletions

View File

@ -360,6 +360,10 @@ bool device_t::findit(bool isvalidation) const
void device_t::start()
{
// prepare the logerror buffer
if (m_machine->allow_logging())
m_string_buffer.reserve(1024);
// find all the registered devices
if (!findit(false))
throw emu_fatalerror("Missing some required objects, unable to proceed");
@ -380,7 +384,7 @@ void device_t::start()
device_sound_interface *sound;
if (state_registrations == 0 && (interface(exec) || interface(sound)) && type() != SPEAKER)
{
logerror("Device '%s' did not register any state to save!\n", tag());
logerror("Device did not register any state to save!\n");
if ((machine().system().flags & MACHINE_SUPPORTS_SAVE) != 0)
fatalerror("Device '%s' did not register any state to save!\n", tag());
}

View File

@ -361,6 +361,9 @@ private:
bool m_config_complete; // have we completed our configuration?
bool m_started; // true if the start function has succeeded
finder_base * m_auto_finder_list; // list of objects to auto-find
// string formatting buffer for logerror
mutable util::ovectorstream m_string_buffer;
};

View File

@ -17,8 +17,6 @@
#ifndef __DEVICE_IPP__
#define __DEVICE_IPP__
#include "strformat.h"
//**************************************************************************
// MEMBER TEMPLATES
//**************************************************************************
@ -26,15 +24,28 @@
template <typename Format, typename... Params>
inline void device_t::popmessage(Format &&fmt, Params &&... args) const
{
if (m_machine)
if (m_machine != nullptr)
m_machine->popmessage(std::forward<Format>(fmt), std::forward<Params>(args)...);
}
template <typename Format, typename... Params>
inline void device_t::logerror(Format &&fmt, Params &&... args) const
{
if (m_machine)
m_machine->logerror(string_format("[%s] %s", tag(), std::forward<Format>(fmt)), std::forward<Params>(args)...);
if (m_machine != nullptr && m_machine->allow_logging())
{
g_profiler.start(PROFILER_LOGERROR);
// dump to the buffer
m_string_buffer.clear();
m_string_buffer.seekp(0);
util::stream_format(m_string_buffer, "[%s] ", tag());
util::stream_format(m_string_buffer, std::forward<Format>(fmt), std::forward<Params>(args)...);
m_string_buffer.put('\0');
m_machine->strlog(&m_string_buffer.vec()[0]);
g_profiler.stop();
}
}
#endif // __DEVICE_IPP__

View File

@ -29,9 +29,11 @@
#include "eminline.h"
#include "profiler.h"
// commonly-referenecd utilities imported from lib/util
// commonly-referenced utilities imported from lib/util
#include "palette.h"
#include "unicode.h"
#include "strformat.h"
#include "vecstream.h"
// emulator-specific utilities
#include "attotime.h"

View File

@ -727,6 +727,19 @@ void running_machine::add_logerror_callback(logerror_callback callback)
}
//-------------------------------------------------
// strlog - send an error logging string to the
// debugger and any OSD-defined output streams
//-------------------------------------------------
void running_machine::strlog(const char *str) const
{
// log to all callbacks
for (auto &cb : m_logerror_list)
cb->m_func(str);
}
//-------------------------------------------------
// debug_break - breaks into the debugger, if
// enabled

View File

@ -19,9 +19,6 @@
#include <functional>
#include "strformat.h"
#include "vecstream.h"
#include <time.h>
// forward declaration instead of osdepend.h
@ -198,6 +195,7 @@ public:
emu_options &options() const { return m_config.options(); }
attotime time() const { return m_scheduler.time(); }
bool scheduled_event_pending() const { return m_exit_pending || m_hard_reset_pending; }
bool allow_logging() const { return !m_logerror_list.empty(); }
// fetch items by name
inline device_t *device(const char *tag) const { return root_device().subdevice(tag); }
@ -233,6 +231,7 @@ public:
void popmessage() const { popmessage(static_cast<char const *>(nullptr)); }
template <typename Format, typename... Params> void popmessage(Format &&fmt, Params &&... args) const;
template <typename Format, typename... Params> void logerror(Format &&fmt, Params &&... args) const;
void strlog(const char *str) const;
UINT32 rand();
const char *describe_context();
@ -387,7 +386,7 @@ template <typename Format, typename... Params>
inline void running_machine::logerror(Format &&fmt, Params &&... args) const
{
// process only if there is a target
if (!m_logerror_list.empty())
if (allow_logging())
{
g_profiler.start(PROFILER_LOGERROR);
@ -397,10 +396,7 @@ inline void running_machine::logerror(Format &&fmt, Params &&... args) const
util::stream_format(m_string_buffer, std::forward<Format>(fmt), std::forward<Params>(args)...);
m_string_buffer.put('\0');
// log to all callbacks
char const *const str(&m_string_buffer.vec()[0]);
for (auto &cb : m_logerror_list)
cb->m_func(str);
strlog(&m_string_buffer.vec()[0]);
g_profiler.stop();
}