mirror of https://github.com/PCSX2/pcsx2.git
win32pthreads: Changed from _beginthreadex to CreateThread, which is the preferred method of creating threads when using dynamic CRT linking.
PCSX2/Win32: * Assigned names to the threads so that they show up nicely in the debugger. * Added more error checking in the new stdout/stderr PipeRedirection code, hopefully fixing Issue 422 (but can't reproduce the error here to be sure). git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1904 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
0fe6bd16f3
commit
39bd850f72
|
@ -23,7 +23,8 @@
|
|||
#undef NEED_DUPLICATEHANDLE
|
||||
|
||||
/* Define if you don't have Win32 _beginthreadex. (eg. WinCE) */
|
||||
#undef NEED_CREATETHREAD
|
||||
// PCSX2 : This is preferred when using the shared CRT, which we do! -- air
|
||||
#define NEED_CREATETHREAD
|
||||
|
||||
/* Define if you don't have Win32 errno. (eg. WinCE) */
|
||||
#undef NEED_ERRNO
|
||||
|
|
|
@ -227,14 +227,17 @@ This theoretically unoptimizes. Not having much luck so far.
|
|||
# define __naked // GCC lacks the naked specifier
|
||||
# define CALLBACK // CALLBACK is a win32-specific mess
|
||||
|
||||
// GCC uses attributes for a lot of things that Visual C+ doesn't.
|
||||
// Inlining note: GCC needs ((unused)) attributes defined on inlined functions to suppress
|
||||
// warnings when a static inlined function isn't used in the scope of a single file (which
|
||||
// happens *by design* like all the friggen time >_<)
|
||||
|
||||
# define __fastcall __attribute__((fastcall))
|
||||
# define __unused __attribute__((unused))
|
||||
# define _inline __inline__ __attribute__((unused))
|
||||
# ifdef NDEBUG
|
||||
# define __forceinline __attribute__((always_inline,unused))
|
||||
# else
|
||||
# define __forceinline // no forceinlines in debug builds
|
||||
# define __forceinline __attribute__((unused))
|
||||
# endif
|
||||
# define __noinline __attribute__((noinline))
|
||||
# define __hot __attribute__((hot))
|
||||
|
|
|
@ -149,6 +149,8 @@ namespace Threading
|
|||
virtual void DoThreadCleanup();
|
||||
|
||||
protected:
|
||||
void SetName( __unused const char* name );
|
||||
|
||||
// Used to dispatch the thread callback function.
|
||||
// (handles some thread cleanup on Win32, and is basically a typecast
|
||||
// on linux).
|
||||
|
|
|
@ -204,6 +204,39 @@ namespace Threading
|
|||
return (void*)owner.m_returncode;
|
||||
}
|
||||
|
||||
void PersistentThread::SetName( __unused const char* name )
|
||||
{
|
||||
wxASSERT( IsSelf() ); // only allowed from our own thread, thanks.
|
||||
|
||||
#ifdef _WINDOWS_
|
||||
static const int MS_VC_EXCEPTION = 0x406D1388;
|
||||
|
||||
#pragma pack(push,8)
|
||||
struct THREADNAME_INFO
|
||||
{
|
||||
DWORD dwType; // Must be 0x1000.
|
||||
LPCSTR szName; // Pointer to name (in user addr space).
|
||||
DWORD dwThreadID; // Thread ID (-1=caller thread).
|
||||
DWORD dwFlags; // Reserved for future use, must be zero.
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
THREADNAME_INFO info;
|
||||
info.dwType = 0x1000;
|
||||
info.szName = name;
|
||||
info.dwThreadID = GetCurrentThreadId();
|
||||
info.dwFlags = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseTaskThread Implementations
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
|
|
@ -602,6 +602,8 @@ static void dummyIrqCallback()
|
|||
|
||||
sptr mtgsThreadObject::ExecuteTask()
|
||||
{
|
||||
SetName( "MTGS" );
|
||||
|
||||
memcpy_aligned( m_gsMem, PS2MEM_GS, sizeof(PS2MEM_GS) );
|
||||
GSsetBaseMem( m_gsMem );
|
||||
GSirqCallback( dummyIrqCallback );
|
||||
|
|
|
@ -116,6 +116,7 @@ static void _cet_callback_cleanup( void* handle )
|
|||
|
||||
sptr SysCoreThread::ExecuteTask()
|
||||
{
|
||||
SetName( "EE Core" );
|
||||
tls_coreThread = this;
|
||||
|
||||
while( m_ExecMode != ExecMode_Running )
|
||||
|
|
|
@ -166,14 +166,16 @@ protected:
|
|||
try
|
||||
{
|
||||
SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL );
|
||||
SetName( (m_color == Color_Red) ? "Redirect_Stderr" :" Redirect_Stdout" );
|
||||
|
||||
while( true )
|
||||
{
|
||||
Sleep( 100 );
|
||||
pthread_testcancel();
|
||||
ReadPipe(m_outpipe, m_color );
|
||||
ReadPipe( m_outpipe, m_color );
|
||||
}
|
||||
}
|
||||
catch( Exception::Win32Error& ex )
|
||||
catch( Exception::RuntimeError& ex )
|
||||
{
|
||||
// Log error, and fail silently. It's not really important if the
|
||||
// pipe fails. PCSX2 will run fine without it in any case.
|
||||
|
@ -220,13 +222,18 @@ WinPipeRedirection::WinPipeRedirection( FILE* stdstream ) :
|
|||
// In some cases GetStdHandle can fail, even when the one we just assigned above is valid.
|
||||
HANDLE newhandle = GetStdHandle(stdhandle);
|
||||
if( newhandle == INVALID_HANDLE_VALUE )
|
||||
throw Exception::Win32Error( "GetStdHandle failed." );
|
||||
throw Exception::Win32Error( "PipeRedirection: GetStdHandle failed." );
|
||||
|
||||
if( newhandle == NULL )
|
||||
throw Exception::RuntimeError( "GetStdHandle returned NULL." ); // not a Win32error (no error code)
|
||||
throw Exception::RuntimeError( "PipeRedirection: GetStdHandle returned NULL." ); // not a Win32error (no error code)
|
||||
|
||||
m_crtFile = _open_osfhandle( (intptr_t)newhandle, _O_TEXT );
|
||||
if( m_crtFile == -1 )
|
||||
throw Exception::RuntimeError( "PipeRedirection: _open_osfhandle returned -1." );
|
||||
|
||||
m_fp = _fdopen( m_crtFile, "w" );
|
||||
if( m_fp == NULL )
|
||||
throw Exception::RuntimeError( "PipeRedirection: _fdopen returned NULL." );
|
||||
|
||||
*stdstream = *m_fp;
|
||||
setvbuf( stdstream, NULL, _IONBF, 0 );
|
||||
|
|
Loading…
Reference in New Issue