* Fixed crash problems when using SPU2-X with old versions of Pcsx2 (0.9.4 and prior).
 * Fixed broken Device specification override (the device GUID wasn't being loaded from the INI).

Pcsx2:
 * Added ThreadAffinity stuff to the CPUSpeed detection.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1368 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-06-15 16:44:26 +00:00
parent b9cb1d3a59
commit 136716a4f5
8 changed files with 71 additions and 35 deletions

View File

@ -180,20 +180,54 @@ static char* bool_to_char( bool testcond )
#endif
#ifdef _WINDOWS_
static HANDLE s_threadId = NULL;
static DWORD s_oldmask = ERROR_INVALID_PARAMETER;
#endif
static void SetSingleAffinity()
{
#ifdef _WINDOWS_
// Assign a single CPU thread affinity to ensure rdtsc() accuracy.
// (rdtsc for each CPU/core can differ, causing skewed results)
DWORD_PTR availProcCpus, availSysCpus;
if( !GetProcessAffinityMask( GetCurrentProcess(), &availProcCpus, &availSysCpus ) ) return;
int i;
for( i=0; i<32; ++i )
{
if( availProcCpus & (1<<i) ) break;
}
HANDLE s_threadId = GetCurrentThread();
DWORD s_oldmask = SetThreadAffinityMask( s_threadId, (1UL<<i) );
if( s_oldmask == ERROR_INVALID_PARAMETER )
{
Console::Notice(
"CpuDetect: SetThreadAffinityMask failed...\n"
"\tSystem Affinity : 0x%08x"
"\tProcess Affinity: 0x%08x"
"\tAttempted Thread Affinity CPU: i",
params availProcCpus, availSysCpus, i
);
}
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
//
s64 CPUSpeedHz( u64 time )
{
u64 timeStart,
timeStop;
s64 startTick,
endTick;
u64 timeStart, timeStop;
s64 startTick, endTick;
if( ! cpucaps.hasTimeStampCounter )
return 0; //check if function is supported
SetSingleAffinity();
if( ! cpucaps.hasTimeStampCounter )
{
return 0; //check if function is supported
}
// Align the cpu execution to a cpuTick boundary.
do { timeStart = GetCPUTicks();
@ -213,6 +247,11 @@ s64 CPUSpeedHz( u64 time )
}
while( ( timeStop - timeStart ) < time );
#ifdef _WINDOWS_
if( s_oldmask != ERROR_INVALID_PARAMETER )
SetThreadAffinityMask( s_threadId, s_oldmask );
#endif
return (s64)( endTick - startTick );
}

View File

@ -307,8 +307,7 @@ EXPORT_C_(void) SPU2shutdown()
EXPORT_C_(void) SPU2setClockPtr(u32 *ptr)
{
cPtr=ptr;
hasPtr=(cPtr!=NULL);
cyclePtr = ptr;
}
bool numpad_plus = false, numpad_plus_old = false;
@ -341,14 +340,14 @@ EXPORT_C_(void) SPU2async(u32 cycles)
numpad_plus_old = numpad_plus;*/
}
if(hasPtr)
if(cyclePtr != NULL)
{
TimeUpdate(*cPtr);
TimeUpdate( *cyclePtr );
}
else
{
pClocks+=cycles;
TimeUpdate(pClocks);
pClocks += cycles;
TimeUpdate( pClocks );
}
}
@ -373,7 +372,7 @@ EXPORT_C_(u16) SPU2read(u32 rmem)
}
else
{
TimeUpdate( *cPtr );
TimeUpdate( *cyclePtr );
if (rmem>>16 == 0x1f80)
{
@ -430,7 +429,9 @@ EXPORT_C_(void) SPU2write(u32 rmem, u16 value)
// If the SPU2 isn't in in sync with the IOP, samples can end up playing at rather
// incorrect pitches and loop lengths.
TimeUpdate( *cPtr );
if( cyclePtr != NULL )
TimeUpdate( *cyclePtr );
if (rmem>>16 == 0x1f80)
SPU_ps1_write(rmem,value);
else

View File

@ -313,7 +313,7 @@ void DoDMAWrite(int core,u16 *pMem,u32 size)
void SPU2readDMA(int core, u16* pMem, u32 size)
{
if(hasPtr) TimeUpdate(*cPtr);
if( cyclePtr != NULL ) TimeUpdate( *cyclePtr );
Cores[core].TSA &= 0xffff8;
@ -394,7 +394,7 @@ void SPU2readDMA(int core, u16* pMem, u32 size)
void SPU2writeDMA(int core, u16* pMem, u32 size)
{
if(hasPtr) TimeUpdate(*cPtr);
if(cyclePtr != NULL) TimeUpdate(*cyclePtr);
Cores[core].DMAPtr=pMem;

View File

@ -53,10 +53,8 @@ s16 OutPos;
s16 InputPos;
u32 Cycles;
u32* cPtr=NULL;
u32 lClocks=0;
bool hasPtr=false;
u32* cyclePtr = NULL;
u32 lClocks = 0;
int PlayMode;
@ -932,10 +930,13 @@ __forceinline void SPU2_FastWrite( u32 rmem, u16 value )
if( ((value>>15)&1) && (!thiscore.CoreEnabled) && (thiscore.InitDelay==0) ) // on init/reset
{
if(hasPtr)
// When we have exact cycle update info from the Pcsx2 IOP unit, then use
// the more accurate delayed initialization system.
if(cyclePtr != NULL)
{
thiscore.InitDelay=1;
thiscore.Regs.STATX=0;
thiscore.InitDelay = 1;
thiscore.Regs.STATX = 0;
}
else
{

View File

@ -174,13 +174,12 @@ extern int PlayMode;
extern int recording;
extern u32 lClocks;
extern u32* cPtr;
extern bool hasPtr;
extern u32* cyclePtr;
extern void SPU2writeLog( const char* action, u32 rmem, u16 value );
extern void TimeUpdate(u32 cClocks);
extern u16 SPU_ps1_read(u32 mem);
extern u16 SPU_ps1_read(u32 mem);
extern void SPU_ps1_write(u32 mem, u16 value);
extern void SPU2_FastWrite( u32 rmem, u16 value );

View File

@ -110,7 +110,7 @@ void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSi
}
}
void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring Data, int DataSize, const TCHAR* Default)
void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring& Data, int DataSize, const TCHAR* Default)
{
wchar_t workspace[512];
GetPrivateProfileString(Section,Name,L"",workspace,DataSize,CfgFile);

View File

@ -69,7 +69,7 @@ void CfgWriteInt(const TCHAR* Section, const TCHAR* Name, int Value);
void CfgWriteStr(const TCHAR* Section, const TCHAR* Name, const wstring& Data);
bool CfgReadBool(const TCHAR *Section,const TCHAR* Name, bool Default);
void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring Data, int DataSize, const TCHAR* Default);
void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring& Data, int DataSize, const TCHAR* Default);
void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSize, const TCHAR* Default);
int CfgReadInt(const TCHAR* Section, const TCHAR* Name,int Default);

View File

@ -194,10 +194,6 @@ public:
for(uint i=0;i<m_NumBuffers;i++)
{
// [Air] note: wfx.nBlockAlign modifier was *10 -- seems excessive to me but maybe
// it was needed for some quirky driver? Theoretically we want the notification as soon
// as possible after the buffer has finished playing.
buffer_events[i] = CreateEvent(NULL,FALSE,FALSE,NULL);
not[i].dwOffset = (wfx.nBlockAlign + BufferSizeBytes*(i+1)) % desc.dwBufferBytes;
not[i].hEventNotify = buffer_events[i];