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:
Jake.Stine 2009-09-22 17:28:48 +00:00
parent 0fe6bd16f3
commit 39bd850f72
7 changed files with 56 additions and 7 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -166,6 +166,8 @@ protected:
try
{
SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL );
SetName( (m_color == Color_Red) ? "Redirect_Stderr" :" Redirect_Stdout" );
while( true )
{
Sleep( 100 );
@ -173,7 +175,7 @@ protected:
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 );