mirror of https://github.com/PCSX2/pcsx2.git
aligned_stack:
* Added -fno-strict-aliasing to the ever growing list of gcc optimizations that can potentially cause perfectly good C code to generate entirely broken results. * Removed the preferred-stack=2, since this branch *should* run fine without it now. * Have Release builds in Linux SIGKILL when encountering an unexpected SIGSEGV. * Fixed some deadlock issues with the new console logger (it introduced cancel points, which is a good thing! unless you're the EE recompiler and you swallow up any attempt by GCC to cancel a thread) * Compilation error fixes. git-svn-id: http://pcsx2.googlecode.com/svn/branches/aligned_stack@2049 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
51999656ab
commit
f172829737
|
@ -66,8 +66,8 @@
|
||||||
<Add option="-fno-guess-branch-probability" />
|
<Add option="-fno-guess-branch-probability" />
|
||||||
<Add option="-fno-dse" />
|
<Add option="-fno-dse" />
|
||||||
<Add option="-fno-tree-dse" />
|
<Add option="-fno-tree-dse" />
|
||||||
|
<Add option="-fno-strict-aliasing" />
|
||||||
<Add option="-pipe -msse -msse2" />
|
<Add option="-pipe -msse -msse2" />
|
||||||
<Add option="-mpreferred-stack-boundary=2" />
|
|
||||||
<Add option="-m32" />
|
<Add option="-m32" />
|
||||||
<Add directory="../../include/Utilities" />
|
<Add directory="../../include/Utilities" />
|
||||||
<Add directory="../../include" />
|
<Add directory="../../include" />
|
||||||
|
|
|
@ -67,8 +67,8 @@
|
||||||
<Add option="-fno-guess-branch-probability" />
|
<Add option="-fno-guess-branch-probability" />
|
||||||
<Add option="-fno-dse" />
|
<Add option="-fno-dse" />
|
||||||
<Add option="-fno-tree-dse" />
|
<Add option="-fno-tree-dse" />
|
||||||
|
<Add option="-fno-strict-aliasing" />
|
||||||
<Add option="-pipe -msse -msse2" />
|
<Add option="-pipe -msse -msse2" />
|
||||||
<Add option="-mpreferred-stack-boundary=2" />
|
|
||||||
<Add option="-m32" />
|
<Add option="-m32" />
|
||||||
<Add directory="../../include/x86emitter" />
|
<Add directory="../../include/x86emitter" />
|
||||||
<Add directory="../../include" />
|
<Add directory="../../include" />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
/* PCSX2 - PS2 Emulator for PCs
|
||||||
* Copyright (C) 2002-2009 PCSX2 Dev Team
|
* Copyright (C) 2002-2009 PCSX2 Dev Team
|
||||||
*
|
*
|
||||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||||
* ation, either version 3 of the License, or (at your option) any later version.
|
* ation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
|
@ -62,7 +62,7 @@ namespace Threading
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// The following set of documented functions have Linux/Win32 specific implementations,
|
// The following set of documented functions have Linux/Win32 specific implementations,
|
||||||
// which are found in WinThreads.cpp and LnxThreads.cpp
|
// which are found in WinThreads.cpp and LnxThreads.cpp
|
||||||
|
|
||||||
|
|
||||||
// Returns the number of available logical CPUs (cores plus hyperthreaded cpus)
|
// Returns the number of available logical CPUs (cores plus hyperthreaded cpus)
|
||||||
extern void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU );
|
extern void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU );
|
||||||
|
@ -146,6 +146,7 @@ namespace Threading
|
||||||
void WaitRaw();
|
void WaitRaw();
|
||||||
bool WaitRaw( const wxTimeSpan& timeout );
|
bool WaitRaw( const wxTimeSpan& timeout );
|
||||||
void WaitNoCancel();
|
void WaitNoCancel();
|
||||||
|
void WaitNoCancel( const wxTimeSpan& timeout );
|
||||||
int Count();
|
int Count();
|
||||||
|
|
||||||
void Wait();
|
void Wait();
|
||||||
|
@ -161,7 +162,7 @@ namespace Threading
|
||||||
MutexLock();
|
MutexLock();
|
||||||
virtual ~MutexLock() throw();
|
virtual ~MutexLock() throw();
|
||||||
virtual bool IsRecursive() const { return false; }
|
virtual bool IsRecursive() const { return false; }
|
||||||
|
|
||||||
void Recreate();
|
void Recreate();
|
||||||
bool RecreateIfLocked();
|
bool RecreateIfLocked();
|
||||||
void Detach();
|
void Detach();
|
||||||
|
@ -173,10 +174,10 @@ namespace Threading
|
||||||
|
|
||||||
void LockRaw();
|
void LockRaw();
|
||||||
bool LockRaw( const wxTimeSpan& timeout );
|
bool LockRaw( const wxTimeSpan& timeout );
|
||||||
|
|
||||||
void Wait();
|
void Wait();
|
||||||
bool Wait( const wxTimeSpan& timeout );
|
bool Wait( const wxTimeSpan& timeout );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// empty constructor used by MutexLockRecursive
|
// empty constructor used by MutexLockRecursive
|
||||||
MutexLock( bool ) {}
|
MutexLock( bool ) {}
|
||||||
|
@ -217,7 +218,7 @@ namespace Threading
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// PersistentThread - Helper class for the basics of starting/managing persistent threads.
|
// PersistentThread - Helper class for the basics of starting/managing persistent threads.
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// This class is meant to be a helper for the typical threading model of "start once and
|
// This class is meant to be a helper for the typical threading model of "start once and
|
||||||
// reuse many times." This class incorporates a lot of extra overhead in stopping and
|
// reuse many times." This class incorporates a lot of extra overhead in stopping and
|
||||||
// starting threads, but in turn provides most of the basic thread-safety and event-handling
|
// starting threads, but in turn provides most of the basic thread-safety and event-handling
|
||||||
// functionality needed for a threaded operation. In practice this model is usually an
|
// functionality needed for a threaded operation. In practice this model is usually an
|
||||||
|
@ -230,7 +231,7 @@ namespace Threading
|
||||||
// void OnStart();
|
// void OnStart();
|
||||||
// void ExecuteTaskInThread();
|
// void ExecuteTaskInThread();
|
||||||
// void OnCleanupInThread();
|
// void OnCleanupInThread();
|
||||||
//
|
//
|
||||||
// Use the public methods Start() and Cancel() to start and shutdown the thread, and use
|
// Use the public methods Start() and Cancel() to start and shutdown the thread, and use
|
||||||
// m_sem_event internally to post/receive events for the thread (make a public accessor for
|
// m_sem_event internally to post/receive events for the thread (make a public accessor for
|
||||||
// it in your derived class if your thread utilizes the post).
|
// it in your derived class if your thread utilizes the post).
|
||||||
|
@ -247,14 +248,14 @@ namespace Threading
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef int (*PlainJoeFP)();
|
typedef int (*PlainJoeFP)();
|
||||||
|
|
||||||
wxString m_name; // diagnostic name for our thread.
|
wxString m_name; // diagnostic name for our thread.
|
||||||
|
|
||||||
pthread_t m_thread;
|
pthread_t m_thread;
|
||||||
Semaphore m_sem_event; // general wait event that's needed by most threads.
|
Semaphore m_sem_event; // general wait event that's needed by most threads.
|
||||||
MutexLock m_lock_InThread; // used for canceling and closing threads in a deadlock-safe manner
|
MutexLock m_lock_InThread; // used for canceling and closing threads in a deadlock-safe manner
|
||||||
MutexLockRecursive m_lock_start; // used to lock the Start() code from starting simultaneous threads accidentally.
|
MutexLockRecursive m_lock_start; // used to lock the Start() code from starting simultaneous threads accidentally.
|
||||||
|
|
||||||
volatile long m_detached; // a boolean value which indicates if the m_thread handle is valid
|
volatile long m_detached; // a boolean value which indicates if the m_thread handle is valid
|
||||||
volatile long m_running; // set true by Start(), and set false by Cancel(), Block(), etc.
|
volatile long m_running; // set true by Start(), and set false by Cancel(), Block(), etc.
|
||||||
|
|
||||||
|
@ -285,7 +286,7 @@ namespace Threading
|
||||||
// Start() once necessary locks have been obtained. Do not override Start() directly
|
// Start() once necessary locks have been obtained. Do not override Start() directly
|
||||||
// unless you're really sure that's what you need to do. ;)
|
// unless you're really sure that's what you need to do. ;)
|
||||||
virtual void OnStart();
|
virtual void OnStart();
|
||||||
|
|
||||||
virtual void OnStartInThread();
|
virtual void OnStartInThread();
|
||||||
|
|
||||||
// This is called when the thread has been canceled or exits normally. The PersistentThread
|
// This is called when the thread has been canceled or exits normally. The PersistentThread
|
||||||
|
@ -327,7 +328,7 @@ namespace Threading
|
||||||
static void* _internal_callback( void* func );
|
static void* _internal_callback( void* func );
|
||||||
static void _pt_callback_cleanup( void* handle );
|
static void _pt_callback_cleanup( void* handle );
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// ScopedLock: Helper class for using Mutexes.
|
// ScopedLock: Helper class for using Mutexes.
|
||||||
// Using this class provides an exception-safe (and generally clean) method of locking
|
// Using this class provides an exception-safe (and generally clean) method of locking
|
||||||
|
@ -370,7 +371,7 @@ namespace Threading
|
||||||
m_lock.Lock();
|
m_lock.Lock();
|
||||||
m_IsLocked = true;
|
m_IsLocked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsLocked() const { return m_IsLocked; }
|
bool IsLocked() const { return m_IsLocked; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -380,9 +381,9 @@ namespace Threading
|
||||||
, m_IsLocked( isTryLock ? m_lock.TryLock() : false )
|
, m_IsLocked( isTryLock ? m_lock.TryLock() : false )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScopedTryLock : public ScopedLock
|
class ScopedTryLock : public ScopedLock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -163,6 +163,14 @@ void Threading::Semaphore::WaitNoCancel()
|
||||||
pthread_setcancelstate( oldstate, NULL );
|
pthread_setcancelstate( oldstate, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Threading::Semaphore::WaitNoCancel( const wxTimeSpan& timeout )
|
||||||
|
{
|
||||||
|
int oldstate;
|
||||||
|
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldstate );
|
||||||
|
WaitRaw( timeout );
|
||||||
|
pthread_setcancelstate( oldstate, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
int Threading::Semaphore::Count()
|
int Threading::Semaphore::Count()
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
|
@ -42,25 +42,3 @@
|
||||||
|
|
||||||
extern void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR);
|
extern void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR);
|
||||||
extern u32 g_sseVUMXCSR, g_sseMXCSR;
|
extern u32 g_sseVUMXCSR, g_sseMXCSR;
|
||||||
|
|
||||||
// SEH - "Built in" Structed Exception Handling support.
|
|
||||||
// This should be available on Windows, via Microsoft or Intel compilers (I'm pretty sure Intel
|
|
||||||
// supports native SEH model). GUNC in Windows, or any compiler in a non-windows platform, will
|
|
||||||
// ned to use setjmp/longjmp instead to exit recompiled code.
|
|
||||||
//
|
|
||||||
#if defined(_WIN32) && !defined(__GNUG__)
|
|
||||||
# define PCSX2_SEH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PCSX2_SEH
|
|
||||||
# include <setjmp.h>
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
SetJmp_Dispatcher = 1,
|
|
||||||
SetJmp_Exit,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern __threadlocal jmp_buf SetJmp_RecExecute;
|
|
||||||
extern __threadlocal jmp_buf SetJmp_StateCheck;
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -44,15 +44,15 @@ void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * )
|
||||||
// get bad virtual address
|
// get bad virtual address
|
||||||
uptr offset = (u8*)info->si_addr - psM;
|
uptr offset = (u8*)info->si_addr - psM;
|
||||||
|
|
||||||
DevCon.Status( "Protected memory cleanup. Offset 0x%x", offset );
|
|
||||||
|
|
||||||
if (offset>=Ps2MemSize::Base)
|
if (offset>=Ps2MemSize::Base)
|
||||||
{
|
{
|
||||||
// Bad mojo! Completely invalid address.
|
// Bad mojo! Completely invalid address.
|
||||||
// Instigate a crash or abort emulation or something.
|
// Instigate a crash or abort emulation or something.
|
||||||
wxTrap();
|
wxTrap();
|
||||||
return;
|
if( !IsDebugBuild )
|
||||||
|
raise( SIGKILL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DevCon.Status( "Protected memory cleanup. Offset 0x%x", offset );
|
||||||
mmap_ClearCpuBlock( offset & ~m_pagemask );
|
mmap_ClearCpuBlock( offset & ~m_pagemask );
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,8 +96,8 @@
|
||||||
<Add option="-fno-guess-branch-probability" />
|
<Add option="-fno-guess-branch-probability" />
|
||||||
<Add option="-fno-dse" />
|
<Add option="-fno-dse" />
|
||||||
<Add option="-fno-tree-dse" />
|
<Add option="-fno-tree-dse" />
|
||||||
|
<Add option="-fno-strict-aliasing" />
|
||||||
<Add option="-pipe -msse -msse2" />
|
<Add option="-pipe -msse -msse2" />
|
||||||
<Add option="-mpreferred-stack-boundary=2" />
|
|
||||||
<Add option="-m32" />
|
<Add option="-m32" />
|
||||||
<Add option="-DWX_PRECOMP" />
|
<Add option="-DWX_PRECOMP" />
|
||||||
<Add directory="$(SvnRootDir)/common/include/" />
|
<Add directory="$(SvnRootDir)/common/include/" />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
/* PCSX2 - PS2 Emulator for PCs
|
||||||
* Copyright (C) 2002-2009 PCSX2 Dev Team
|
* Copyright (C) 2002-2009 PCSX2 Dev Team
|
||||||
*
|
*
|
||||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||||
* ation, either version 3 of the License, or (at your option) any later version.
|
* ation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
@ -61,8 +61,9 @@ extern void SysClearExecutionCache(); // clears recompiled execution caches!
|
||||||
extern u8 *SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller="Unnamed");
|
extern u8 *SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller="Unnamed");
|
||||||
extern void vSyncDebugStuff( uint frame );
|
extern void vSyncDebugStuff( uint frame );
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
// --------------------------------------------------------------------------------------
|
||||||
//
|
// Memory Protection (Used by VTLB, Recompilers, and Texture caches)
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
#ifdef __LINUX__
|
#ifdef __LINUX__
|
||||||
|
|
||||||
# include <signal.h>
|
# include <signal.h>
|
||||||
|
@ -87,6 +88,33 @@ extern void vSyncDebugStuff( uint frame );
|
||||||
# error PCSX2 - Unsupported operating system platform.
|
# error PCSX2 - Unsupported operating system platform.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// PCSX2_SEH - Defines existence of "built in" Structed Exception Handling support.
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// This should be available on Windows, via Microsoft or Intel compilers (I'm pretty sure Intel
|
||||||
|
// supports native SEH model). GNUC in Windows, or any compiler in a non-windows platform, will
|
||||||
|
// need to use setjmp/longjmp instead to exit recompiled code.
|
||||||
|
//
|
||||||
|
#if defined(_WIN32) && !defined(__GNUC__)
|
||||||
|
# define PCSX2_SEH
|
||||||
|
#else
|
||||||
|
|
||||||
|
# include <setjmp.h>
|
||||||
|
|
||||||
|
// Platforms without SEH need to use SetJmp / LongJmp to deal with exiting the recompiled
|
||||||
|
// code execution pipelines in an efficient manner, since standard C++ exceptions cannot
|
||||||
|
// unwind across dynamically recompiled code.
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SetJmp_Dispatcher = 1,
|
||||||
|
SetJmp_Exit,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern jmp_buf SetJmp_RecExecute;
|
||||||
|
extern jmp_buf SetJmp_StateCheck;
|
||||||
|
#endif
|
||||||
|
|
||||||
class pxMessageBoxEvent;
|
class pxMessageBoxEvent;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -242,7 +242,7 @@ ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, A
|
||||||
{
|
{
|
||||||
m_TextCtrl.SetBackgroundColour( wxColor( 230, 235, 242 ) );
|
m_TextCtrl.SetBackgroundColour( wxColor( 230, 235, 242 ) );
|
||||||
m_TextCtrl.SetDefaultStyle( m_ColorTable[DefaultConsoleColor] );
|
m_TextCtrl.SetDefaultStyle( m_ColorTable[DefaultConsoleColor] );
|
||||||
|
|
||||||
// create Log menu (contains most options)
|
// create Log menu (contains most options)
|
||||||
wxMenuBar *pMenuBar = new wxMenuBar();
|
wxMenuBar *pMenuBar = new wxMenuBar();
|
||||||
wxMenu& menuLog = *new wxMenu();
|
wxMenu& menuLog = *new wxMenu();
|
||||||
|
@ -312,9 +312,7 @@ int m_pendingFlushes = 0;
|
||||||
// and this one will magically follow suite. :)
|
// and this one will magically follow suite. :)
|
||||||
void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
|
void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
|
||||||
{
|
{
|
||||||
//#ifdef PCSX2_SEH
|
|
||||||
pthread_testcancel();
|
pthread_testcancel();
|
||||||
//#endif
|
|
||||||
|
|
||||||
ScopedLock lock( m_QueueLock );
|
ScopedLock lock( m_QueueLock );
|
||||||
|
|
||||||
|
@ -324,7 +322,7 @@ void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (m_QueueColorSection.GetLength() == 0) || ((color != Color_Current) && (m_QueueColorSection.GetLast().color != color)) )
|
if( (m_QueueColorSection.GetLength() == 0) || ((color != Color_Current) && (m_QueueColorSection.GetLast().color != color)) )
|
||||||
{
|
{
|
||||||
++m_CurQueuePos; // Don't overwrite the NULL;
|
++m_CurQueuePos; // Don't overwrite the NULL;
|
||||||
m_QueueColorSection.Add( ColorSection(color, m_CurQueuePos) );
|
m_QueueColorSection.Add( ColorSection(color, m_CurQueuePos) );
|
||||||
}
|
}
|
||||||
|
@ -333,10 +331,10 @@ void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
|
||||||
m_QueueBuffer.MakeRoomFor( endpos + 1 ); // and the null!!
|
m_QueueBuffer.MakeRoomFor( endpos + 1 ); // and the null!!
|
||||||
memcpy_fast( &m_QueueBuffer[m_CurQueuePos], text.c_str(), sizeof(wxChar) * text.Length() );
|
memcpy_fast( &m_QueueBuffer[m_CurQueuePos], text.c_str(), sizeof(wxChar) * text.Length() );
|
||||||
m_CurQueuePos = endpos;
|
m_CurQueuePos = endpos;
|
||||||
|
|
||||||
// this NULL may be overwritten if the next message sent doesn't perform a color change.
|
// this NULL may be overwritten if the next message sent doesn't perform a color change.
|
||||||
m_QueueBuffer[m_CurQueuePos] = 0;
|
m_QueueBuffer[m_CurQueuePos] = 0;
|
||||||
|
|
||||||
// Idle events don't always pass (wx blocks them when moving windows or using menus, for
|
// Idle events don't always pass (wx blocks them when moving windows or using menus, for
|
||||||
// example). So let's hackfix it so that an alternate message is posted if the queue is
|
// example). So let's hackfix it so that an alternate message is posted if the queue is
|
||||||
// "piling up."
|
// "piling up."
|
||||||
|
@ -355,7 +353,7 @@ void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
|
||||||
++m_WaitingThreadsForFlush;
|
++m_WaitingThreadsForFlush;
|
||||||
lock.Unlock();
|
lock.Unlock();
|
||||||
|
|
||||||
if( !m_sem_QueueFlushed.WaitRaw( wxTimeSpan( 0,0,0,500 ) ) )
|
if( !m_sem_QueueFlushed.Wait( wxTimeSpan( 0,0,0,500 ) ) )
|
||||||
{
|
{
|
||||||
// Necessary since the main thread could grab the lock and process before
|
// Necessary since the main thread could grab the lock and process before
|
||||||
// the above function actually returns (gotta love threading!)
|
// the above function actually returns (gotta love threading!)
|
||||||
|
@ -528,7 +526,7 @@ void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& evt )
|
||||||
// the textctrl has focus or not. The wxWidgets AppendText() function uses EM_LINESCROLL
|
// the textctrl has focus or not. The wxWidgets AppendText() function uses EM_LINESCROLL
|
||||||
// instead, which tends to be much faster for high-volume logs, but also ends up refreshing
|
// instead, which tends to be much faster for high-volume logs, but also ends up refreshing
|
||||||
// the console in sloppy fashion for normal logging.
|
// the console in sloppy fashion for normal logging.
|
||||||
|
|
||||||
// (both are needed, the WM_VSCROLL makes the scrolling smooth, and the EM_LINESCROLL avoids
|
// (both are needed, the WM_VSCROLL makes the scrolling smooth, and the EM_LINESCROLL avoids
|
||||||
// weird errors when the buffer reaches "max" and starts clearing old history)
|
// weird errors when the buffer reaches "max" and starts clearing old history)
|
||||||
|
|
||||||
|
|
|
@ -241,13 +241,19 @@ static DynGenFunc* _DynGen_DispatcherReg()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set to 0 for a speedup in release builds.
|
// Set to 0 for a speedup in release builds.
|
||||||
|
// [doesn't apply to GCC/Mac, which must always align]
|
||||||
#define PCSX2_IOP_FORCED_ALIGN_STACK 0 //1
|
#define PCSX2_IOP_FORCED_ALIGN_STACK 0 //1
|
||||||
|
|
||||||
|
|
||||||
|
// For overriding stackframe generation options in Debug builds (possibly useful for troubleshooting)
|
||||||
|
// Typically this value should be the same as IsDevBuild.
|
||||||
|
static const bool GenerateStackFrame = IsDevBuild;
|
||||||
|
|
||||||
static DynGenFunc* _DynGen_EnterRecompiledCode()
|
static DynGenFunc* _DynGen_EnterRecompiledCode()
|
||||||
{
|
{
|
||||||
u8* retval = xGetPtr();
|
u8* retval = xGetPtr();
|
||||||
|
|
||||||
bool allocatedStack = IsDevBuild || PCSX2_IOP_FORCED_ALIGN_STACK;
|
bool allocatedStack = GenerateStackFrame || PCSX2_IOP_FORCED_ALIGN_STACK;
|
||||||
|
|
||||||
// Optimization: The IOP never uses stack-based parameter invocation, so we can avoid
|
// Optimization: The IOP never uses stack-based parameter invocation, so we can avoid
|
||||||
// allocating any room on the stack for it (which is important since the IOP's entry
|
// allocating any room on the stack for it (which is important since the IOP's entry
|
||||||
|
@ -274,7 +280,7 @@ static DynGenFunc* _DynGen_EnterRecompiledCode()
|
||||||
// this is usually worthless because CALL+PUSH leaves us 8 byte aligned instead (fail). So
|
// this is usually worthless because CALL+PUSH leaves us 8 byte aligned instead (fail). So
|
||||||
// we have to do the usual set of stackframe alignments and simulated callstack mess
|
// we have to do the usual set of stackframe alignments and simulated callstack mess
|
||||||
// *regardless*.
|
// *regardless*.
|
||||||
|
|
||||||
// MSVC/Intel compilers:
|
// MSVC/Intel compilers:
|
||||||
// The PCSX2_IOP_FORCED_ALIGN_STACK setting is 0, so we don't care. Just push regs like
|
// The PCSX2_IOP_FORCED_ALIGN_STACK setting is 0, so we don't care. Just push regs like
|
||||||
// the good old days! (stack alignment will be indeterminate)
|
// the good old days! (stack alignment will be indeterminate)
|
||||||
|
@ -284,13 +290,12 @@ static DynGenFunc* _DynGen_EnterRecompiledCode()
|
||||||
xPUSH( ebx );
|
xPUSH( ebx );
|
||||||
|
|
||||||
allocatedStack = false;
|
allocatedStack = false;
|
||||||
CannotUseCallBecauseItWillUnalignTheGodDamnedStack = !!PCSX2_ASSUME_ALIGNED_STACK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uptr* imm = NULL;
|
uptr* imm = NULL;
|
||||||
if( allocatedStack )
|
if( allocatedStack )
|
||||||
{
|
{
|
||||||
if( IsDevBuild )
|
if( GenerateStackFrame )
|
||||||
{
|
{
|
||||||
// Simulate a CALL function by pushing the call address and EBP onto the stack.
|
// Simulate a CALL function by pushing the call address and EBP onto the stack.
|
||||||
// This retains proper stacktrace and stack unwinding (handy in devbuilds!)
|
// This retains proper stacktrace and stack unwinding (handy in devbuilds!)
|
||||||
|
@ -301,12 +306,15 @@ static DynGenFunc* _DynGen_EnterRecompiledCode()
|
||||||
// This part simulates the "normal" stackframe prep of "push ebp, mov ebp, esp"
|
// This part simulates the "normal" stackframe prep of "push ebp, mov ebp, esp"
|
||||||
xMOV( ptr32[esp+0x08], ebp );
|
xMOV( ptr32[esp+0x08], ebp );
|
||||||
xLEA( ebp, ptr32[esp+0x08] );
|
xLEA( ebp, ptr32[esp+0x08] );
|
||||||
|
|
||||||
xMOV( &s_store_esp, esp );
|
|
||||||
xMOV( &s_store_ebp, ebp );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( IsDevBuild )
|
||||||
|
{
|
||||||
|
xMOV( &s_store_esp, esp );
|
||||||
|
xMOV( &s_store_ebp, ebp );
|
||||||
|
}
|
||||||
|
|
||||||
xJMP( iopDispatcherReg );
|
xJMP( iopDispatcherReg );
|
||||||
if( imm != NULL )
|
if( imm != NULL )
|
||||||
*imm = (uptr)xGetPtr();
|
*imm = (uptr)xGetPtr();
|
||||||
|
@ -319,7 +327,7 @@ static DynGenFunc* _DynGen_EnterRecompiledCode()
|
||||||
if( allocatedStack )
|
if( allocatedStack )
|
||||||
{
|
{
|
||||||
// pop the nested "simulated call" stackframe, if needed:
|
// pop the nested "simulated call" stackframe, if needed:
|
||||||
if( IsDevBuild ) xLEAVE();
|
if( GenerateStackFrame ) xLEAVE();
|
||||||
xMOV( edi, ptr[ebp-12] );
|
xMOV( edi, ptr[ebp-12] );
|
||||||
xMOV( esi, ptr[ebp-8] );
|
xMOV( esi, ptr[ebp-8] );
|
||||||
xMOV( ebx, ptr[ebp-4] );
|
xMOV( ebx, ptr[ebp-4] );
|
||||||
|
@ -859,22 +867,22 @@ static __noinline s32 recExecuteBlock( s32 eeCycles )
|
||||||
// Register freezing note:
|
// Register freezing note:
|
||||||
// The IOP does not use mmx/xmm registers, so we don't modify the status
|
// The IOP does not use mmx/xmm registers, so we don't modify the status
|
||||||
// of the g_EEFreezeRegs here.
|
// of the g_EEFreezeRegs here.
|
||||||
|
|
||||||
// [TODO] recExecuteBlock could be replaced by a direct call to the iopEnterRecompiledCode()
|
// [TODO] recExecuteBlock could be replaced by a direct call to the iopEnterRecompiledCode()
|
||||||
// (by assigning its address to the psxRec structure). But for that to happen, we need
|
// (by assigning its address to the psxRec structure). But for that to happen, we need
|
||||||
// to move psxBreak/psxCycleEE update code to emitted assembly code. >_< --air
|
// to move psxBreak/psxCycleEE update code to emitted assembly code. >_< --air
|
||||||
|
|
||||||
// Likely Disasm, as borrowed from MSVC:
|
// Likely Disasm, as borrowed from MSVC:
|
||||||
|
|
||||||
// Entry:
|
// Entry:
|
||||||
// mov eax,dword ptr [esp+4]
|
// mov eax,dword ptr [esp+4]
|
||||||
// mov dword ptr [psxBreak (0E88DCCh)],0
|
// mov dword ptr [psxBreak (0E88DCCh)],0
|
||||||
// mov dword ptr [psxCycleEE (832A84h)],eax
|
// mov dword ptr [psxCycleEE (832A84h)],eax
|
||||||
|
|
||||||
// Exit:
|
// Exit:
|
||||||
// mov ecx,dword ptr [psxBreak (0E88DCCh)]
|
// mov ecx,dword ptr [psxBreak (0E88DCCh)]
|
||||||
// mov edx,dword ptr [psxCycleEE (832A84h)]
|
// mov edx,dword ptr [psxCycleEE (832A84h)]
|
||||||
// lea eax,[edx+ecx]
|
// lea eax,[edx+ecx]
|
||||||
|
|
||||||
iopEnterRecompiledCode();
|
iopEnterRecompiledCode();
|
||||||
|
|
||||||
|
|
|
@ -684,8 +684,17 @@ static void StateThreadCheck_LongJmp()
|
||||||
{
|
{
|
||||||
setjmp( SetJmp_StateCheck );
|
setjmp( SetJmp_StateCheck );
|
||||||
|
|
||||||
|
int oldstate;
|
||||||
|
|
||||||
|
// Important! Most of the console logging and such has cancel points in it. This is great
|
||||||
|
// in Windows, where SEH lets us safely kill a thread from anywhere we want. This is bad
|
||||||
|
// in Linux, which cannot have a C++ exception cross the recompiler. Hence the changing
|
||||||
|
// of the cancelstate here!
|
||||||
|
|
||||||
|
pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldstate );
|
||||||
mtgsThread.RethrowException();
|
mtgsThread.RethrowException();
|
||||||
SysCoreThread::Get().StateCheckInThread();
|
SysCoreThread::Get().StateCheckInThread();
|
||||||
|
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldstate );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void recExecute()
|
static void recExecute()
|
||||||
|
@ -847,17 +856,17 @@ void recClear(u32 addr, u32 size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUG__
|
#ifndef PCSX2_SEH
|
||||||
__threadlocal jmp_buf SetJmp_RecExecute;
|
jmp_buf SetJmp_RecExecute;
|
||||||
__threadlocal jmp_buf SetJmp_StateCheck;
|
jmp_buf SetJmp_StateCheck;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void ExitRec()
|
static void ExitRec()
|
||||||
{
|
{
|
||||||
#ifdef __GNUG__
|
#ifdef PCSX2_SEH
|
||||||
longjmp( SetJmp_RecExecute, SetJmp_Exit );
|
|
||||||
#else
|
|
||||||
throw Exception::ExitRecExecute();
|
throw Exception::ExitRecExecute();
|
||||||
|
#else
|
||||||
|
longjmp( SetJmp_RecExecute, SetJmp_Exit );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1085,7 +1094,7 @@ static u32 eeScaleBlockCycles()
|
||||||
static void iBranchTest(u32 newpc)
|
static void iBranchTest(u32 newpc)
|
||||||
{
|
{
|
||||||
_DynGen_StackFrameCheck();
|
_DynGen_StackFrameCheck();
|
||||||
|
|
||||||
if( g_ExecBiosHack ) CheckForBIOSEnd();
|
if( g_ExecBiosHack ) CheckForBIOSEnd();
|
||||||
|
|
||||||
// Check the Event scheduler if our "cycle target" has been reached.
|
// Check the Event scheduler if our "cycle target" has been reached.
|
||||||
|
@ -1313,7 +1322,7 @@ void __fastcall dyna_block_discard(u32 start,u32 sz)
|
||||||
recClear(start, sz);
|
recClear(start, sz);
|
||||||
|
|
||||||
// Stack trick: This function was invoked via a direct jmp, so manually pop the
|
// Stack trick: This function was invoked via a direct jmp, so manually pop the
|
||||||
// EBP/stackframe before issuing a RET, else esp/ebp will be incorrect.
|
// EBP/stackframe before issuing a RET, else esp/ebp will be incorrect.
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
__asm leave __asm jmp [ExitRecompiledCode]
|
__asm leave __asm jmp [ExitRecompiledCode]
|
||||||
|
|
Loading…
Reference in New Issue