mirror of https://github.com/PCSX2/pcsx2.git
* Redid console logging to use stdout instead of the buffered queue (probably less buggy).
* Removed some hacks from cpuDetectInit's use of cpuId. * Improved assertion checking for thread affinity. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2327 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
94cdfb6a8b
commit
ba473e0a7f
|
@ -81,6 +81,10 @@ struct IConsoleWriter
|
||||||
// SetColor implementation for internal use only.
|
// SetColor implementation for internal use only.
|
||||||
void (__concall *DoSetColor)( ConsoleColors color );
|
void (__concall *DoSetColor)( ConsoleColors color );
|
||||||
|
|
||||||
|
// Special implementation of DoWrite that's pretty much for MSVC use only.
|
||||||
|
// All implementations should map to DoWrite, except Stdio which should map to Null.
|
||||||
|
void (__concall *DoWriteFromStdout)( const wxString& fmt );
|
||||||
|
|
||||||
void (__concall *Newline)();
|
void (__concall *Newline)();
|
||||||
void (__concall *SetTitle)( const wxString& title );
|
void (__concall *SetTitle)( const wxString& title );
|
||||||
|
|
||||||
|
@ -111,6 +115,9 @@ struct IConsoleWriter
|
||||||
bool Error( const wxChar* fmt, ... ) const;
|
bool Error( const wxChar* fmt, ... ) const;
|
||||||
bool Warning( const wxChar* fmt, ... ) const;
|
bool Warning( const wxChar* fmt, ... ) const;
|
||||||
|
|
||||||
|
bool WriteFromStdout( const char* fmt, ... ) const;
|
||||||
|
bool WriteFromStdout( ConsoleColors color, const char* fmt, ... ) const;
|
||||||
|
|
||||||
// internal value for indentation of individual lines. Use the Indent() member to invoke.
|
// internal value for indentation of individual lines. Use the Indent() member to invoke.
|
||||||
int _imm_indentation;
|
int _imm_indentation;
|
||||||
|
|
||||||
|
@ -209,7 +216,7 @@ extern void ConsoleBuffer_Clear();
|
||||||
extern void ConsoleBuffer_FlushToFile( FILE *fp );
|
extern void ConsoleBuffer_FlushToFile( FILE *fp );
|
||||||
|
|
||||||
extern const IConsoleWriter ConsoleWriter_Null;
|
extern const IConsoleWriter ConsoleWriter_Null;
|
||||||
extern const IConsoleWriter ConsoleWriter_Stdio;
|
extern const IConsoleWriter ConsoleWriter_Stdout;
|
||||||
extern const IConsoleWriter ConsoleWriter_Assert;
|
extern const IConsoleWriter ConsoleWriter_Assert;
|
||||||
extern const IConsoleWriter ConsoleWriter_Buffered;
|
extern const IConsoleWriter ConsoleWriter_Buffered;
|
||||||
extern const IConsoleWriter ConsoleWriter_wxError;
|
extern const IConsoleWriter ConsoleWriter_wxError;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#undef Yield // release th burden of windows.h global namespace spam.
|
#undef Yield // release th burden of windows.h global namespace spam.
|
||||||
|
|
||||||
#define AllowFromMainThreadOnly() \
|
#define AffinityAssert_AllowFromMain() \
|
||||||
pxAssertMsg( wxThread::IsMain(), "Thread affinity violation: Call allowed from main thread only." )
|
pxAssertMsg( wxThread::IsMain(), "Thread affinity violation: Call allowed from main thread only." )
|
||||||
|
|
||||||
class wxTimeSpan;
|
class wxTimeSpan;
|
||||||
|
@ -419,6 +419,9 @@ namespace Threading
|
||||||
|
|
||||||
void FrankenMutex( Mutex& mutex );
|
void FrankenMutex( Mutex& mutex );
|
||||||
|
|
||||||
|
bool AffinityAssert_AllowFromSelf() const;
|
||||||
|
bool AffinityAssert_DisallowFromSelf() const;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Section of methods for internal use only.
|
// Section of methods for internal use only.
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
|
|
||||||
using namespace Threading;
|
using namespace Threading;
|
||||||
|
|
||||||
|
static wxString m_buffer; // used by ConsoleBuffer
|
||||||
|
static Mutex m_bufferlock; // used by ConsoleBuffer
|
||||||
|
|
||||||
// This function re-assigns the console log writer(s) to the specified target. It makes sure
|
// This function re-assigns the console log writer(s) to the specified target. It makes sure
|
||||||
// to flush any contents from the buffered console log (which typically accumulates due to
|
// to flush any contents from the buffered console log (which typically accumulates due to
|
||||||
// log suspension during log file/window re-init operations) into the new log.
|
// log suspension during log file/window re-init operations) into the new log.
|
||||||
|
@ -34,8 +37,12 @@ void Console_SetActiveHandler( const IConsoleWriter& writer, FILE* flushfp )
|
||||||
"Invalid IConsoleWriter object! All function pointer interfaces must be implemented."
|
"Invalid IConsoleWriter object! All function pointer interfaces must be implemented."
|
||||||
);
|
);
|
||||||
|
|
||||||
if( !ConsoleBuffer_Get().IsEmpty() )
|
if( &writer != &ConsoleWriter_Buffered )
|
||||||
writer.DoWriteLn( ConsoleBuffer_Get() );
|
{
|
||||||
|
ScopedLock lock( m_bufferlock );
|
||||||
|
if( !ConsoleBuffer_Get().IsEmpty() )
|
||||||
|
writer.DoWriteLn( ConsoleBuffer_Get() );
|
||||||
|
}
|
||||||
|
|
||||||
Console = writer;
|
Console = writer;
|
||||||
|
|
||||||
|
@ -64,6 +71,7 @@ const IConsoleWriter ConsoleWriter_Null =
|
||||||
ConsoleNull_DoWriteLn,
|
ConsoleNull_DoWriteLn,
|
||||||
ConsoleNull_DoSetColor,
|
ConsoleNull_DoSetColor,
|
||||||
|
|
||||||
|
ConsoleNull_DoWrite,
|
||||||
ConsoleNull_Newline,
|
ConsoleNull_Newline,
|
||||||
ConsoleNull_SetTitle,
|
ConsoleNull_SetTitle,
|
||||||
|
|
||||||
|
@ -71,7 +79,7 @@ const IConsoleWriter ConsoleWriter_Null =
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// Console_Stdio
|
// Console_Stdout
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef __LINUX__
|
#ifdef __LINUX__
|
||||||
|
@ -117,23 +125,23 @@ static __forceinline const wxChar* GetLinuxConsoleColor(ConsoleColors color)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// One possible default write action at startup and shutdown is to use the stdout.
|
// One possible default write action at startup and shutdown is to use the stdout.
|
||||||
static void __concall ConsoleStdio_DoWrite( const wxString& fmt )
|
static void __concall ConsoleStdout_DoWrite( const wxString& fmt )
|
||||||
{
|
{
|
||||||
wxPrintf( fmt );
|
wxPrintf( fmt );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default write action at startup and shutdown is to use the stdout.
|
// Default write action at startup and shutdown is to use the stdout.
|
||||||
static void __concall ConsoleStdio_DoWriteLn( const wxString& fmt )
|
static void __concall ConsoleStdout_DoWriteLn( const wxString& fmt )
|
||||||
{
|
{
|
||||||
wxPrintf( fmt + L"\n" );
|
wxPrintf( fmt + L"\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __concall ConsoleStdio_Newline()
|
static void __concall ConsoleStdout_Newline()
|
||||||
{
|
{
|
||||||
wxPrintf( L"\n" );
|
wxPrintf( L"\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __concall ConsoleStdio_DoSetColor( ConsoleColors color )
|
static void __concall ConsoleStdout_DoSetColor( ConsoleColors color )
|
||||||
{
|
{
|
||||||
#ifdef __LINUX__
|
#ifdef __LINUX__
|
||||||
wxPrintf(L"\033[0m");
|
wxPrintf(L"\033[0m");
|
||||||
|
@ -141,21 +149,22 @@ static void __concall ConsoleStdio_DoSetColor( ConsoleColors color )
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __concall ConsoleStdio_SetTitle( const wxString& title )
|
static void __concall ConsoleStdout_SetTitle( const wxString& title )
|
||||||
{
|
{
|
||||||
#ifdef __LINUX__
|
#ifdef __LINUX__
|
||||||
wxPrintf(L"\033]0;" + title + L"\007");
|
wxPrintf(L"\033]0;" + title + L"\007");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const IConsoleWriter ConsoleWriter_Stdio =
|
const IConsoleWriter ConsoleWriter_Stdout =
|
||||||
{
|
{
|
||||||
ConsoleStdio_DoWrite, // Writes without newlines go to buffer to avoid error log spam.
|
ConsoleStdout_DoWrite, // Writes without newlines go to buffer to avoid error log spam.
|
||||||
ConsoleStdio_DoWriteLn,
|
ConsoleStdout_DoWriteLn,
|
||||||
ConsoleStdio_DoSetColor,
|
ConsoleStdout_DoSetColor,
|
||||||
|
|
||||||
ConsoleStdio_Newline,
|
ConsoleNull_DoWrite, // writes from stdout are ignored here, lest we create infinite loop hell >_<
|
||||||
ConsoleStdio_SetTitle,
|
ConsoleStdout_Newline,
|
||||||
|
ConsoleStdout_SetTitle,
|
||||||
|
|
||||||
0, // instance-level indentation (should always be 0)
|
0, // instance-level indentation (should always be 0)
|
||||||
};
|
};
|
||||||
|
@ -180,6 +189,7 @@ const IConsoleWriter ConsoleWriter_Assert =
|
||||||
ConsoleAssert_DoWriteLn,
|
ConsoleAssert_DoWriteLn,
|
||||||
ConsoleNull_DoSetColor,
|
ConsoleNull_DoSetColor,
|
||||||
|
|
||||||
|
ConsoleNull_DoWrite,
|
||||||
ConsoleNull_Newline,
|
ConsoleNull_Newline,
|
||||||
ConsoleNull_SetTitle,
|
ConsoleNull_SetTitle,
|
||||||
|
|
||||||
|
@ -190,8 +200,6 @@ const IConsoleWriter ConsoleWriter_Assert =
|
||||||
// ConsoleBuffer
|
// ConsoleBuffer
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
static wxString m_buffer;
|
|
||||||
|
|
||||||
const wxString& ConsoleBuffer_Get()
|
const wxString& ConsoleBuffer_Get()
|
||||||
{
|
{
|
||||||
return m_buffer;
|
return m_buffer;
|
||||||
|
@ -199,6 +207,7 @@ const wxString& ConsoleBuffer_Get()
|
||||||
|
|
||||||
void ConsoleBuffer_Clear()
|
void ConsoleBuffer_Clear()
|
||||||
{
|
{
|
||||||
|
ScopedLock lock( m_bufferlock );
|
||||||
m_buffer.Clear();
|
m_buffer.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +215,7 @@ void ConsoleBuffer_Clear()
|
||||||
// clears the buffer contents to 0.
|
// clears the buffer contents to 0.
|
||||||
void ConsoleBuffer_FlushToFile( FILE *fp )
|
void ConsoleBuffer_FlushToFile( FILE *fp )
|
||||||
{
|
{
|
||||||
|
ScopedLock lock( m_bufferlock );
|
||||||
if( fp == NULL || m_buffer.IsEmpty() ) return;
|
if( fp == NULL || m_buffer.IsEmpty() ) return;
|
||||||
px_fputs( fp, m_buffer.ToUTF8() );
|
px_fputs( fp, m_buffer.ToUTF8() );
|
||||||
m_buffer.Clear();
|
m_buffer.Clear();
|
||||||
|
@ -213,11 +223,13 @@ void ConsoleBuffer_FlushToFile( FILE *fp )
|
||||||
|
|
||||||
static void __concall ConsoleBuffer_DoWrite( const wxString& fmt )
|
static void __concall ConsoleBuffer_DoWrite( const wxString& fmt )
|
||||||
{
|
{
|
||||||
|
ScopedLock lock( m_bufferlock );
|
||||||
m_buffer += fmt;
|
m_buffer += fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __concall ConsoleBuffer_DoWriteLn( const wxString& fmt )
|
static void __concall ConsoleBuffer_DoWriteLn( const wxString& fmt )
|
||||||
{
|
{
|
||||||
|
ScopedLock lock( m_bufferlock );
|
||||||
m_buffer += fmt + L"\n";
|
m_buffer += fmt + L"\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,6 +239,7 @@ const IConsoleWriter ConsoleWriter_Buffered =
|
||||||
ConsoleBuffer_DoWriteLn,
|
ConsoleBuffer_DoWriteLn,
|
||||||
ConsoleNull_DoSetColor,
|
ConsoleNull_DoSetColor,
|
||||||
|
|
||||||
|
ConsoleBuffer_DoWrite,
|
||||||
ConsoleNull_Newline,
|
ConsoleNull_Newline,
|
||||||
ConsoleNull_SetTitle,
|
ConsoleNull_SetTitle,
|
||||||
|
|
||||||
|
@ -253,6 +266,7 @@ const IConsoleWriter ConsoleWriter_wxError =
|
||||||
Console_wxLogError_DoWriteLn,
|
Console_wxLogError_DoWriteLn,
|
||||||
ConsoleNull_DoSetColor,
|
ConsoleNull_DoSetColor,
|
||||||
|
|
||||||
|
ConsoleBuffer_DoWrite,
|
||||||
ConsoleNull_Newline,
|
ConsoleNull_Newline,
|
||||||
ConsoleNull_SetTitle,
|
ConsoleNull_SetTitle,
|
||||||
|
|
||||||
|
@ -616,6 +630,36 @@ bool IConsoleWriter::Warning( const wxChar* fmt, ... ) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool IConsoleWriter::WriteFromStdout( const char* fmt, ... ) const
|
||||||
|
{
|
||||||
|
if( DoWriteFromStdout == ConsoleNull_DoWrite ) return false;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args,fmt);
|
||||||
|
DoWrite( ascii_format_string(fmt, args) );
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IConsoleWriter::WriteFromStdout( ConsoleColors color, const char* fmt, ... ) const
|
||||||
|
{
|
||||||
|
if( DoWriteFromStdout == ConsoleNull_DoWrite ) return false;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args,fmt);
|
||||||
|
ConsoleColorScope cs( color );
|
||||||
|
DoWrite( ascii_format_string(fmt, args) );
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// Default Writer for C++ init / startup:
|
// Default Writer for C++ init / startup:
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -627,7 +671,7 @@ bool IConsoleWriter::Warning( const wxChar* fmt, ... ) const
|
||||||
#if wxUSE_GUI && defined(__WXMSW__)
|
#if wxUSE_GUI && defined(__WXMSW__)
|
||||||
# define _DefaultWriter_ ConsoleWriter_Assert
|
# define _DefaultWriter_ ConsoleWriter_Assert
|
||||||
#else
|
#else
|
||||||
# define _DefaultWriter_ ConsoleWriter_Stdio
|
# define _DefaultWriter_ ConsoleWriter_Stdout
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Important! Only Assert and Null console loggers are allowed for initial console targeting.
|
// Important! Only Assert and Null console loggers are allowed for initial console targeting.
|
||||||
|
|
|
@ -67,12 +67,12 @@ void Threading::PersistentThread::_pt_callback_cleanup( void* handle )
|
||||||
((PersistentThread*)handle)->_ThreadCleanup();
|
((PersistentThread*)handle)->_ThreadCleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
Threading::PersistentThread::PersistentThread() :
|
Threading::PersistentThread::PersistentThread()
|
||||||
m_name( L"PersistentThread" )
|
: m_name( L"PersistentThread" )
|
||||||
, m_thread()
|
, m_thread()
|
||||||
, m_sem_event()
|
, m_sem_event()
|
||||||
, m_lock_InThread()
|
, m_lock_InThread()
|
||||||
, m_lock_start()
|
, m_lock_start()
|
||||||
{
|
{
|
||||||
m_detached = true; // start out with m_thread in detached/invalid state
|
m_detached = true; // start out with m_thread in detached/invalid state
|
||||||
m_running = false;
|
m_running = false;
|
||||||
|
@ -116,6 +116,16 @@ Threading::PersistentThread::~PersistentThread() throw()
|
||||||
DESTRUCTOR_CATCHALL
|
DESTRUCTOR_CATCHALL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Threading::PersistentThread::AffinityAssert_AllowFromSelf() const
|
||||||
|
{
|
||||||
|
return pxAssertMsg( IsSelf(), wxsFormat( L"Thread affinity violation: Call allowed from '%s' thread only.", m_name ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Threading::PersistentThread::AffinityAssert_DisallowFromSelf() const
|
||||||
|
{
|
||||||
|
return pxAssertMsg( !IsSelf(), wxsFormat( L"Thread affinity violation: Call is *not* allowed from '%s' thread.", m_name ) );
|
||||||
|
}
|
||||||
|
|
||||||
void Threading::PersistentThread::FrankenMutex( Mutex& mutex )
|
void Threading::PersistentThread::FrankenMutex( Mutex& mutex )
|
||||||
{
|
{
|
||||||
if( mutex.RecreateIfLocked() )
|
if( mutex.RecreateIfLocked() )
|
||||||
|
@ -155,7 +165,7 @@ void Threading::PersistentThread::Start()
|
||||||
// This function should not be called from the owner thread.
|
// This function should not be called from the owner thread.
|
||||||
bool Threading::PersistentThread::Detach()
|
bool Threading::PersistentThread::Detach()
|
||||||
{
|
{
|
||||||
pxAssertMsg( !IsSelf(), "Thread affinity error." ); // not allowed from our own thread.
|
AffinityAssert_DisallowFromSelf();
|
||||||
|
|
||||||
if( _InterlockedExchange( &m_detached, true ) ) return false;
|
if( _InterlockedExchange( &m_detached, true ) ) return false;
|
||||||
pthread_detach( m_thread );
|
pthread_detach( m_thread );
|
||||||
|
@ -175,7 +185,7 @@ bool Threading::PersistentThread::Detach()
|
||||||
//
|
//
|
||||||
void Threading::PersistentThread::Cancel( bool isBlocking )
|
void Threading::PersistentThread::Cancel( bool isBlocking )
|
||||||
{
|
{
|
||||||
pxAssertMsg( !IsSelf(), "Thread affinity error." );
|
AffinityAssert_DisallowFromSelf();
|
||||||
|
|
||||||
{
|
{
|
||||||
// Prevent simultaneous startup and cancel:
|
// Prevent simultaneous startup and cancel:
|
||||||
|
@ -210,8 +220,7 @@ void Threading::PersistentThread::Cancel( bool isBlocking )
|
||||||
//
|
//
|
||||||
void Threading::PersistentThread::Block()
|
void Threading::PersistentThread::Block()
|
||||||
{
|
{
|
||||||
pxAssertDev( !IsSelf(), "Thread deadlock detected; Block() should never be called by the owner thread." );
|
AffinityAssert_DisallowFromSelf();
|
||||||
|
|
||||||
m_lock_InThread.Wait();
|
m_lock_InThread.Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +277,7 @@ void Threading::PersistentThread::_selfRunningTest( const wxChar* name ) const
|
||||||
//
|
//
|
||||||
void Threading::PersistentThread::WaitOnSelf( Semaphore& sem ) const
|
void Threading::PersistentThread::WaitOnSelf( Semaphore& sem ) const
|
||||||
{
|
{
|
||||||
if( !pxAssertDev( !IsSelf(), "WaitOnSelf called from inside the blocking thread (invalid operation!)" ) ) return;
|
if( !AffinityAssert_DisallowFromSelf() ) return;
|
||||||
|
|
||||||
while( true )
|
while( true )
|
||||||
{
|
{
|
||||||
|
@ -292,7 +301,7 @@ void Threading::PersistentThread::WaitOnSelf( Semaphore& sem ) const
|
||||||
//
|
//
|
||||||
void Threading::PersistentThread::WaitOnSelf( Mutex& mutex ) const
|
void Threading::PersistentThread::WaitOnSelf( Mutex& mutex ) const
|
||||||
{
|
{
|
||||||
if( !pxAssertDev( !IsSelf(), "WaitOnSelf called from inside the blocking thread (invalid operation!)" ) ) return;
|
if( !AffinityAssert_DisallowFromSelf() ) return;
|
||||||
|
|
||||||
while( true )
|
while( true )
|
||||||
{
|
{
|
||||||
|
@ -305,7 +314,7 @@ static const wxTimeSpan SelfWaitInterval( 0,0,0,333 );
|
||||||
|
|
||||||
bool Threading::PersistentThread::WaitOnSelf( Semaphore& sem, const wxTimeSpan& timeout ) const
|
bool Threading::PersistentThread::WaitOnSelf( Semaphore& sem, const wxTimeSpan& timeout ) const
|
||||||
{
|
{
|
||||||
if( !pxAssertDev( !IsSelf(), "WaitOnSelf called from inside the blocking thread (invalid operation!)" ) ) return true;
|
if( !AffinityAssert_DisallowFromSelf() ) return true;
|
||||||
|
|
||||||
wxTimeSpan runningout( timeout );
|
wxTimeSpan runningout( timeout );
|
||||||
|
|
||||||
|
@ -321,7 +330,7 @@ bool Threading::PersistentThread::WaitOnSelf( Semaphore& sem, const wxTimeSpan&
|
||||||
|
|
||||||
bool Threading::PersistentThread::WaitOnSelf( Mutex& mutex, const wxTimeSpan& timeout ) const
|
bool Threading::PersistentThread::WaitOnSelf( Mutex& mutex, const wxTimeSpan& timeout ) const
|
||||||
{
|
{
|
||||||
if( !pxAssertDev( !IsSelf(), "WaitOnSelf called from inside the blocking thread (invalid operation!)" ) ) return true;
|
if( !AffinityAssert_DisallowFromSelf() ) return true;
|
||||||
|
|
||||||
wxTimeSpan runningout( timeout );
|
wxTimeSpan runningout( timeout );
|
||||||
|
|
||||||
|
@ -341,7 +350,7 @@ bool Threading::PersistentThread::WaitOnSelf( Mutex& mutex, const wxTimeSpan& ti
|
||||||
// and cleanup, or use the DoThreadCleanup() override to perform resource cleanup).
|
// and cleanup, or use the DoThreadCleanup() override to perform resource cleanup).
|
||||||
void Threading::PersistentThread::TestCancel() const
|
void Threading::PersistentThread::TestCancel() const
|
||||||
{
|
{
|
||||||
pxAssert( IsSelf() );
|
AffinityAssert_AllowFromSelf();
|
||||||
pthread_testcancel();
|
pthread_testcancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,10 +431,8 @@ void Threading::PersistentThread::_try_virtual_invoke( void (PersistentThread::*
|
||||||
// OnCleanupInThread() to extend cleanup functionality.
|
// OnCleanupInThread() to extend cleanup functionality.
|
||||||
void Threading::PersistentThread::_ThreadCleanup()
|
void Threading::PersistentThread::_ThreadCleanup()
|
||||||
{
|
{
|
||||||
pxAssertMsg( IsSelf(), "Thread affinity error." ); // only allowed from our own thread, thanks.
|
AffinityAssert_AllowFromSelf();
|
||||||
|
|
||||||
_try_virtual_invoke( &PersistentThread::OnCleanupInThread );
|
_try_virtual_invoke( &PersistentThread::OnCleanupInThread );
|
||||||
|
|
||||||
m_lock_InThread.Release();
|
m_lock_InThread.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,7 +493,7 @@ void Threading::PersistentThread::_DoSetThreadName( const wxString& name )
|
||||||
|
|
||||||
void Threading::PersistentThread::_DoSetThreadName( const char* name )
|
void Threading::PersistentThread::_DoSetThreadName( const char* name )
|
||||||
{
|
{
|
||||||
pxAssertMsg( IsSelf(), "Thread affinity error." ); // only allowed from our own thread, thanks.
|
if( !AffinityAssert_AllowFromSelf() ) return;
|
||||||
|
|
||||||
// This feature needs Windows headers and MSVC's SEH support:
|
// This feature needs Windows headers and MSVC's SEH support:
|
||||||
|
|
||||||
|
|
|
@ -17,13 +17,9 @@
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "cpudetect_internal.h"
|
#include "cpudetect_internal.h"
|
||||||
|
|
||||||
s32 iCpuId( u32 cmd, u32 *regs )
|
void iCpuId( u32 cmd, u32 *regs )
|
||||||
{
|
{
|
||||||
// ecx should be zero for CPUID(4)
|
|
||||||
__asm__ __volatile__ ( "xor %ecx, %ecx" );
|
|
||||||
|
|
||||||
__cpuid( (int*)regs, cmd );
|
__cpuid( (int*)regs, cmd );
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: Apparently this solution is Linux/Solaris only.
|
// Note: Apparently this solution is Linux/Solaris only.
|
||||||
|
|
|
@ -17,12 +17,10 @@
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "cpudetect_internal.h"
|
#include "cpudetect_internal.h"
|
||||||
|
|
||||||
s32 iCpuId( u32 cmd, u32 *regs )
|
void iCpuId( u32 cmd, u32 *regs )
|
||||||
{
|
{
|
||||||
// ecx should be zero for CPUID(4)
|
// ecx should be zero for CPUID(4)
|
||||||
__asm xor ecx, ecx;
|
|
||||||
__cpuid( (int*)regs, cmd );
|
__cpuid( (int*)regs, cmd );
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU )
|
void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU )
|
||||||
|
@ -54,7 +52,8 @@ void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhys
|
||||||
bool _test_instruction( void* pfnCall )
|
bool _test_instruction( void* pfnCall )
|
||||||
{
|
{
|
||||||
__try {
|
__try {
|
||||||
((void (*)())pfnCall)();
|
u128 regsave;
|
||||||
|
((void (__fastcall *)(void*))pfnCall)( ®save );
|
||||||
}
|
}
|
||||||
__except(EXCEPTION_EXECUTE_HANDLER) {
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -68,79 +68,72 @@ static s64 CPUSpeedHz( u64 time )
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
void cpudetectInit()
|
void cpudetectInit()
|
||||||
{
|
{
|
||||||
u32 regs[ 4 ];
|
u32 regs[ 4 ];
|
||||||
u32 cmds;
|
u32 cmds;
|
||||||
//AMD 64 STUFF
|
//AMD 64 STUFF
|
||||||
u32 x86_64_8BITBRANDID;
|
u32 x86_64_8BITBRANDID;
|
||||||
u32 x86_64_12BITBRANDID;
|
u32 x86_64_12BITBRANDID;
|
||||||
|
|
||||||
memzero( x86caps.VendorName );
|
memzero( x86caps.VendorName );
|
||||||
x86caps.FamilyID = 0;
|
x86caps.FamilyID = 0;
|
||||||
x86caps.Model = 0;
|
x86caps.Model = 0;
|
||||||
x86caps.TypeID = 0;
|
x86caps.TypeID = 0;
|
||||||
x86caps.StepID = 0;
|
x86caps.StepID = 0;
|
||||||
x86caps.Flags = 0;
|
x86caps.Flags = 0;
|
||||||
x86caps.EFlags = 0;
|
x86caps.EFlags = 0;
|
||||||
|
|
||||||
if ( iCpuId( 0, regs ) == -1 ) return;
|
//memzero( regs );
|
||||||
|
iCpuId( 0, regs );
|
||||||
|
|
||||||
cmds = regs[ 0 ];
|
cmds = regs[ 0 ];
|
||||||
((u32*)x86caps.VendorName)[ 0 ] = regs[ 1 ];
|
((u32*)x86caps.VendorName)[ 0 ] = regs[ 1 ];
|
||||||
((u32*)x86caps.VendorName)[ 1 ] = regs[ 3 ];
|
((u32*)x86caps.VendorName)[ 1 ] = regs[ 3 ];
|
||||||
((u32*)x86caps.VendorName)[ 2 ] = regs[ 2 ];
|
((u32*)x86caps.VendorName)[ 2 ] = regs[ 2 ];
|
||||||
|
|
||||||
u32 LogicalCoresPerPhysicalCPU = 0;
|
u32 LogicalCoresPerPhysicalCPU = 0;
|
||||||
u32 PhysicalCoresPerPhysicalCPU = 1;
|
u32 PhysicalCoresPerPhysicalCPU = 1;
|
||||||
|
|
||||||
if ( cmds >= 0x00000001 )
|
if ( cmds >= 0x00000001 )
|
||||||
{
|
{
|
||||||
if ( iCpuId( 0x00000001, regs ) != -1 )
|
iCpuId( 0x00000001, regs );
|
||||||
{
|
|
||||||
x86caps.StepID = regs[ 0 ] & 0xf;
|
|
||||||
x86caps.Model = (regs[ 0 ] >> 4) & 0xf;
|
|
||||||
x86caps.FamilyID = (regs[ 0 ] >> 8) & 0xf;
|
|
||||||
x86caps.TypeID = (regs[ 0 ] >> 12) & 0x3;
|
|
||||||
LogicalCoresPerPhysicalCPU = ( regs[1] >> 16 ) & 0xff;
|
|
||||||
x86_64_8BITBRANDID = regs[ 1 ] & 0xff;
|
|
||||||
x86caps.Flags = regs[ 3 ];
|
|
||||||
x86caps.Flags2 = regs[ 2 ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// detect multicore for Intel cpu
|
x86caps.StepID = regs[ 0 ] & 0xf;
|
||||||
|
x86caps.Model = (regs[ 0 ] >> 4) & 0xf;
|
||||||
|
x86caps.FamilyID = (regs[ 0 ] >> 8) & 0xf;
|
||||||
|
x86caps.TypeID = (regs[ 0 ] >> 12) & 0x3;
|
||||||
|
x86_64_8BITBRANDID = regs[ 1 ] & 0xff;
|
||||||
|
x86caps.Flags = regs[ 3 ];
|
||||||
|
x86caps.Flags2 = regs[ 2 ];
|
||||||
|
|
||||||
if ((cmds >= 0x00000004) && !strcmp("GenuineIntel",x86caps.VendorName))
|
LogicalCoresPerPhysicalCPU = ( regs[1] >> 16 ) & 0xff;
|
||||||
{
|
}
|
||||||
if ( iCpuId( 0x00000004, regs ) != -1 )
|
|
||||||
{
|
|
||||||
PhysicalCoresPerPhysicalCPU += ( regs[0] >> 26) & 0x3f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( iCpuId( 0x80000000, regs ) != -1 )
|
// detect multicore for Intel cpu
|
||||||
{
|
|
||||||
cmds = regs[ 0 ];
|
|
||||||
if ( cmds >= 0x80000001 )
|
|
||||||
{
|
|
||||||
if ( iCpuId( 0x80000001, regs ) != -1 )
|
|
||||||
{
|
|
||||||
x86_64_12BITBRANDID = regs[1] & 0xfff;
|
|
||||||
x86caps.EFlags2 = regs[ 2 ];
|
|
||||||
x86caps.EFlags = regs[ 3 ];
|
|
||||||
|
|
||||||
}
|
if ((cmds >= 0x00000004) && !strcmp("GenuineIntel",x86caps.VendorName))
|
||||||
}
|
{
|
||||||
|
iCpuId( 0x00000004, regs );
|
||||||
// detect multicore for AMD cpu
|
PhysicalCoresPerPhysicalCPU += ( regs[0] >> 26) & 0x3f;
|
||||||
|
}
|
||||||
if ((cmds >= 0x80000008) && !strcmp("AuthenticAMD",x86caps.VendorName))
|
|
||||||
{
|
iCpuId( 0x80000000, regs );
|
||||||
if ( iCpuId( 0x80000008, regs ) != -1 )
|
cmds = regs[ 0 ];
|
||||||
{
|
if ( cmds >= 0x80000001 )
|
||||||
PhysicalCoresPerPhysicalCPU += ( regs[2] ) & 0xff;
|
{
|
||||||
}
|
iCpuId( 0x80000001, regs );
|
||||||
}
|
|
||||||
}
|
x86_64_12BITBRANDID = regs[1] & 0xfff;
|
||||||
|
x86caps.EFlags2 = regs[ 2 ];
|
||||||
|
x86caps.EFlags = regs[ 3 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
// detect multicore for AMD cpu
|
||||||
|
|
||||||
|
if ((cmds >= 0x80000008) && !strcmp("AuthenticAMD",x86caps.VendorName))
|
||||||
|
{
|
||||||
|
iCpuId( 0x80000008, regs );
|
||||||
|
PhysicalCoresPerPhysicalCPU += ( regs[2] ) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
switch(x86caps.TypeID)
|
switch(x86caps.TypeID)
|
||||||
{
|
{
|
||||||
|
@ -245,15 +238,21 @@ void cpudetectInit()
|
||||||
if( CanTestInstructionSets() )
|
if( CanTestInstructionSets() )
|
||||||
{
|
{
|
||||||
xSetPtr( recSSE );
|
xSetPtr( recSSE );
|
||||||
|
xMOVDQU( ptr[ecx], xmm1 );
|
||||||
xMOVSLDUP( xmm1, xmm0 );
|
xMOVSLDUP( xmm1, xmm0 );
|
||||||
|
xMOVDQU( xmm1, ptr[ecx] );
|
||||||
xRET();
|
xRET();
|
||||||
|
|
||||||
u8* funcSSSE3 = xGetPtr();
|
u8* funcSSSE3 = xGetPtr();
|
||||||
xPABS.W( xmm0, xmm1 );
|
xMOVDQU( ptr[ecx], xmm1 );
|
||||||
|
xPABS.W( xmm1, xmm0 );
|
||||||
|
xMOVDQU( xmm1, ptr[ecx] );
|
||||||
xRET();
|
xRET();
|
||||||
|
|
||||||
u8* funcSSE41 = xGetPtr();
|
u8* funcSSE41 = xGetPtr();
|
||||||
|
xMOVDQU( ptr[ecx], xmm1 );
|
||||||
xBLEND.VPD( xmm1, xmm0 );
|
xBLEND.VPD( xmm1, xmm0 );
|
||||||
|
xMOVDQU( xmm1, ptr[ecx] );
|
||||||
xRET();
|
xRET();
|
||||||
|
|
||||||
bool sse3_result = _test_instruction( recSSE ); // sse3
|
bool sse3_result = _test_instruction( recSSE ); // sse3
|
||||||
|
|
|
@ -53,4 +53,4 @@ public:
|
||||||
|
|
||||||
extern bool CanTestInstructionSets();
|
extern bool CanTestInstructionSets();
|
||||||
extern bool _test_instruction( void* pfnCall );
|
extern bool _test_instruction( void* pfnCall );
|
||||||
extern s32 iCpuId( u32 cmd, u32 *regs );
|
extern void iCpuId( u32 cmd, u32 *regs );
|
||||||
|
|
|
@ -37,21 +37,21 @@ const Pcsx2Config EmuConfig;
|
||||||
Pcsx2Config::GSOptions& SetGSConfig()
|
Pcsx2Config::GSOptions& SetGSConfig()
|
||||||
{
|
{
|
||||||
//DbgCon.WriteLn( "Direct modification of EmuConfig.GS detected" );
|
//DbgCon.WriteLn( "Direct modification of EmuConfig.GS detected" );
|
||||||
AllowFromMainThreadOnly();
|
AffinityAssert_AllowFromMain();
|
||||||
return const_cast<Pcsx2Config::GSOptions&>(EmuConfig.GS);
|
return const_cast<Pcsx2Config::GSOptions&>(EmuConfig.GS);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleLogFilters& SetConsoleConfig()
|
ConsoleLogFilters& SetConsoleConfig()
|
||||||
{
|
{
|
||||||
//DbgCon.WriteLn( "Direct modification of EmuConfig.Log detected" );
|
//DbgCon.WriteLn( "Direct modification of EmuConfig.Log detected" );
|
||||||
AllowFromMainThreadOnly();
|
AffinityAssert_AllowFromMain();
|
||||||
return const_cast<ConsoleLogFilters&>(EmuConfig.Log);
|
return const_cast<ConsoleLogFilters&>(EmuConfig.Log);
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceLogFilters& SetTraceConfig()
|
TraceLogFilters& SetTraceConfig()
|
||||||
{
|
{
|
||||||
//DbgCon.WriteLn( "Direct modification of EmuConfig.TraceLog detected" );
|
//DbgCon.WriteLn( "Direct modification of EmuConfig.TraceLog detected" );
|
||||||
AllowFromMainThreadOnly();
|
AffinityAssert_AllowFromMain();
|
||||||
return const_cast<TraceLogFilters&>(EmuConfig.Trace);
|
return const_cast<TraceLogFilters&>(EmuConfig.Trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ static int resume_tries = 0;
|
||||||
void AppCoreThread::Resume()
|
void AppCoreThread::Resume()
|
||||||
{
|
{
|
||||||
// Thread control (suspend / resume) should only be performed from the main/gui thread.
|
// Thread control (suspend / resume) should only be performed from the main/gui thread.
|
||||||
if( !AllowFromMainThreadOnly() ) return;
|
if( !AffinityAssert_AllowFromMain() ) return;
|
||||||
if( m_ExecMode == ExecMode_Opened ) return;
|
if( m_ExecMode == ExecMode_Opened ) return;
|
||||||
if( m_ResumeProtection.IsLocked() ) return;
|
if( m_ResumeProtection.IsLocked() ) return;
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ void Pcsx2App::PostPadKey( wxKeyEvent& evt )
|
||||||
|
|
||||||
int Pcsx2App::ThreadedModalDialog( DialogIdentifiers dialogId )
|
int Pcsx2App::ThreadedModalDialog( DialogIdentifiers dialogId )
|
||||||
{
|
{
|
||||||
AllowFromMainThreadOnly();
|
AffinityAssert_AllowFromMain();
|
||||||
|
|
||||||
MsgboxEventResult result;
|
MsgboxEventResult result;
|
||||||
wxCommandEvent joe( pxEVT_OpenModalDialog, dialogId );
|
wxCommandEvent joe( pxEVT_OpenModalDialog, dialogId );
|
||||||
|
@ -399,7 +399,7 @@ GSFrame& Pcsx2App::GetGSFrame() const
|
||||||
|
|
||||||
void AppApplySettings( const AppConfig* oldconf )
|
void AppApplySettings( const AppConfig* oldconf )
|
||||||
{
|
{
|
||||||
AllowFromMainThreadOnly();
|
AffinityAssert_AllowFromMain();
|
||||||
|
|
||||||
g_Conf->Folders.ApplyDefaults();
|
g_Conf->Folders.ApplyDefaults();
|
||||||
|
|
||||||
|
@ -452,7 +452,7 @@ AppIniLoader::AppIniLoader()
|
||||||
|
|
||||||
void AppLoadSettings()
|
void AppLoadSettings()
|
||||||
{
|
{
|
||||||
if( !AllowFromMainThreadOnly() ) return;
|
if( !AffinityAssert_AllowFromMain() ) return;
|
||||||
|
|
||||||
AppIniLoader loader;
|
AppIniLoader loader;
|
||||||
g_Conf->LoadSave( loader );
|
g_Conf->LoadSave( loader );
|
||||||
|
@ -461,7 +461,7 @@ void AppLoadSettings()
|
||||||
|
|
||||||
void AppSaveSettings()
|
void AppSaveSettings()
|
||||||
{
|
{
|
||||||
if( !AllowFromMainThreadOnly() ) return;
|
if( !AffinityAssert_AllowFromMain() ) return;
|
||||||
|
|
||||||
AppIniSaver saver;
|
AppIniSaver saver;
|
||||||
g_Conf->LoadSave( saver );
|
g_Conf->LoadSave( saver );
|
||||||
|
|
|
@ -589,9 +589,12 @@ void ConsoleLogFrame::OnIdleEvent( wxIdleEvent& evt )
|
||||||
void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& evt )
|
void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& evt )
|
||||||
{
|
{
|
||||||
ScopedLock locker( m_QueueLock );
|
ScopedLock locker( m_QueueLock );
|
||||||
|
|
||||||
m_pendingFlushMsg = false;
|
m_pendingFlushMsg = false;
|
||||||
//if( m_TextCtrl.HasWriteLock() ) return;
|
|
||||||
|
// recursion guard needed due to Mutex lock/acquire code below.
|
||||||
|
static int recursion_counter = 0;
|
||||||
|
RecursionGuard recguard( recursion_counter );
|
||||||
|
if( recguard.IsReentrant() ) return;
|
||||||
|
|
||||||
if( m_CurQueuePos != 0 )
|
if( m_CurQueuePos != 0 )
|
||||||
{
|
{
|
||||||
|
@ -609,7 +612,9 @@ void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& evt )
|
||||||
locker.Acquire();
|
locker.Acquire();
|
||||||
}
|
}
|
||||||
|
|
||||||
DoFlushQueue();
|
if( m_CurQueuePos != 0 )
|
||||||
|
DoFlushQueue();
|
||||||
|
|
||||||
//m_TextCtrl.Thaw();
|
//m_TextCtrl.Thaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,9 +623,6 @@ void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& evt )
|
||||||
// paperwork. But wxEVT_IDLE doesn't work when you click menus or the title bar of a window,
|
// paperwork. But wxEVT_IDLE doesn't work when you click menus or the title bar of a window,
|
||||||
// making it pretty well annoyingly useless for just about anything. >_<
|
// making it pretty well annoyingly useless for just about anything. >_<
|
||||||
|
|
||||||
// Workaround: I added a Sleep(1) to the DoWrite method to give the GUI some time to
|
|
||||||
// do its paperwork.
|
|
||||||
|
|
||||||
if( m_WaitingThreadsForFlush > 0 )
|
if( m_WaitingThreadsForFlush > 0 )
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
|
@ -702,7 +704,7 @@ void Pcsx2App::ProgramLog_PostEvent( wxEvent& evt )
|
||||||
static void __concall ConsoleToFile_Newline()
|
static void __concall ConsoleToFile_Newline()
|
||||||
{
|
{
|
||||||
#ifdef __LINUX__
|
#ifdef __LINUX__
|
||||||
if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdio.Newline();
|
if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdout.Newline();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __LINUX__
|
#ifdef __LINUX__
|
||||||
|
@ -715,7 +717,7 @@ static void __concall ConsoleToFile_Newline()
|
||||||
static void __concall ConsoleToFile_DoWrite( const wxString& fmt )
|
static void __concall ConsoleToFile_DoWrite( const wxString& fmt )
|
||||||
{
|
{
|
||||||
#ifdef __LINUX__
|
#ifdef __LINUX__
|
||||||
if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdio.DoWrite(fmt);
|
if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdout.DoWrite(fmt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
px_fputs( emuLog, fmt.ToUTF8() );
|
px_fputs( emuLog, fmt.ToUTF8() );
|
||||||
|
@ -731,12 +733,12 @@ static void __concall ConsoleToFile_DoWriteLn( const wxString& fmt )
|
||||||
|
|
||||||
static void __concall ConsoleToFile_SetTitle( const wxString& title )
|
static void __concall ConsoleToFile_SetTitle( const wxString& title )
|
||||||
{
|
{
|
||||||
ConsoleWriter_Stdio.SetTitle(title);
|
ConsoleWriter_Stdout.SetTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __concall ConsoleToFile_DoSetColor( ConsoleColors color )
|
static void __concall ConsoleToFile_DoSetColor( ConsoleColors color )
|
||||||
{
|
{
|
||||||
ConsoleWriter_Stdio.DoSetColor(color);
|
ConsoleWriter_Stdout.DoSetColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const IConsoleWriter ConsoleWriter_File;
|
extern const IConsoleWriter ConsoleWriter_File;
|
||||||
|
@ -746,6 +748,7 @@ const IConsoleWriter ConsoleWriter_File =
|
||||||
ConsoleToFile_DoWriteLn,
|
ConsoleToFile_DoWriteLn,
|
||||||
ConsoleToFile_DoSetColor,
|
ConsoleToFile_DoSetColor,
|
||||||
|
|
||||||
|
ConsoleToFile_DoWrite,
|
||||||
ConsoleToFile_Newline,
|
ConsoleToFile_Newline,
|
||||||
ConsoleToFile_SetTitle,
|
ConsoleToFile_SetTitle,
|
||||||
};
|
};
|
||||||
|
@ -799,6 +802,7 @@ static const IConsoleWriter ConsoleWriter_Window =
|
||||||
ConsoleToWindow_DoWriteLn<ConsoleWriter_Null>,
|
ConsoleToWindow_DoWriteLn<ConsoleWriter_Null>,
|
||||||
ConsoleToWindow_DoSetColor<ConsoleWriter_Null>,
|
ConsoleToWindow_DoSetColor<ConsoleWriter_Null>,
|
||||||
|
|
||||||
|
ConsoleToWindow_DoWrite<ConsoleWriter_Null>,
|
||||||
ConsoleToWindow_Newline<ConsoleWriter_Null>,
|
ConsoleToWindow_Newline<ConsoleWriter_Null>,
|
||||||
ConsoleToWindow_SetTitle<ConsoleWriter_Null>,
|
ConsoleToWindow_SetTitle<ConsoleWriter_Null>,
|
||||||
};
|
};
|
||||||
|
@ -809,6 +813,7 @@ static const IConsoleWriter ConsoleWriter_WindowAndFile =
|
||||||
ConsoleToWindow_DoWriteLn<ConsoleWriter_File>,
|
ConsoleToWindow_DoWriteLn<ConsoleWriter_File>,
|
||||||
ConsoleToWindow_DoSetColor<ConsoleWriter_File>,
|
ConsoleToWindow_DoSetColor<ConsoleWriter_File>,
|
||||||
|
|
||||||
|
ConsoleToWindow_DoWrite<ConsoleWriter_File>,
|
||||||
ConsoleToWindow_Newline<ConsoleWriter_File>,
|
ConsoleToWindow_Newline<ConsoleWriter_File>,
|
||||||
ConsoleToWindow_SetTitle<ConsoleWriter_File>,
|
ConsoleToWindow_SetTitle<ConsoleWriter_File>,
|
||||||
};
|
};
|
||||||
|
@ -818,14 +823,14 @@ void Pcsx2App::EnableAllLogging() const
|
||||||
if( emuLog )
|
if( emuLog )
|
||||||
Console_SetActiveHandler( (m_ProgramLogBox!=NULL) ? (IConsoleWriter&)ConsoleWriter_WindowAndFile : (IConsoleWriter&)ConsoleWriter_File );
|
Console_SetActiveHandler( (m_ProgramLogBox!=NULL) ? (IConsoleWriter&)ConsoleWriter_WindowAndFile : (IConsoleWriter&)ConsoleWriter_File );
|
||||||
else
|
else
|
||||||
Console_SetActiveHandler( (m_ProgramLogBox!=NULL) ? (IConsoleWriter&)ConsoleWriter_Window : (IConsoleWriter&)ConsoleWriter_Buffered );
|
Console_SetActiveHandler( (m_ProgramLogBox!=NULL) ? (IConsoleWriter&)ConsoleWriter_Window : (IConsoleWriter&)ConsoleWriter_Stdout );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to disable the emuLog disk logger, typically used when disabling or re-initializing the
|
// Used to disable the emuLog disk logger, typically used when disabling or re-initializing the
|
||||||
// emuLog file handle. Call SetConsoleLogging to re-enable the disk logger when finished.
|
// emuLog file handle. Call SetConsoleLogging to re-enable the disk logger when finished.
|
||||||
void Pcsx2App::DisableDiskLogging() const
|
void Pcsx2App::DisableDiskLogging() const
|
||||||
{
|
{
|
||||||
Console_SetActiveHandler( (m_ProgramLogBox!=NULL) ? (IConsoleWriter&)ConsoleWriter_Window : (IConsoleWriter&)ConsoleWriter_Buffered );
|
Console_SetActiveHandler( (m_ProgramLogBox!=NULL) ? (IConsoleWriter&)ConsoleWriter_Window : (IConsoleWriter&)ConsoleWriter_Stdout );
|
||||||
|
|
||||||
// Semi-hack: It's possible, however very unlikely, that a secondary thread could attempt
|
// Semi-hack: It's possible, however very unlikely, that a secondary thread could attempt
|
||||||
// to write to the logfile just before we disable logging, and would thus have a pending write
|
// to write to the logfile just before we disable logging, and would thus have a pending write
|
||||||
|
@ -834,7 +839,7 @@ void Pcsx2App::DisableDiskLogging() const
|
||||||
// when changing settings, so the chance for problems is low. We minimize it further here
|
// when changing settings, so the chance for problems is low. We minimize it further here
|
||||||
// by sleeping off 5ms, which should allow any pending log-to-disk events to finish up.
|
// by sleeping off 5ms, which should allow any pending log-to-disk events to finish up.
|
||||||
//
|
//
|
||||||
// (the most ideal solution would be a mutex lock in the Disk logger itself, but for now I
|
// (the most correct solution would be a mutex lock in the Disk logger itself, but for now I
|
||||||
// am going to try and keep the logger lock-free and use this semi-hack instead).
|
// am going to try and keep the logger lock-free and use this semi-hack instead).
|
||||||
|
|
||||||
Threading::Sleep( 5 );
|
Threading::Sleep( 5 );
|
||||||
|
@ -842,6 +847,6 @@ void Pcsx2App::DisableDiskLogging() const
|
||||||
|
|
||||||
void Pcsx2App::DisableWindowLogging() const
|
void Pcsx2App::DisableWindowLogging() const
|
||||||
{
|
{
|
||||||
Console_SetActiveHandler( (emuLog!=NULL) ? (IConsoleWriter&)ConsoleWriter_File : (IConsoleWriter&)ConsoleWriter_Buffered );
|
Console_SetActiveHandler( (emuLog!=NULL) ? (IConsoleWriter&)ConsoleWriter_File : (IConsoleWriter&)ConsoleWriter_Stdout );
|
||||||
Threading::Sleep( 5 );
|
Threading::Sleep( 5 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,9 +84,9 @@ protected:
|
||||||
const ConsoleColors m_color;
|
const ConsoleColors m_color;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WinPipeThread( const HANDLE& outpipe, ConsoleColors color ) :
|
WinPipeThread( const HANDLE& outpipe, ConsoleColors color )
|
||||||
m_outpipe( outpipe )
|
: m_outpipe( outpipe )
|
||||||
, m_color( color )
|
, m_color( color )
|
||||||
{
|
{
|
||||||
m_name = (m_color == Color_Red) ? L"Redirect_Stderr" : L"Redirect_Stdout";
|
m_name = (m_color == Color_Red) ? L"Redirect_Stderr" : L"Redirect_Stdout";
|
||||||
}
|
}
|
||||||
|
@ -150,8 +150,7 @@ protected:
|
||||||
|
|
||||||
// ATTENTION: The Console always prints ANSI to the pipe independent if compiled as UNICODE or MBCS!
|
// ATTENTION: The Console always prints ANSI to the pipe independent if compiled as UNICODE or MBCS!
|
||||||
s8_Buf[u32_Read] = 0;
|
s8_Buf[u32_Read] = 0;
|
||||||
OemToCharA(s8_Buf, s8_Buf); // convert DOS codepage -> ANSI
|
Console.WriteFromStdout( m_color, s8_Buf );
|
||||||
Console.Write( m_color, s8_Buf );
|
|
||||||
|
|
||||||
TestCancel();
|
TestCancel();
|
||||||
}
|
}
|
||||||
|
@ -187,12 +186,12 @@ public:
|
||||||
void Cleanup() throw();
|
void Cleanup() throw();
|
||||||
};
|
};
|
||||||
|
|
||||||
WinPipeRedirection::WinPipeRedirection( FILE* stdstream ) :
|
WinPipeRedirection::WinPipeRedirection( FILE* stdstream )
|
||||||
m_readpipe(INVALID_HANDLE_VALUE)
|
: m_readpipe(INVALID_HANDLE_VALUE)
|
||||||
, m_writepipe(INVALID_HANDLE_VALUE)
|
, m_writepipe(INVALID_HANDLE_VALUE)
|
||||||
, m_crtFile(-1)
|
, m_crtFile(-1)
|
||||||
, m_fp(NULL)
|
, m_fp(NULL)
|
||||||
, m_Thread( m_readpipe, (stdstream == stderr) ? Color_Red : Color_Black )
|
, m_Thread( m_readpipe, (stdstream == stderr) ? Color_Red : Color_Black )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -236,6 +235,7 @@ WinPipeRedirection::WinPipeRedirection( FILE* stdstream ) :
|
||||||
}
|
}
|
||||||
catch( ... )
|
catch( ... )
|
||||||
{
|
{
|
||||||
|
Cleanup();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue