* 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:
Jake.Stine 2009-12-07 22:43:16 +00:00
parent 94cdfb6a8b
commit ba473e0a7f
13 changed files with 206 additions and 146 deletions

View File

@ -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;

View File

@ -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.

View File

@ -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.

View File

@ -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:

View File

@ -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.

View File

@ -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)( &regsave );
} }
__except(EXCEPTION_EXECUTE_HANDLER) { __except(EXCEPTION_EXECUTE_HANDLER) {
return false; return false;

View File

@ -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

View File

@ -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 );

View File

@ -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);
} }

View File

@ -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;

View File

@ -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 );

View File

@ -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 );
} }

View File

@ -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;
} }
} }