Fixed the Recent Iso List, which got broken a few revs back... and many more wee bug fixes, most are too unimportant to list here!!

Code Cleanups:
 * cpuDetect: Split Win32/Linux code portions into separate modules. (probably breaks linux)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2205 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-11-16 13:54:32 +00:00
parent b40dd9253d
commit af7bb73948
15 changed files with 445 additions and 298 deletions

View File

@ -1,123 +1,125 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file> <CodeBlocks_project_file>
<FileVersion major="1" minor="6" /> <FileVersion major="1" minor="6" />
<Project> <Project>
<Option title="x86emitter" /> <Option title="x86emitter" />
<Option pch_mode="2" /> <Option pch_mode="2" />
<Option compiler="gcc" /> <Option compiler="gcc" />
<Build> <Build>
<Target title="Debug"> <Target title="Debug">
<Option output="../../../deps/debug/libx86emitter.a" prefix_auto="0" extension_auto="0" /> <Option output="../../../deps/debug/libx86emitter.a" prefix_auto="0" extension_auto="0" />
<Option working_dir="" /> <Option working_dir="" />
<Option object_output="./.objs/debug/" /> <Option object_output="./.objs/debug/" />
<Option type="2" /> <Option type="2" />
<Option compiler="gcc" /> <Option compiler="gcc" />
<Option createDefFile="1" /> <Option createDefFile="1" />
<Compiler> <Compiler>
<Add option="-Wall" /> <Add option="-Wall" />
<Add option="-g" /> <Add option="-g" />
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=yes --cflags`" /> <Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=yes --cflags`" />
<Add option="-DPCSX2_DEVBUILD" /> <Add option="-DPCSX2_DEVBUILD" />
<Add option="-DPCSX2_DEBUG" /> <Add option="-DPCSX2_DEBUG" />
</Compiler> </Compiler>
</Target> </Target>
<Target title="Release"> <Target title="Release">
<Option output="../../../deps/release/libx86emitter.a" prefix_auto="0" extension_auto="0" /> <Option output="../../../deps/release/libx86emitter.a" prefix_auto="0" extension_auto="0" />
<Option working_dir="" /> <Option working_dir="" />
<Option object_output="./.objs/release/" /> <Option object_output="./.objs/release/" />
<Option type="2" /> <Option type="2" />
<Option compiler="gcc" /> <Option compiler="gcc" />
<Option createDefFile="1" /> <Option createDefFile="1" />
<Compiler> <Compiler>
<Add option="-O2" /> <Add option="-O2" />
<Add option="-Wall" /> <Add option="-Wall" />
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=no --cflags`" /> <Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=no --cflags`" />
<Add option="-DNDEBUG" /> <Add option="-DNDEBUG" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add option="-s" /> <Add option="-s" />
</Linker> </Linker>
</Target> </Target>
<Target title="Devel"> <Target title="Devel">
<Option output="../../../deps/devel/libx86emitter.a" prefix_auto="0" extension_auto="0" /> <Option output="../../../deps/devel/libx86emitter.a" prefix_auto="0" extension_auto="0" />
<Option working_dir="" /> <Option working_dir="" />
<Option object_output="./.objs/devel" /> <Option object_output="./.objs/devel" />
<Option type="2" /> <Option type="2" />
<Option compiler="gcc" /> <Option compiler="gcc" />
<Option createDefFile="1" /> <Option createDefFile="1" />
<Compiler> <Compiler>
<Add option="-O2" /> <Add option="-O2" />
<Add option="-Wall" /> <Add option="-Wall" />
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=no --cflags`" /> <Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=no --cflags`" />
<Add option="-DPCSX2_DEVBUILD" /> <Add option="-DPCSX2_DEVBUILD" />
<Add option="-DPCSX2_DEVEL" /> <Add option="-DPCSX2_DEVEL" />
<Add option="-DNDEBUG" /> <Add option="-DNDEBUG" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add option="-s" /> <Add option="-s" />
</Linker> </Linker>
</Target> </Target>
</Build> </Build>
<Compiler> <Compiler>
<Add option="-march=i486" /> <Add option="-march=i486" />
<Add option="-Wno-format" /> <Add option="-Wno-format" />
<Add option="-Wno-unused-parameter" /> <Add option="-Wno-unused-parameter" />
<Add option="-Wno-unused-value" /> <Add option="-Wno-unused-value" />
<Add option="-Wunused-variable" /> <Add option="-Wunused-variable" />
<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="-fno-strict-aliasing" />
<Add option="-pipe -msse -msse2" /> <Add option="-pipe -msse -msse2" />
<Add option="-m32" /> <Add option="-m32" />
<Add directory="../../include/x86emitter" /> <Add directory="../../include/x86emitter" />
<Add directory="../../include" /> <Add directory="../../include" />
</Compiler> </Compiler>
<Unit filename="../../include/x86emitter/implement/dwshift.h" /> <Unit filename="../../include/x86emitter/implement/dwshift.h" />
<Unit filename="../../include/x86emitter/implement/group1.h" /> <Unit filename="../../include/x86emitter/implement/group1.h" />
<Unit filename="../../include/x86emitter/implement/group2.h" /> <Unit filename="../../include/x86emitter/implement/group2.h" />
<Unit filename="../../include/x86emitter/implement/group3.h" /> <Unit filename="../../include/x86emitter/implement/group3.h" />
<Unit filename="../../include/x86emitter/implement/helpers.h" /> <Unit filename="../../include/x86emitter/implement/helpers.h" />
<Unit filename="../../include/x86emitter/implement/incdec.h" /> <Unit filename="../../include/x86emitter/implement/incdec.h" />
<Unit filename="../../include/x86emitter/implement/jmpcall.h" /> <Unit filename="../../include/x86emitter/implement/jmpcall.h" />
<Unit filename="../../include/x86emitter/implement/movs.h" /> <Unit filename="../../include/x86emitter/implement/movs.h" />
<Unit filename="../../include/x86emitter/implement/simd_arithmetic.h" /> <Unit filename="../../include/x86emitter/implement/simd_arithmetic.h" />
<Unit filename="../../include/x86emitter/implement/simd_comparisons.h" /> <Unit filename="../../include/x86emitter/implement/simd_comparisons.h" />
<Unit filename="../../include/x86emitter/implement/simd_helpers.h" /> <Unit filename="../../include/x86emitter/implement/simd_helpers.h" />
<Unit filename="../../include/x86emitter/implement/simd_moremovs.h" /> <Unit filename="../../include/x86emitter/implement/simd_moremovs.h" />
<Unit filename="../../include/x86emitter/implement/simd_shufflepack.h" /> <Unit filename="../../include/x86emitter/implement/simd_shufflepack.h" />
<Unit filename="../../include/x86emitter/implement/simd_templated_helpers.h" /> <Unit filename="../../include/x86emitter/implement/simd_templated_helpers.h" />
<Unit filename="../../include/x86emitter/implement/test.h" /> <Unit filename="../../include/x86emitter/implement/test.h" />
<Unit filename="../../include/x86emitter/implement/xchg.h" /> <Unit filename="../../include/x86emitter/implement/xchg.h" />
<Unit filename="../../include/x86emitter/implement/xmm/moremovs.h" /> <Unit filename="../../include/x86emitter/implement/xmm/moremovs.h" />
<Unit filename="../../include/x86emitter/implement/xmm/shufflepack.h" /> <Unit filename="../../include/x86emitter/implement/xmm/shufflepack.h" />
<Unit filename="../../include/x86emitter/inlines.inl" /> <Unit filename="../../include/x86emitter/inlines.inl" />
<Unit filename="../../include/x86emitter/instructions.h" /> <Unit filename="../../include/x86emitter/instructions.h" />
<Unit filename="../../include/x86emitter/internal.h" /> <Unit filename="../../include/x86emitter/internal.h" />
<Unit filename="../../include/x86emitter/legacy_instructions.h" /> <Unit filename="../../include/x86emitter/legacy_instructions.h" />
<Unit filename="../../include/x86emitter/legacy_internal.h" /> <Unit filename="../../include/x86emitter/legacy_internal.h" />
<Unit filename="../../include/x86emitter/legacy_types.h" /> <Unit filename="../../include/x86emitter/legacy_types.h" />
<Unit filename="../../include/x86emitter/macros.h" /> <Unit filename="../../include/x86emitter/macros.h" />
<Unit filename="../../include/x86emitter/sse_helpers.h" /> <Unit filename="../../include/x86emitter/sse_helpers.h" />
<Unit filename="../../include/x86emitter/tools.h" /> <Unit filename="../../include/x86emitter/tools.h" />
<Unit filename="../../include/x86emitter/x86emitter.h" /> <Unit filename="../../include/x86emitter/x86emitter.h" />
<Unit filename="../../include/x86emitter/x86types.h" /> <Unit filename="../../include/x86emitter/x86types.h" />
<Unit filename="../../src/x86emitter/3dnow.cpp" /> <Unit filename="../../src/x86emitter/3dnow.cpp" />
<Unit filename="../../src/x86emitter/PrecompiledHeader.h" /> <Unit filename="../../src/x86emitter/PrecompiledHeader.h" />
<Unit filename="../../src/x86emitter/cpudetect.cpp" /> <Unit filename="../../src/x86emitter/LnxCpuDetect.cpp" />
<Unit filename="../../src/x86emitter/fpu.cpp" /> <Unit filename="../../src/x86emitter/cpudetect.cpp" />
<Unit filename="../../src/x86emitter/groups.cpp" /> <Unit filename="../../src/x86emitter/cpudetect_internal.cpp" />
<Unit filename="../../src/x86emitter/jmp.cpp" /> <Unit filename="../../src/x86emitter/fpu.cpp" />
<Unit filename="../../src/x86emitter/legacy.cpp" /> <Unit filename="../../src/x86emitter/groups.cpp" />
<Unit filename="../../src/x86emitter/legacy_sse.cpp" /> <Unit filename="../../src/x86emitter/jmp.cpp" />
<Unit filename="../../src/x86emitter/movs.cpp" /> <Unit filename="../../src/x86emitter/legacy.cpp" />
<Unit filename="../../src/x86emitter/simd.cpp" /> <Unit filename="../../src/x86emitter/legacy_sse.cpp" />
<Unit filename="../../src/x86emitter/tools.cpp" /> <Unit filename="../../src/x86emitter/movs.cpp" />
<Unit filename="../../src/x86emitter/x86emitter.cpp" /> <Unit filename="../../src/x86emitter/simd.cpp" />
<Extensions> <Unit filename="../../src/x86emitter/tools.cpp" />
<envvars /> <Unit filename="../../src/x86emitter/x86emitter.cpp" />
<code_completion /> <Extensions>
<debugger /> <envvars />
</Extensions> <code_completion />
</Project> <debugger />
</CodeBlocks_project_file> </Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -205,6 +205,10 @@
RelativePath="..\..\src\x86emitter\cpudetect.cpp" RelativePath="..\..\src\x86emitter\cpudetect.cpp"
> >
</File> </File>
<File
RelativePath="..\..\src\x86emitter\cpudetect_internal.h"
>
</File>
<File <File
RelativePath="..\..\src\x86emitter\fpu.cpp" RelativePath="..\..\src\x86emitter\fpu.cpp"
> >
@ -269,6 +273,46 @@
RelativePath="..\..\src\x86emitter\x86emitter.cpp" RelativePath="..\..\src\x86emitter\x86emitter.cpp"
> >
</File> </File>
<Filter
Name="Linux"
>
<File
RelativePath="..\..\src\x86emitter\LnxCpuDetect.cpp"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Devel|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Windows"
>
<File
RelativePath="..\..\src\x86emitter\WinCpuDetect.cpp"
>
</File>
</Filter>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"

View File

@ -64,9 +64,6 @@ 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)
extern void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU );
// Releases a timeslice to other threads. // Releases a timeslice to other threads.
extern void Timeslice(); extern void Timeslice();

View File

@ -20,6 +20,9 @@
// this is all that needs to be called and will fill up the below structs // this is all that needs to be called and will fill up the below structs
extern void cpudetectInit(); extern void cpudetectInit();
// Returns the number of available logical CPUs (cores plus hyperthreaded cpus)
extern void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU );
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// x86CPU_INFO // x86CPU_INFO
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------

View File

@ -24,25 +24,6 @@
static bool isMultiCore = true; // assume more than one CPU (safer) static bool isMultiCore = true; // assume more than one CPU (safer)
// Note: Apparently this solution is Linux/Solaris only.
// FreeBSD/OsX need something far more complicated (apparently)
void Threading::CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU )
{
const uint numCPU = sysconf( _SC_NPROCESSORS_ONLN );
if( numCPU > 0 )
{
isMultiCore = numCPU > 1;
x86caps.LogicalCores = numCPU;
x86caps.PhysicalCores = ( numCPU / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU;
}
else
{
// Indeterminate?
x86caps.LogicalCores = 1;
x86caps.PhysicalCores = 1;
}
}
__forceinline void Threading::Sleep( int ms ) __forceinline void Threading::Sleep( int ms )
{ {
usleep( 1000*ms ); usleep( 1000*ms );

View File

@ -18,37 +18,6 @@
#include "x86emitter/tools.h" #include "x86emitter/tools.h"
#include "Threading.h" #include "Threading.h"
#ifdef _WIN32
#include "implement.h" // win32 pthreads implementations.
#endif
void Threading::CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU )
{
DWORD vProcessCPUs;
DWORD vSystemCPUs;
x86caps.LogicalCores = 1;
if( !GetProcessAffinityMask (GetCurrentProcess (),
&vProcessCPUs, &vSystemCPUs) ) return;
int CPUs = 0;
DWORD bit;
for (bit = 1; bit != 0; bit <<= 1)
{
if (vSystemCPUs & bit)
CPUs++;
}
x86caps.LogicalCores = CPUs;
if( LogicalCoresPerPhysicalCPU > CPUs) // for 1-socket HTT-disabled machines
LogicalCoresPerPhysicalCPU = CPUs;
x86caps.PhysicalCores = ( CPUs / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU;
//ptw32_smp_system = ( x86caps.LogicalCores > 1 ) ? TRUE : FALSE;
}
__forceinline void Threading::Sleep( int ms ) __forceinline void Threading::Sleep( int ms )
{ {
::Sleep( ms ); ::Sleep( ms );

View File

@ -0,0 +1,62 @@
/* Cpudetection lib
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* 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-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "cpudetect_internal.h"
s32 iCpuId( u32 cmd, u32 *regs )
{
// ecx should be zero for CPUID(4)
__asm__ __volatile__ ( "xor %ecx, %ecx" );
__cpuid( (int*)regs, cmd );
return 0;
}
// Note: Apparently this solution is Linux/Solaris only.
// FreeBSD/OsX need something far more complicated (apparently)
void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU )
{
const uint numCPU = sysconf( _SC_NPROCESSORS_ONLN );
if( numCPU > 0 )
{
isMultiCore = numCPU > 1;
x86caps.LogicalCores = numCPU;
x86caps.PhysicalCores = ( numCPU / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU;
}
else
{
// Indeterminate?
x86caps.LogicalCores = 1;
x86caps.PhysicalCores = 1;
}
}
bool CanTestInstructionSets()
{
// Not implemented yet for linux. (see cpudetect_internal.h for details)
return false;
}
bool _test_instruction( void* pfnCall )
{
// Not implemented yet for linux. (see cpudetect_internal.h for details)
return false;
}
// Not implemented yet for linux (see cpudetect_internal.h for details)
SingleCoreAffinity::SingleCoreAffinity() {}
SingleCoreAffinity::~SingleCoreAffinity() throw() {}

View File

@ -0,0 +1,112 @@
/* Cpudetection lib
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* 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-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "cpudetect_internal.h"
s32 iCpuId( u32 cmd, u32 *regs )
{
// ecx should be zero for CPUID(4)
__asm xor ecx, ecx;
__cpuid( (int*)regs, cmd );
return 0;
}
void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU )
{
DWORD vProcessCPUs;
DWORD vSystemCPUs;
x86caps.LogicalCores = 1;
if( !GetProcessAffinityMask (GetCurrentProcess (),
&vProcessCPUs, &vSystemCPUs) ) return;
int CPUs = 0;
DWORD bit;
for (bit = 1; bit != 0; bit <<= 1)
{
if (vSystemCPUs & bit)
CPUs++;
}
x86caps.LogicalCores = CPUs;
if( LogicalCoresPerPhysicalCPU > CPUs) // for 1-socket HTT-disabled machines
LogicalCoresPerPhysicalCPU = CPUs;
x86caps.PhysicalCores = ( CPUs / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU;
}
bool _test_instruction( void* pfnCall )
{
__try {
((void (*)())pfnCall)();
}
__except(EXCEPTION_EXECUTE_HANDLER) {
return false;
}
return true;
}
bool CanTestInstructionSets()
{
return true;
}
SingleCoreAffinity::SingleCoreAffinity()
{
s_threadId = NULL;
s_oldmask = ERROR_INVALID_PARAMETER;
DWORD_PTR availProcCpus, availSysCpus;
if( !GetProcessAffinityMask( GetCurrentProcess(), &availProcCpus, &availSysCpus ) ) return;
int i;
for( i=0; i<32; ++i )
{
if( availProcCpus & (1<<i) ) break;
}
s_threadId = GetCurrentThread();
s_oldmask = SetThreadAffinityMask( s_threadId, (1UL<<i) );
if( s_oldmask == ERROR_INVALID_PARAMETER )
{
Console.Warning(
"CpuDetect: SetThreadAffinityMask failed...\n"
"\tSystem Affinity : 0x%08x"
"\tProcess Affinity: 0x%08x"
"\tAttempted Thread Affinity CPU: i",
availProcCpus, availSysCpus, i
);
}
};
SingleCoreAffinity::~SingleCoreAffinity() throw()
{
if( s_oldmask != ERROR_INVALID_PARAMETER )
SetThreadAffinityMask( s_threadId, s_oldmask );
}
void SetSingleAffinity()
{
}
void RestoreAffinity()
{
}

View File

@ -13,98 +13,22 @@
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Utilities/RedtapeWindows.h" #include "cpudetect_internal.h"
#include "Utilities/Threading.h"
#include "internal.h" #include "internal.h"
#include "tools.h"
using namespace x86Emitter; using namespace x86Emitter;
__aligned16 x86CPU_INFO x86caps; __aligned16 x86CPU_INFO x86caps;
static s32 iCpuId( u32 cmd, u32 *regs )
{
#ifdef _MSC_VER
__asm xor ecx, ecx; // ecx should be zero for CPUID(4)
#else
__asm__ __volatile__ ( "xor %ecx, %ecx" );
#endif
__cpuid( (int*)regs, cmd );
return 0;
}
static u64 GetRdtsc( void )
{
return __rdtsc();
}
//////////////////////////////////////////////////////////////////////////////////////////
// Note: This function doesn't support GCC/Linux. Looking online it seems the only
// way to simulate the Microsoft SEH model is to use unix signals, and the 'sigaction'
// function specifically. Maybe a project for a linux developer at a later date. :)
//
#ifdef _MSC_VER
static bool _test_instruction( void* pfnCall )
{
__try {
((void (*)())pfnCall)();
}
__except(EXCEPTION_EXECUTE_HANDLER) {
return false;
}
return true;
}
static char* bool_to_char( bool testcond )
{
return testcond ? "true" : "false";
}
#endif
#ifdef __LINUX__ #ifdef __LINUX__
# include <sys/time.h> # include <sys/time.h>
# include <errno.h> # include <errno.h>
#endif #endif
#ifdef _WINDOWS_ static char* bool_to_char( bool testcond )
static HANDLE s_threadId = NULL;
static DWORD s_oldmask = ERROR_INVALID_PARAMETER;
#endif
static void SetSingleAffinity()
{ {
#ifdef _WINDOWS_ return testcond ? "true" : "false";
// 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;
}
s_threadId = GetCurrentThread();
s_oldmask = SetThreadAffinityMask( s_threadId, (1UL<<i) );
if( s_oldmask == ERROR_INVALID_PARAMETER )
{
Console.Warning(
"CpuDetect: SetThreadAffinityMask failed...\n"
"\tSystem Affinity : 0x%08x"
"\tProcess Affinity: 0x%08x"
"\tAttempted Thread Affinity CPU: i",
availProcCpus, availSysCpus, i
);
}
#endif
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -115,9 +39,9 @@ static s64 CPUSpeedHz( u64 time )
s64 startTick, endTick; s64 startTick, endTick;
if( ! x86caps.hasTimeStampCounter ) if( ! x86caps.hasTimeStampCounter )
return 0; //check if function is supported return 0;
SetSingleAffinity(); SingleCoreAffinity affinity_lock;
// Align the cpu execution to a cpuTick boundary. // Align the cpu execution to a cpuTick boundary.
@ -126,23 +50,18 @@ static s64 CPUSpeedHz( u64 time )
do do
{ {
timeStop = GetCPUTicks( ); timeStop = GetCPUTicks();
startTick = GetRdtsc( ); startTick = __rdtsc();
} while( ( timeStop - timeStart ) == 0 ); } while( ( timeStop - timeStart ) == 0 );
timeStart = timeStop; timeStart = timeStop;
do do
{ {
timeStop = GetCPUTicks(); timeStop = GetCPUTicks();
endTick = GetRdtsc(); endTick = __rdtsc();
} }
while( ( timeStop - timeStart ) < time ); while( ( timeStop - timeStart ) < time );
#ifdef _WINDOWS_
if( s_oldmask != ERROR_INVALID_PARAMETER )
SetThreadAffinityMask( s_threadId, s_oldmask );
#endif
return (s64)( endTick - startTick ); return (s64)( endTick - startTick );
} }
@ -327,20 +246,10 @@ void cpudetectInit()
HostSys::MemProtectStatic( recSSE, Protect_ReadWrite, true ); HostSys::MemProtectStatic( recSSE, Protect_ReadWrite, true );
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// SIMD Instruction Support Detection // SIMD Instruction Support Detection (Second Pass)
// //
// Can the SSE3 / SSE4.1 bits be trusted? Using an instruction test is a very "complete"
// approach to ensuring the instruction set is supported, and at least one reported case
// of a Q9550 not having it's SSE 4.1 bit set but still supporting it properly is fixed
// by this --air
// (note: the user who reported the case later fixed the problem by doing a CMOS reset)
//
// Linux support note: Linux/GCC doesn't have SEH-style exceptions which allow handling of
// CPU-level exceptions (__try/__except in msvc) so this code is disabled on GCC, and
// detection relies on the CPUID bits alone.
#ifdef _MSC_VER if( CanTestInstructionSets() )
if( recSSE != NULL )
{ {
xSetPtr( recSSE ); xSetPtr( recSSE );
xMOVSLDUP( xmm1, xmm0 ); xMOVSLDUP( xmm1, xmm0 );
@ -395,7 +304,6 @@ void cpudetectInit()
"\tRelying on CPUID results. [this is not an error]" "\tRelying on CPUID results. [this is not an error]"
); );
} }
#endif
//////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////
// Establish MXCSR Mask... // Establish MXCSR Mask...
@ -424,6 +332,6 @@ void cpudetectInit()
LogicalCoresPerPhysicalCPU = 1; LogicalCoresPerPhysicalCPU = 1;
// This will assign values into x86caps.LogicalCores and PhysicalCores // This will assign values into x86caps.LogicalCores and PhysicalCores
Threading::CountLogicalCores( LogicalCoresPerPhysicalCPU, PhysicalCoresPerPhysicalCPU ); CountLogicalCores( LogicalCoresPerPhysicalCPU, PhysicalCoresPerPhysicalCPU );
} }

View File

@ -0,0 +1,56 @@
/* Cpudetection lib
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* 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-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "Utilities/RedtapeWindows.h"
#include "x86emitter/tools.h"
// --------------------------------------------------------------------------------------
// Thread Affinity Lock
// --------------------------------------------------------------------------------------
// Assign a single CPU/core for this thread's affinity to ensure rdtsc() accuracy.
// (rdtsc for each CPU/core can differ, causing skewed results)
class SingleCoreAffinity
{
protected:
#ifdef _WINDOWS_
HANDLE s_threadId;
DWORD s_oldmask;
#endif
public:
SingleCoreAffinity();
virtual ~SingleCoreAffinity() throw();
};
// --------------------------------------------------------------------------------------
// SIMD "Manual" Detection, using Invalid Instruction Checks
// --------------------------------------------------------------------------------------
//
// Note: This API doesn't support GCC/Linux. Looking online it seems the only
// way to simulate the Microsoft SEH model is to use unix signals, and the 'sigaction'
// function specifically. A linux coder could implement this using sigaction at a later
// date, however its not really a big deal: CPUID should be 99-100% accurate, as no modern
// software would work on the CPU if it mis-reported capabilities. However there are known
// cases of a CPU failing to report supporting instruction sets it does in fact support.
// This secondary test fixes such cases (although apparently a CMOS reset does as well).
//
extern bool CanTestInstructionSets();
extern bool _test_instruction( void* pfnCall );
extern s32 iCpuId( u32 cmd, u32 *regs );

View File

@ -65,24 +65,22 @@ const wxImage& LoadImageAny(
pxAppResources::pxAppResources() pxAppResources::pxAppResources()
{ {
// RecentIsoList and Menu must be created immediately, since they depend on listening for App configuration
// events that can be thrown very early ni program execution.
RecentIsoMenu = new wxMenu();
RecentIsoMenu->Append( MenuId_IsoBrowse, _("Browse..."), _("Browse for an Iso that is not in your recent history.") );
RecentIsoList = new RecentIsoManager( RecentIsoMenu );
} }
wxMenu& Pcsx2App::GetRecentIsoMenu() wxMenu& Pcsx2App::GetRecentIsoMenu()
{ {
if( !m_Resources->RecentIsoMenu ) pxAssert( m_Resources->RecentIsoMenu );
{
m_Resources->RecentIsoMenu = new wxMenu();
m_Resources->RecentIsoMenu->Append( MenuId_IsoBrowse, _("Browse..."), _("Browse for an Iso that is not in your recent history.") );
}
return *m_Resources->RecentIsoMenu; return *m_Resources->RecentIsoMenu;
} }
RecentIsoManager& Pcsx2App::GetRecentIsoList() RecentIsoManager& Pcsx2App::GetRecentIsoList()
{ {
if( !m_Resources->RecentIsoList ) pxAssert( m_Resources->RecentIsoList );
m_Resources->RecentIsoList = new RecentIsoManager( &GetRecentIsoMenu() );
return *m_Resources->RecentIsoList; return *m_Resources->RecentIsoList;
} }

View File

@ -337,10 +337,10 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title):
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
m_menuBoot.Append(MenuId_Boot_CDVD, _("Run CDVD"), m_menuBoot.Append(MenuId_Boot_CDVD, _("Run CDVD"),
_("Use this to access the PS2 system configuration menu")); _("For booting DVD discs or Isos, depending on the configured CDVD source."));
m_menuBoot.Append(MenuId_Boot_ELF, _("Run ELF File..."), m_menuBoot.Append(MenuId_Boot_ELF, _("Run ELF File..."),
_("For running raw binaries")); _("For running raw binaries directly"));
m_menuBoot.AppendSeparator(); m_menuBoot.AppendSeparator();
m_menuBoot.Append(MenuId_Exit, _("Exit"), m_menuBoot.Append(MenuId_Exit, _("Exit"),

View File

@ -16,13 +16,14 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "MainFrame.h" #include "MainFrame.h"
RecentIsoManager::RecentIsoManager( wxMenu* menu ) : RecentIsoManager::RecentIsoManager( wxMenu* menu )
m_Menu( menu ) : m_Menu( menu )
, m_MaxLength( g_Conf->RecentFileCount ) , m_MaxLength( g_Conf->RecentFileCount )
, m_cursel( 0 ) , m_Listener_SettingsLoadSave ( wxGetApp().Source_SettingsLoadSave(), EventListener<IniInterface>( this, OnSettingsLoadSave ) )
, m_Separator( NULL ) , m_Listener_SettingsApplied ( wxGetApp().Source_SettingsApplied(), EventListener<int>( this, OnSettingsApplied ) )
, m_Listener_SettingsLoadSave( wxGetApp().Source_SettingsLoadSave(), EventListener<IniInterface>( this, OnSettingsLoadSave ) )
{ {
m_cursel = 0;
m_Separator = NULL;
Connect( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(RecentIsoManager::OnChangedSelection) ); Connect( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(RecentIsoManager::OnChangedSelection) );
} }
@ -132,6 +133,11 @@ void RecentIsoManager::InsertIntoMenu( int id )
curitem.ItemPtr->Check(); curitem.ItemPtr->Check();
} }
void RecentIsoManager::DoSettingsApplied( int& ini )
{
// TODO : Implement application of Recent Iso List "maximum" history option
}
void RecentIsoManager::DoSettingsLoadSave( IniInterface& ini ) void RecentIsoManager::DoSettingsLoadSave( IniInterface& ini )
{ {
ini.GetConfig().SetRecordDefaults( false ); ini.GetConfig().SetRecordDefaults( false );
@ -173,3 +179,9 @@ void __evt_fastcall RecentIsoManager::OnSettingsLoadSave( void* obj, IniInterfac
if( obj == NULL ) return; if( obj == NULL ) return;
((RecentIsoManager*)obj)->DoSettingsLoadSave( ini ); ((RecentIsoManager*)obj)->DoSettingsLoadSave( ini );
} }
void __evt_fastcall RecentIsoManager::OnSettingsApplied( void* obj, int& ini )
{
if( obj == NULL ) return;
((RecentIsoManager*)obj)->DoSettingsApplied( ini );
}

View File

@ -44,6 +44,7 @@ protected:
wxMenuItem* m_Separator; wxMenuItem* m_Separator;
EventListenerBinding<IniInterface> m_Listener_SettingsLoadSave; EventListenerBinding<IniInterface> m_Listener_SettingsLoadSave;
EventListenerBinding<int> m_Listener_SettingsApplied;
public: public:
RecentIsoManager( wxMenu* menu ); RecentIsoManager( wxMenu* menu );
@ -56,8 +57,10 @@ public:
protected: protected:
void InsertIntoMenu( int id ); void InsertIntoMenu( int id );
void DoSettingsLoadSave( IniInterface& ini ); void DoSettingsLoadSave( IniInterface& ini );
void DoSettingsApplied( int& val );
void OnChangedSelection( wxCommandEvent& evt ); void OnChangedSelection( wxCommandEvent& evt );
static void __evt_fastcall OnSettingsLoadSave( void* obj, IniInterface& evt ); static void __evt_fastcall OnSettingsLoadSave( void* obj, IniInterface& evt );
static void __evt_fastcall OnSettingsApplied( void* obj, int& evt );
}; };

View File

@ -154,7 +154,7 @@ EXPORT_C_(s32) DEV9test()
#ifdef _WIN32 #ifdef _WIN32
EXPORT_C_(void) DEV9configure() EXPORT_C_(void) DEV9configure()
{ {
SysMessage("Nothing to Configure"); SysMessage("Nothing to Configure?!");
} }
EXPORT_C_(void) DEV9about() EXPORT_C_(void) DEV9about()
@ -170,7 +170,7 @@ void SysMessage(const char *fmt, ...)
va_start(list,fmt); va_start(list,fmt);
vsprintf(tmp,fmt,list); vsprintf(tmp,fmt,list);
va_end(list); va_end(list);
MessageBox(0, tmp, "DEV9null Msg", 0); MessageBox( GetActiveWindow(), tmp, "DEV9null Msg", MB_SETFOREGROUND | MB_OK );
} }
BOOL APIENTRY DllMain(HANDLE hModule, // DLL INIT BOOL APIENTRY DllMain(HANDLE hModule, // DLL INIT