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.
|
||||
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 *SetTitle)( const wxString& title );
|
||||
|
||||
|
@ -111,6 +115,9 @@ struct IConsoleWriter
|
|||
bool Error( 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.
|
||||
int _imm_indentation;
|
||||
|
||||
|
@ -209,7 +216,7 @@ extern void ConsoleBuffer_Clear();
|
|||
extern void ConsoleBuffer_FlushToFile( FILE *fp );
|
||||
|
||||
extern const IConsoleWriter ConsoleWriter_Null;
|
||||
extern const IConsoleWriter ConsoleWriter_Stdio;
|
||||
extern const IConsoleWriter ConsoleWriter_Stdout;
|
||||
extern const IConsoleWriter ConsoleWriter_Assert;
|
||||
extern const IConsoleWriter ConsoleWriter_Buffered;
|
||||
extern const IConsoleWriter ConsoleWriter_wxError;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#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." )
|
||||
|
||||
class wxTimeSpan;
|
||||
|
@ -419,6 +419,9 @@ namespace Threading
|
|||
|
||||
void FrankenMutex( Mutex& mutex );
|
||||
|
||||
bool AffinityAssert_AllowFromSelf() const;
|
||||
bool AffinityAssert_DisallowFromSelf() const;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Section of methods for internal use only.
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
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
|
||||
// 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.
|
||||
|
@ -34,8 +37,12 @@ void Console_SetActiveHandler( const IConsoleWriter& writer, FILE* flushfp )
|
|||
"Invalid IConsoleWriter object! All function pointer interfaces must be implemented."
|
||||
);
|
||||
|
||||
if( !ConsoleBuffer_Get().IsEmpty() )
|
||||
writer.DoWriteLn( ConsoleBuffer_Get() );
|
||||
if( &writer != &ConsoleWriter_Buffered )
|
||||
{
|
||||
ScopedLock lock( m_bufferlock );
|
||||
if( !ConsoleBuffer_Get().IsEmpty() )
|
||||
writer.DoWriteLn( ConsoleBuffer_Get() );
|
||||
}
|
||||
|
||||
Console = writer;
|
||||
|
||||
|
@ -64,6 +71,7 @@ const IConsoleWriter ConsoleWriter_Null =
|
|||
ConsoleNull_DoWriteLn,
|
||||
ConsoleNull_DoSetColor,
|
||||
|
||||
ConsoleNull_DoWrite,
|
||||
ConsoleNull_Newline,
|
||||
ConsoleNull_SetTitle,
|
||||
|
||||
|
@ -71,7 +79,7 @@ const IConsoleWriter ConsoleWriter_Null =
|
|||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Console_Stdio
|
||||
// Console_Stdout
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef __LINUX__
|
||||
|
@ -117,23 +125,23 @@ static __forceinline const wxChar* GetLinuxConsoleColor(ConsoleColors color)
|
|||
#endif
|
||||
|
||||
// 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 );
|
||||
}
|
||||
|
||||
// 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" );
|
||||
}
|
||||
|
||||
static void __concall ConsoleStdio_Newline()
|
||||
static void __concall ConsoleStdout_Newline()
|
||||
{
|
||||
wxPrintf( L"\n" );
|
||||
}
|
||||
|
||||
static void __concall ConsoleStdio_DoSetColor( ConsoleColors color )
|
||||
static void __concall ConsoleStdout_DoSetColor( ConsoleColors color )
|
||||
{
|
||||
#ifdef __LINUX__
|
||||
wxPrintf(L"\033[0m");
|
||||
|
@ -141,21 +149,22 @@ static void __concall ConsoleStdio_DoSetColor( ConsoleColors color )
|
|||
#endif
|
||||
}
|
||||
|
||||
static void __concall ConsoleStdio_SetTitle( const wxString& title )
|
||||
static void __concall ConsoleStdout_SetTitle( const wxString& title )
|
||||
{
|
||||
#ifdef __LINUX__
|
||||
wxPrintf(L"\033]0;" + title + L"\007");
|
||||
#endif
|
||||
}
|
||||
|
||||
const IConsoleWriter ConsoleWriter_Stdio =
|
||||
const IConsoleWriter ConsoleWriter_Stdout =
|
||||
{
|
||||
ConsoleStdio_DoWrite, // Writes without newlines go to buffer to avoid error log spam.
|
||||
ConsoleStdio_DoWriteLn,
|
||||
ConsoleStdio_DoSetColor,
|
||||
ConsoleStdout_DoWrite, // Writes without newlines go to buffer to avoid error log spam.
|
||||
ConsoleStdout_DoWriteLn,
|
||||
ConsoleStdout_DoSetColor,
|
||||
|
||||
ConsoleStdio_Newline,
|
||||
ConsoleStdio_SetTitle,
|
||||
ConsoleNull_DoWrite, // writes from stdout are ignored here, lest we create infinite loop hell >_<
|
||||
ConsoleStdout_Newline,
|
||||
ConsoleStdout_SetTitle,
|
||||
|
||||
0, // instance-level indentation (should always be 0)
|
||||
};
|
||||
|
@ -180,6 +189,7 @@ const IConsoleWriter ConsoleWriter_Assert =
|
|||
ConsoleAssert_DoWriteLn,
|
||||
ConsoleNull_DoSetColor,
|
||||
|
||||
ConsoleNull_DoWrite,
|
||||
ConsoleNull_Newline,
|
||||
ConsoleNull_SetTitle,
|
||||
|
||||
|
@ -190,8 +200,6 @@ const IConsoleWriter ConsoleWriter_Assert =
|
|||
// ConsoleBuffer
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
static wxString m_buffer;
|
||||
|
||||
const wxString& ConsoleBuffer_Get()
|
||||
{
|
||||
return m_buffer;
|
||||
|
@ -199,6 +207,7 @@ const wxString& ConsoleBuffer_Get()
|
|||
|
||||
void ConsoleBuffer_Clear()
|
||||
{
|
||||
ScopedLock lock( m_bufferlock );
|
||||
m_buffer.Clear();
|
||||
}
|
||||
|
||||
|
@ -206,6 +215,7 @@ void ConsoleBuffer_Clear()
|
|||
// clears the buffer contents to 0.
|
||||
void ConsoleBuffer_FlushToFile( FILE *fp )
|
||||
{
|
||||
ScopedLock lock( m_bufferlock );
|
||||
if( fp == NULL || m_buffer.IsEmpty() ) return;
|
||||
px_fputs( fp, m_buffer.ToUTF8() );
|
||||
m_buffer.Clear();
|
||||
|
@ -213,11 +223,13 @@ void ConsoleBuffer_FlushToFile( FILE *fp )
|
|||
|
||||
static void __concall ConsoleBuffer_DoWrite( const wxString& fmt )
|
||||
{
|
||||
ScopedLock lock( m_bufferlock );
|
||||
m_buffer += fmt;
|
||||
}
|
||||
|
||||
static void __concall ConsoleBuffer_DoWriteLn( const wxString& fmt )
|
||||
{
|
||||
ScopedLock lock( m_bufferlock );
|
||||
m_buffer += fmt + L"\n";
|
||||
}
|
||||
|
||||
|
@ -227,6 +239,7 @@ const IConsoleWriter ConsoleWriter_Buffered =
|
|||
ConsoleBuffer_DoWriteLn,
|
||||
ConsoleNull_DoSetColor,
|
||||
|
||||
ConsoleBuffer_DoWrite,
|
||||
ConsoleNull_Newline,
|
||||
ConsoleNull_SetTitle,
|
||||
|
||||
|
@ -253,6 +266,7 @@ const IConsoleWriter ConsoleWriter_wxError =
|
|||
Console_wxLogError_DoWriteLn,
|
||||
ConsoleNull_DoSetColor,
|
||||
|
||||
ConsoleBuffer_DoWrite,
|
||||
ConsoleNull_Newline,
|
||||
ConsoleNull_SetTitle,
|
||||
|
||||
|
@ -616,6 +630,36 @@ bool IConsoleWriter::Warning( const wxChar* fmt, ... ) const
|
|||
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:
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -627,7 +671,7 @@ bool IConsoleWriter::Warning( const wxChar* fmt, ... ) const
|
|||
#if wxUSE_GUI && defined(__WXMSW__)
|
||||
# define _DefaultWriter_ ConsoleWriter_Assert
|
||||
#else
|
||||
# define _DefaultWriter_ ConsoleWriter_Stdio
|
||||
# define _DefaultWriter_ ConsoleWriter_Stdout
|
||||
#endif
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
Threading::PersistentThread::PersistentThread() :
|
||||
m_name( L"PersistentThread" )
|
||||
, m_thread()
|
||||
, m_sem_event()
|
||||
, m_lock_InThread()
|
||||
, m_lock_start()
|
||||
Threading::PersistentThread::PersistentThread()
|
||||
: m_name( L"PersistentThread" )
|
||||
, m_thread()
|
||||
, m_sem_event()
|
||||
, m_lock_InThread()
|
||||
, m_lock_start()
|
||||
{
|
||||
m_detached = true; // start out with m_thread in detached/invalid state
|
||||
m_running = false;
|
||||
|
@ -116,6 +116,16 @@ Threading::PersistentThread::~PersistentThread() throw()
|
|||
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 )
|
||||
{
|
||||
if( mutex.RecreateIfLocked() )
|
||||
|
@ -155,7 +165,7 @@ void Threading::PersistentThread::Start()
|
|||
// This function should not be called from the owner thread.
|
||||
bool Threading::PersistentThread::Detach()
|
||||
{
|
||||
pxAssertMsg( !IsSelf(), "Thread affinity error." ); // not allowed from our own thread.
|
||||
AffinityAssert_DisallowFromSelf();
|
||||
|
||||
if( _InterlockedExchange( &m_detached, true ) ) return false;
|
||||
pthread_detach( m_thread );
|
||||
|
@ -175,7 +185,7 @@ bool Threading::PersistentThread::Detach()
|
|||
//
|
||||
void Threading::PersistentThread::Cancel( bool isBlocking )
|
||||
{
|
||||
pxAssertMsg( !IsSelf(), "Thread affinity error." );
|
||||
AffinityAssert_DisallowFromSelf();
|
||||
|
||||
{
|
||||
// Prevent simultaneous startup and cancel:
|
||||
|
@ -210,8 +220,7 @@ void Threading::PersistentThread::Cancel( bool isBlocking )
|
|||
//
|
||||
void Threading::PersistentThread::Block()
|
||||
{
|
||||
pxAssertDev( !IsSelf(), "Thread deadlock detected; Block() should never be called by the owner thread." );
|
||||
|
||||
AffinityAssert_DisallowFromSelf();
|
||||
m_lock_InThread.Wait();
|
||||
}
|
||||
|
||||
|
@ -268,7 +277,7 @@ void Threading::PersistentThread::_selfRunningTest( const wxChar* name ) 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 )
|
||||
{
|
||||
|
@ -292,7 +301,7 @@ void Threading::PersistentThread::WaitOnSelf( Semaphore& sem ) 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 )
|
||||
{
|
||||
|
@ -305,7 +314,7 @@ static const wxTimeSpan SelfWaitInterval( 0,0,0,333 );
|
|||
|
||||
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 );
|
||||
|
||||
|
@ -321,7 +330,7 @@ bool Threading::PersistentThread::WaitOnSelf( Semaphore& sem, const wxTimeSpan&
|
|||
|
||||
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 );
|
||||
|
||||
|
@ -341,7 +350,7 @@ bool Threading::PersistentThread::WaitOnSelf( Mutex& mutex, const wxTimeSpan& ti
|
|||
// and cleanup, or use the DoThreadCleanup() override to perform resource cleanup).
|
||||
void Threading::PersistentThread::TestCancel() const
|
||||
{
|
||||
pxAssert( IsSelf() );
|
||||
AffinityAssert_AllowFromSelf();
|
||||
pthread_testcancel();
|
||||
}
|
||||
|
||||
|
@ -422,10 +431,8 @@ void Threading::PersistentThread::_try_virtual_invoke( void (PersistentThread::*
|
|||
// OnCleanupInThread() to extend cleanup functionality.
|
||||
void Threading::PersistentThread::_ThreadCleanup()
|
||||
{
|
||||
pxAssertMsg( IsSelf(), "Thread affinity error." ); // only allowed from our own thread, thanks.
|
||||
|
||||
AffinityAssert_AllowFromSelf();
|
||||
_try_virtual_invoke( &PersistentThread::OnCleanupInThread );
|
||||
|
||||
m_lock_InThread.Release();
|
||||
}
|
||||
|
||||
|
@ -486,7 +493,7 @@ void Threading::PersistentThread::_DoSetThreadName( const wxString& 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:
|
||||
|
||||
|
|
|
@ -17,13 +17,9 @@
|
|||
#include "PrecompiledHeader.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 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Note: Apparently this solution is Linux/Solaris only.
|
||||
|
|
|
@ -17,12 +17,10 @@
|
|||
#include "PrecompiledHeader.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 xor ecx, ecx;
|
||||
__cpuid( (int*)regs, cmd );
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU )
|
||||
|
@ -54,7 +52,8 @@ void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhys
|
|||
bool _test_instruction( void* pfnCall )
|
||||
{
|
||||
__try {
|
||||
((void (*)())pfnCall)();
|
||||
u128 regsave;
|
||||
((void (__fastcall *)(void*))pfnCall)( ®save );
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
return false;
|
||||
|
|
|
@ -68,79 +68,72 @@ static s64 CPUSpeedHz( u64 time )
|
|||
////////////////////////////////////////////////////
|
||||
void cpudetectInit()
|
||||
{
|
||||
u32 regs[ 4 ];
|
||||
u32 cmds;
|
||||
//AMD 64 STUFF
|
||||
u32 x86_64_8BITBRANDID;
|
||||
u32 x86_64_12BITBRANDID;
|
||||
u32 regs[ 4 ];
|
||||
u32 cmds;
|
||||
//AMD 64 STUFF
|
||||
u32 x86_64_8BITBRANDID;
|
||||
u32 x86_64_12BITBRANDID;
|
||||
|
||||
memzero( x86caps.VendorName );
|
||||
x86caps.FamilyID = 0;
|
||||
x86caps.Model = 0;
|
||||
x86caps.TypeID = 0;
|
||||
x86caps.StepID = 0;
|
||||
x86caps.Flags = 0;
|
||||
x86caps.EFlags = 0;
|
||||
memzero( x86caps.VendorName );
|
||||
x86caps.FamilyID = 0;
|
||||
x86caps.Model = 0;
|
||||
x86caps.TypeID = 0;
|
||||
x86caps.StepID = 0;
|
||||
x86caps.Flags = 0;
|
||||
x86caps.EFlags = 0;
|
||||
|
||||
if ( iCpuId( 0, regs ) == -1 ) return;
|
||||
//memzero( regs );
|
||||
iCpuId( 0, regs );
|
||||
|
||||
cmds = regs[ 0 ];
|
||||
((u32*)x86caps.VendorName)[ 0 ] = regs[ 1 ];
|
||||
((u32*)x86caps.VendorName)[ 1 ] = regs[ 3 ];
|
||||
((u32*)x86caps.VendorName)[ 2 ] = regs[ 2 ];
|
||||
cmds = regs[ 0 ];
|
||||
((u32*)x86caps.VendorName)[ 0 ] = regs[ 1 ];
|
||||
((u32*)x86caps.VendorName)[ 1 ] = regs[ 3 ];
|
||||
((u32*)x86caps.VendorName)[ 2 ] = regs[ 2 ];
|
||||
|
||||
u32 LogicalCoresPerPhysicalCPU = 0;
|
||||
u32 PhysicalCoresPerPhysicalCPU = 1;
|
||||
u32 LogicalCoresPerPhysicalCPU = 0;
|
||||
u32 PhysicalCoresPerPhysicalCPU = 1;
|
||||
|
||||
if ( cmds >= 0x00000001 )
|
||||
{
|
||||
if ( iCpuId( 0x00000001, regs ) != -1 )
|
||||
{
|
||||
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 ];
|
||||
}
|
||||
}
|
||||
if ( cmds >= 0x00000001 )
|
||||
{
|
||||
iCpuId( 0x00000001, regs );
|
||||
|
||||
// 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))
|
||||
{
|
||||
if ( iCpuId( 0x00000004, regs ) != -1 )
|
||||
{
|
||||
PhysicalCoresPerPhysicalCPU += ( regs[0] >> 26) & 0x3f;
|
||||
}
|
||||
}
|
||||
LogicalCoresPerPhysicalCPU = ( regs[1] >> 16 ) & 0xff;
|
||||
}
|
||||
|
||||
if ( iCpuId( 0x80000000, regs ) != -1 )
|
||||
{
|
||||
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 ];
|
||||
// detect multicore for Intel cpu
|
||||
|
||||
}
|
||||
}
|
||||
if ((cmds >= 0x00000004) && !strcmp("GenuineIntel",x86caps.VendorName))
|
||||
{
|
||||
iCpuId( 0x00000004, regs );
|
||||
PhysicalCoresPerPhysicalCPU += ( regs[0] >> 26) & 0x3f;
|
||||
}
|
||||
|
||||
// detect multicore for AMD cpu
|
||||
iCpuId( 0x80000000, regs );
|
||||
cmds = regs[ 0 ];
|
||||
if ( cmds >= 0x80000001 )
|
||||
{
|
||||
iCpuId( 0x80000001, regs );
|
||||
|
||||
if ((cmds >= 0x80000008) && !strcmp("AuthenticAMD",x86caps.VendorName))
|
||||
{
|
||||
if ( iCpuId( 0x80000008, regs ) != -1 )
|
||||
{
|
||||
PhysicalCoresPerPhysicalCPU += ( regs[2] ) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
|
@ -245,15 +238,21 @@ void cpudetectInit()
|
|||
if( CanTestInstructionSets() )
|
||||
{
|
||||
xSetPtr( recSSE );
|
||||
xMOVDQU( ptr[ecx], xmm1 );
|
||||
xMOVSLDUP( xmm1, xmm0 );
|
||||
xMOVDQU( xmm1, ptr[ecx] );
|
||||
xRET();
|
||||
|
||||
u8* funcSSSE3 = xGetPtr();
|
||||
xPABS.W( xmm0, xmm1 );
|
||||
xMOVDQU( ptr[ecx], xmm1 );
|
||||
xPABS.W( xmm1, xmm0 );
|
||||
xMOVDQU( xmm1, ptr[ecx] );
|
||||
xRET();
|
||||
|
||||
u8* funcSSE41 = xGetPtr();
|
||||
xMOVDQU( ptr[ecx], xmm1 );
|
||||
xBLEND.VPD( xmm1, xmm0 );
|
||||
xMOVDQU( xmm1, ptr[ecx] );
|
||||
xRET();
|
||||
|
||||
bool sse3_result = _test_instruction( recSSE ); // sse3
|
||||
|
|
|
@ -53,4 +53,4 @@ public:
|
|||
|
||||
extern bool CanTestInstructionSets();
|
||||
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()
|
||||
{
|
||||
//DbgCon.WriteLn( "Direct modification of EmuConfig.GS detected" );
|
||||
AllowFromMainThreadOnly();
|
||||
AffinityAssert_AllowFromMain();
|
||||
return const_cast<Pcsx2Config::GSOptions&>(EmuConfig.GS);
|
||||
}
|
||||
|
||||
ConsoleLogFilters& SetConsoleConfig()
|
||||
{
|
||||
//DbgCon.WriteLn( "Direct modification of EmuConfig.Log detected" );
|
||||
AllowFromMainThreadOnly();
|
||||
AffinityAssert_AllowFromMain();
|
||||
return const_cast<ConsoleLogFilters&>(EmuConfig.Log);
|
||||
}
|
||||
|
||||
TraceLogFilters& SetTraceConfig()
|
||||
{
|
||||
//DbgCon.WriteLn( "Direct modification of EmuConfig.TraceLog detected" );
|
||||
AllowFromMainThreadOnly();
|
||||
AffinityAssert_AllowFromMain();
|
||||
return const_cast<TraceLogFilters&>(EmuConfig.Trace);
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ static int resume_tries = 0;
|
|||
void AppCoreThread::Resume()
|
||||
{
|
||||
// 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_ResumeProtection.IsLocked() ) return;
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ void Pcsx2App::PostPadKey( wxKeyEvent& evt )
|
|||
|
||||
int Pcsx2App::ThreadedModalDialog( DialogIdentifiers dialogId )
|
||||
{
|
||||
AllowFromMainThreadOnly();
|
||||
AffinityAssert_AllowFromMain();
|
||||
|
||||
MsgboxEventResult result;
|
||||
wxCommandEvent joe( pxEVT_OpenModalDialog, dialogId );
|
||||
|
@ -399,7 +399,7 @@ GSFrame& Pcsx2App::GetGSFrame() const
|
|||
|
||||
void AppApplySettings( const AppConfig* oldconf )
|
||||
{
|
||||
AllowFromMainThreadOnly();
|
||||
AffinityAssert_AllowFromMain();
|
||||
|
||||
g_Conf->Folders.ApplyDefaults();
|
||||
|
||||
|
@ -452,7 +452,7 @@ AppIniLoader::AppIniLoader()
|
|||
|
||||
void AppLoadSettings()
|
||||
{
|
||||
if( !AllowFromMainThreadOnly() ) return;
|
||||
if( !AffinityAssert_AllowFromMain() ) return;
|
||||
|
||||
AppIniLoader loader;
|
||||
g_Conf->LoadSave( loader );
|
||||
|
@ -461,7 +461,7 @@ void AppLoadSettings()
|
|||
|
||||
void AppSaveSettings()
|
||||
{
|
||||
if( !AllowFromMainThreadOnly() ) return;
|
||||
if( !AffinityAssert_AllowFromMain() ) return;
|
||||
|
||||
AppIniSaver saver;
|
||||
g_Conf->LoadSave( saver );
|
||||
|
|
|
@ -589,9 +589,12 @@ void ConsoleLogFrame::OnIdleEvent( wxIdleEvent& evt )
|
|||
void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& evt )
|
||||
{
|
||||
ScopedLock locker( m_QueueLock );
|
||||
|
||||
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 )
|
||||
{
|
||||
|
@ -609,7 +612,9 @@ void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& evt )
|
|||
locker.Acquire();
|
||||
}
|
||||
|
||||
DoFlushQueue();
|
||||
if( m_CurQueuePos != 0 )
|
||||
DoFlushQueue();
|
||||
|
||||
//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,
|
||||
// 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 )
|
||||
{
|
||||
do {
|
||||
|
@ -702,7 +704,7 @@ void Pcsx2App::ProgramLog_PostEvent( wxEvent& evt )
|
|||
static void __concall ConsoleToFile_Newline()
|
||||
{
|
||||
#ifdef __LINUX__
|
||||
if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdio.Newline();
|
||||
if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdout.Newline();
|
||||
#endif
|
||||
|
||||
#ifdef __LINUX__
|
||||
|
@ -715,7 +717,7 @@ static void __concall ConsoleToFile_Newline()
|
|||
static void __concall ConsoleToFile_DoWrite( const wxString& fmt )
|
||||
{
|
||||
#ifdef __LINUX__
|
||||
if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdio.DoWrite(fmt);
|
||||
if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdout.DoWrite(fmt);
|
||||
#endif
|
||||
|
||||
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 )
|
||||
{
|
||||
ConsoleWriter_Stdio.SetTitle(title);
|
||||
ConsoleWriter_Stdout.SetTitle(title);
|
||||
}
|
||||
|
||||
static void __concall ConsoleToFile_DoSetColor( ConsoleColors color )
|
||||
{
|
||||
ConsoleWriter_Stdio.DoSetColor(color);
|
||||
ConsoleWriter_Stdout.DoSetColor(color);
|
||||
}
|
||||
|
||||
extern const IConsoleWriter ConsoleWriter_File;
|
||||
|
@ -746,6 +748,7 @@ const IConsoleWriter ConsoleWriter_File =
|
|||
ConsoleToFile_DoWriteLn,
|
||||
ConsoleToFile_DoSetColor,
|
||||
|
||||
ConsoleToFile_DoWrite,
|
||||
ConsoleToFile_Newline,
|
||||
ConsoleToFile_SetTitle,
|
||||
};
|
||||
|
@ -799,6 +802,7 @@ static const IConsoleWriter ConsoleWriter_Window =
|
|||
ConsoleToWindow_DoWriteLn<ConsoleWriter_Null>,
|
||||
ConsoleToWindow_DoSetColor<ConsoleWriter_Null>,
|
||||
|
||||
ConsoleToWindow_DoWrite<ConsoleWriter_Null>,
|
||||
ConsoleToWindow_Newline<ConsoleWriter_Null>,
|
||||
ConsoleToWindow_SetTitle<ConsoleWriter_Null>,
|
||||
};
|
||||
|
@ -809,6 +813,7 @@ static const IConsoleWriter ConsoleWriter_WindowAndFile =
|
|||
ConsoleToWindow_DoWriteLn<ConsoleWriter_File>,
|
||||
ConsoleToWindow_DoSetColor<ConsoleWriter_File>,
|
||||
|
||||
ConsoleToWindow_DoWrite<ConsoleWriter_File>,
|
||||
ConsoleToWindow_Newline<ConsoleWriter_File>,
|
||||
ConsoleToWindow_SetTitle<ConsoleWriter_File>,
|
||||
};
|
||||
|
@ -818,14 +823,14 @@ void Pcsx2App::EnableAllLogging() const
|
|||
if( emuLog )
|
||||
Console_SetActiveHandler( (m_ProgramLogBox!=NULL) ? (IConsoleWriter&)ConsoleWriter_WindowAndFile : (IConsoleWriter&)ConsoleWriter_File );
|
||||
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
|
||||
// emuLog file handle. Call SetConsoleLogging to re-enable the disk logger when finished.
|
||||
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
|
||||
// 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
|
||||
// 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).
|
||||
|
||||
Threading::Sleep( 5 );
|
||||
|
@ -842,6 +847,6 @@ void Pcsx2App::DisableDiskLogging() 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 );
|
||||
}
|
||||
|
|
|
@ -84,9 +84,9 @@ protected:
|
|||
const ConsoleColors m_color;
|
||||
|
||||
public:
|
||||
WinPipeThread( const HANDLE& outpipe, ConsoleColors color ) :
|
||||
m_outpipe( outpipe )
|
||||
, m_color( color )
|
||||
WinPipeThread( const HANDLE& outpipe, ConsoleColors color )
|
||||
: m_outpipe( outpipe )
|
||||
, m_color( color )
|
||||
{
|
||||
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!
|
||||
s8_Buf[u32_Read] = 0;
|
||||
OemToCharA(s8_Buf, s8_Buf); // convert DOS codepage -> ANSI
|
||||
Console.Write( m_color, s8_Buf );
|
||||
Console.WriteFromStdout( m_color, s8_Buf );
|
||||
|
||||
TestCancel();
|
||||
}
|
||||
|
@ -187,12 +186,12 @@ public:
|
|||
void Cleanup() throw();
|
||||
};
|
||||
|
||||
WinPipeRedirection::WinPipeRedirection( FILE* stdstream ) :
|
||||
m_readpipe(INVALID_HANDLE_VALUE)
|
||||
, m_writepipe(INVALID_HANDLE_VALUE)
|
||||
, m_crtFile(-1)
|
||||
, m_fp(NULL)
|
||||
, m_Thread( m_readpipe, (stdstream == stderr) ? Color_Red : Color_Black )
|
||||
WinPipeRedirection::WinPipeRedirection( FILE* stdstream )
|
||||
: m_readpipe(INVALID_HANDLE_VALUE)
|
||||
, m_writepipe(INVALID_HANDLE_VALUE)
|
||||
, m_crtFile(-1)
|
||||
, m_fp(NULL)
|
||||
, m_Thread( m_readpipe, (stdstream == stderr) ? Color_Red : Color_Black )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -236,6 +235,7 @@ WinPipeRedirection::WinPipeRedirection( FILE* stdstream ) :
|
|||
}
|
||||
catch( ... )
|
||||
{
|
||||
Cleanup();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue