/[pcsx2_0.9.7]/trunk/common/src/x86emitter/WinCpuDetect.cpp
ViewVC logotype

Annotation of /trunk/common/src/x86emitter/WinCpuDetect.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 10 months ago) by william
File size: 3568 byte(s)
committing r3113 initial commit again...
1 william 31 /* Cpudetection lib
2     * Copyright (C) 2002-2010 PCSX2 Dev Team
3     *
4     * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5     * of the GNU Lesser General Public License as published by the Free Software Found-
6     * ation, either version 3 of the License, or (at your option) any later version.
7     *
8     * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10     * PURPOSE. See the GNU General Public License for more details.
11     *
12     * You should have received a copy of the GNU General Public License along with PCSX2.
13     * If not, see <http://www.gnu.org/licenses/>.
14     */
15    
16    
17     #include "PrecompiledHeader.h"
18     #include "cpudetect_internal.h"
19    
20     void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU )
21     {
22     DWORD vProcessCPUs;
23     DWORD vSystemCPUs;
24    
25     x86caps.LogicalCores = 1;
26    
27     if( !GetProcessAffinityMask (GetCurrentProcess (),
28     &vProcessCPUs, &vSystemCPUs) ) return;
29    
30     int CPUs = 0;
31     DWORD bit;
32    
33     for (bit = 1; bit != 0; bit <<= 1)
34     {
35     if (vSystemCPUs & bit)
36     CPUs++;
37     }
38    
39     x86caps.LogicalCores = CPUs;
40     if( LogicalCoresPerPhysicalCPU > CPUs) // for 1-socket HTT-disabled machines
41     LogicalCoresPerPhysicalCPU = CPUs;
42    
43     x86caps.PhysicalCores = ( CPUs / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU;
44     }
45    
46     bool _test_instruction( void* pfnCall )
47     {
48     __try {
49     u128 regsave;
50     ((void (__fastcall *)(void*))pfnCall)( &regsave );
51     }
52     __except(EXCEPTION_EXECUTE_HANDLER) { return false; }
53    
54     return true;
55     }
56    
57     bool CanEmitShit()
58     {
59     // Under Windows, pre 0.9.6 versions of PCSX2 may not initialize the TLS
60     // register (FS register), so plugins (DLLs) using our x86emitter in multithreaded
61     // mode will just crash/fail if it tries to do the instruction set tests.
62    
63     #if x86EMIT_MULTITHREADED
64     static __threadlocal int tls_failcheck;
65     __try { tls_failcheck = 1; }
66     __except(EXCEPTION_EXECUTE_HANDLER) { return false; }
67     #endif
68    
69     return true;
70     }
71    
72     bool CanTestInstructionSets()
73     {
74     return CanEmitShit();
75     }
76    
77     SingleCoreAffinity::SingleCoreAffinity()
78     {
79     s_threadId = NULL;
80     s_oldmask = ERROR_INVALID_PARAMETER;
81    
82     DWORD_PTR availProcCpus, availSysCpus;
83     if( !GetProcessAffinityMask( GetCurrentProcess(), &availProcCpus, &availSysCpus ) ) return;
84    
85     int i;
86     for( i=0; i<32; ++i )
87     {
88     if( availProcCpus & (1<<i) ) break;
89     }
90    
91     s_threadId = GetCurrentThread();
92     s_oldmask = SetThreadAffinityMask( s_threadId, (1UL<<i) );
93    
94     if( s_oldmask == ERROR_INVALID_PARAMETER )
95     {
96     Console.Warning(
97     "CpuDetect: SetThreadAffinityMask failed...\n"
98     "\tSystem Affinity : 0x%08x"
99     "\tProcess Affinity: 0x%08x"
100     "\tAttempted Thread Affinity CPU: i",
101     availProcCpus, availSysCpus, i
102     );
103     }
104    
105     Sleep( 2 );
106    
107     // Sleep Explained: I arbitrarily pick Core 0 to lock to for running the CPU test. This
108     // means that the current thread will need to be switched to Core 0 if it's currently
109     // scheduled on a difference cpu/core. However, Windows does not necessarily perform
110     // that scheduling immediately upon the call to SetThreadAffinityMask (seems dependent
111     // on version: XP does, Win7 does not). So by issuing a Sleep here we give Win7 time
112     // to issue a timeslice and move our thread to Core 0. Without this, it tends to move
113     // the thread during the cpuSpeed test instead, causing totally wacky results.
114     };
115    
116     SingleCoreAffinity::~SingleCoreAffinity() throw()
117     {
118     if( s_oldmask != ERROR_INVALID_PARAMETER )
119     SetThreadAffinityMask( s_threadId, s_oldmask );
120     }
121    
122     void SetSingleAffinity()
123     {
124    
125     }
126    
127     void RestoreAffinity()
128     {
129     }

  ViewVC Help
Powered by ViewVC 1.1.22