Skip to content

Commit b04c151

Browse files
committed
Added support for multiple processor groups. Changed the ThreadAffinity class to use a new struct GroupAffinity. Changed operating system checks to make use of a new flag OperatingSystem.IsUnix.
1 parent 87c6f02 commit b04c151

25 files changed

Lines changed: 337 additions & 168 deletions

GUI/MainForm.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ public MainForm() {
130130
systemTray.HideShowCommand += hideShowClick;
131131
systemTray.ExitCommand += exitClick;
132132

133-
int p = (int)Environment.OSVersion.Platform;
134-
if ((p == 4) || (p == 128)) { // Unix
133+
if (Hardware.OperatingSystem.IsUnix) { // Unix
135134
treeView.RowHeight = Math.Max(treeView.RowHeight, 18);
136135
splitContainer.BorderStyle = BorderStyle.None;
137136
splitContainer.Border3DStyle = Border3DStyle.Adjust;

GUI/NotifyIconAdv.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ public class NotifyIconAdv : IDisposable {
2323
private NotifyIconWindowsImplementation windowsNotifyIcon;
2424

2525
public NotifyIconAdv() {
26-
int p = (int)Environment.OSVersion.Platform;
27-
if ((p == 4) || (p == 128)) { // Unix
26+
if (Hardware.OperatingSystem.IsUnix) { // Unix
2827
genericNotifyIcon = new NotifyIcon();
2928
} else { // Windows
3029
windowsNotifyIcon = new NotifyIconWindowsImplementation();

GUI/StartupManager.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ private bool IsAdministrator() {
3939
}
4040

4141
public StartupManager() {
42-
int p = (int)System.Environment.OSVersion.Platform;
43-
if ((p == 4) || (p == 128)) {
42+
if (Hardware.OperatingSystem.IsUnix) {
4443
scheduler = null;
4544
isAvailable = false;
4645
return;

Hardware/ATI/ADL.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,7 @@ private static void GetDelegate<T>(string entryPoint, out T newDelegate)
431431
}
432432

433433
private static void CreateDelegates(string name) {
434-
int p = (int)Environment.OSVersion.Platform;
435-
if ((p == 4) || (p == 128))
434+
if (OperatingSystem.IsUnix)
436435
dllName = name + ".so";
437436
else
438437
dllName = name + ".dll";

Hardware/CPU/AMD0FCPU.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,9 @@ public override void Update() {
129129
Thread.Sleep(1);
130130

131131
uint eax, edx;
132-
if (Ring0.RdmsrTx(FIDVID_STATUS, out eax, out edx,
133-
1UL << cpuid[i][0].Thread)) {
132+
if (Ring0.RdmsrTx(FIDVID_STATUS, out eax, out edx,
133+
cpuid[i][0].Affinity))
134+
{
134135
// CurrFID can be found in eax bits 0-5, MaxFID in 16-21
135136
// 8-13 hold StartFID, we don't use that here.
136137
double curMP = 0.5 * ((eax & 0x3F) + 8);

Hardware/CPU/AMD10CPU.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public AMD10CPU(int processorIndex, CPUID[][] cpuid, ISettings settings)
108108
corePerformanceBoostSupport = (cpuid[0][0].ExtData[7, 3] & (1 << 9)) > 0;
109109

110110
// set affinity to the first thread for all frequency estimations
111-
ulong mask = ThreadAffinity.Set(1UL << cpuid[0][0].Thread);
111+
var previousAffinity = ThreadAffinity.Set(cpuid[0][0].Affinity);
112112

113113
// disable core performance boost
114114
uint hwcrEax, hwcrEdx;
@@ -132,12 +132,11 @@ public AMD10CPU(int processorIndex, CPUID[][] cpuid, ISettings settings)
132132
Ring0.Wrmsr(HWCR, hwcrEax, hwcrEdx);
133133

134134
// restore the thread affinity.
135-
ThreadAffinity.Set(mask);
135+
ThreadAffinity.Set(previousAffinity);
136136

137137
// the file reader for lm-sensors support on Linux
138138
temperatureStream = null;
139-
int p = (int)Environment.OSVersion.Platform;
140-
if ((p == 4) || (p == 128)) {
139+
if (OperatingSystem.IsUnix) {
141140
string[] devicePaths = Directory.GetDirectories("/sys/class/hwmon/");
142141
foreach (string path in devicePaths) {
143142
string name = null;
@@ -345,8 +344,8 @@ public override void Update() {
345344
Thread.Sleep(1);
346345

347346
uint curEax, curEdx;
348-
if (Ring0.RdmsrTx(COFVID_STATUS, out curEax, out curEdx,
349-
1UL << cpuid[i][0].Thread))
347+
if (Ring0.RdmsrTx(COFVID_STATUS, out curEax, out curEdx,
348+
cpuid[i][0].Affinity))
350349
{
351350
double multiplier;
352351
multiplier = GetCoreMultiplier(curEax);

Hardware/CPU/AMD17CPU.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ public override void Update() {
272272
private class Core {
273273

274274
private readonly AMD17CPU cpu;
275-
private readonly ulong threadAffinityMask;
275+
private readonly GroupAffinity affinity;
276276

277277
private readonly Sensor powerSensor;
278278
private readonly Sensor clockSensor;
@@ -284,7 +284,7 @@ private class Core {
284284
public Core(int index, CPUID[] threads, AMD17CPU cpu, ISettings settings)
285285
{
286286
this.cpu = cpu;
287-
this.threadAffinityMask = 1UL << threads[0].Thread;
287+
this.affinity = threads[0].Affinity;
288288

289289
string coreString = cpu.CoreString(index);
290290
this.powerSensor =
@@ -294,7 +294,7 @@ public Core(int index, CPUID[] threads, AMD17CPU cpu, ISettings settings)
294294

295295
if (cpu.energyUnitMultiplier != 0) {
296296
if (Ring0.RdmsrTx(MSR_CORE_ENERGY_STAT, out uint energyConsumed,
297-
out _, threadAffinityMask))
297+
out _, affinity))
298298
{
299299
lastEnergyTime = DateTime.UtcNow;
300300
lastEnergyConsumed = energyConsumed;
@@ -319,13 +319,13 @@ public void Update() {
319319
DateTime energyTime = DateTime.MinValue;
320320
double? multiplier = null;
321321

322-
ulong mask = ThreadAffinity.Set(threadAffinityMask);
322+
var previousAffinity = ThreadAffinity.Set(affinity);
323323
if (Ring0.Rdmsr(MSR_CORE_ENERGY_STAT, out uint energyConsumed, out _)) {
324324
energyTime = DateTime.UtcNow;
325325
}
326326

327327
multiplier = GetMultiplier();
328-
ThreadAffinity.Set(mask);
328+
ThreadAffinity.Set(previousAffinity);
329329

330330
if (cpu.energyUnitMultiplier != 0) {
331331
float deltaTime = (float)(energyTime - lastEnergyTime).TotalSeconds;

Hardware/CPU/CPUGroup.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,17 @@ internal class CPUGroup : IGroup {
2323
private static CPUID[][] GetProcessorThreads() {
2424

2525
List<CPUID> threads = new List<CPUID>();
26-
for (int i = 0; i < 64; i++) {
27-
try {
28-
threads.Add(new CPUID(i));
29-
} catch (ArgumentOutOfRangeException) { }
26+
for (int i = 0; i < ThreadAffinity.ProcessorGroupCount; i++) {
27+
for (int j = 0; j < 64; j++) {
28+
try {
29+
if (!ThreadAffinity.IsValid(GroupAffinity.Single((ushort)i, j)))
30+
continue;
31+
var cpuid = CPUID.Get(i, j);
32+
if (cpuid != null)
33+
threads.Add(cpuid);
34+
} catch (ArgumentOutOfRangeException) {
35+
}
36+
}
3037
}
3138

3239
SortedDictionary<uint, List<CPUID>> processors =
@@ -172,6 +179,7 @@ public string GetReport() {
172179
r.AppendLine();
173180
for (int j = 0; j < threads[i].Length; j++)
174181
for (int k = 0; k < threads[i][j].Length; k++) {
182+
r.AppendLine(" CPU Group: " + threads[i][j][k].Group);
175183
r.AppendLine(" CPU Thread: " + threads[i][j][k].Thread);
176184
r.AppendLine(" APIC ID: " + threads[i][j][k].ApicId);
177185
r.AppendLine(" Processor ID: " + threads[i][j][k].ProcessorId);

Hardware/CPU/CPUID.cs

Lines changed: 81 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ internal enum Vendor {
2121

2222
internal class CPUID {
2323

24+
private readonly int group;
2425
private readonly int thread;
26+
private readonly GroupAffinity affinity;
2527

2628
private readonly Vendor vendor = Vendor.Unknown;
2729

@@ -68,83 +70,87 @@ private static uint NextLog2(long x) {
6870
return count;
6971
}
7072

71-
public CPUID(int thread) {
73+
public static CPUID Get(int group, int thread) {
74+
if (thread >= 64)
75+
return null;
76+
77+
var affinity = GroupAffinity.Single((ushort)group, thread);
78+
79+
var previousAffinity = ThreadAffinity.Set(affinity);
80+
if (previousAffinity == GroupAffinity.Undefined)
81+
return null;
82+
83+
try {
84+
return new CPUID(group, thread, affinity);
85+
} finally {
86+
ThreadAffinity.Set(previousAffinity);
87+
}
88+
}
89+
90+
private CPUID(int group, int thread, GroupAffinity affinity) {
91+
this.group = group;
7292
this.thread = thread;
93+
this.affinity = affinity;
7394

7495
uint maxCpuid = 0;
7596
uint maxCpuidExt = 0;
7697

7798
uint eax, ebx, ecx, edx;
7899

79-
if (thread >= 64)
80-
throw new ArgumentOutOfRangeException("thread");
81-
ulong mask = 1UL << thread;
82-
83-
if (Opcode.CpuidTx(CPUID_0, 0,
84-
out eax, out ebx, out ecx, out edx, mask)) {
85-
if (eax > 0)
86-
maxCpuid = eax;
87-
else
88-
return;
89-
90-
StringBuilder vendorBuilder = new StringBuilder();
91-
AppendRegister(vendorBuilder, ebx);
92-
AppendRegister(vendorBuilder, edx);
93-
AppendRegister(vendorBuilder, ecx);
94-
string cpuVendor = vendorBuilder.ToString();
95-
switch (cpuVendor) {
96-
case "GenuineIntel":
97-
vendor = Vendor.Intel;
98-
break;
99-
case "AuthenticAMD":
100-
vendor = Vendor.AMD;
101-
break;
102-
default:
103-
vendor = Vendor.Unknown;
104-
break;
105-
}
106-
eax = ebx = ecx = edx = 0;
107-
if (Opcode.CpuidTx(CPUID_EXT, 0,
108-
out eax, out ebx, out ecx, out edx, mask)) {
109-
if (eax > CPUID_EXT)
110-
maxCpuidExt = eax - CPUID_EXT;
111-
else
112-
return;
113-
} else {
114-
throw new ArgumentOutOfRangeException("thread");
115-
}
116-
} else {
117-
throw new ArgumentOutOfRangeException("thread");
100+
Opcode.Cpuid(CPUID_0, 0, out eax, out ebx, out ecx, out edx);
101+
if (eax > 0)
102+
maxCpuid = eax;
103+
else
104+
return;
105+
106+
StringBuilder vendorBuilder = new StringBuilder();
107+
AppendRegister(vendorBuilder, ebx);
108+
AppendRegister(vendorBuilder, edx);
109+
AppendRegister(vendorBuilder, ecx);
110+
string cpuVendor = vendorBuilder.ToString();
111+
switch (cpuVendor) {
112+
case "GenuineIntel":
113+
vendor = Vendor.Intel;
114+
break;
115+
case "AuthenticAMD":
116+
vendor = Vendor.AMD;
117+
break;
118+
default:
119+
vendor = Vendor.Unknown;
120+
break;
118121
}
122+
eax = ebx = ecx = edx = 0;
123+
Opcode.Cpuid(CPUID_EXT, 0, out eax, out ebx, out ecx, out edx);
124+
if (eax > CPUID_EXT)
125+
maxCpuidExt = eax - CPUID_EXT;
126+
else
127+
return;
119128

120129
maxCpuid = Math.Min(maxCpuid, 1024);
121-
maxCpuidExt = Math.Min(maxCpuidExt, 1024);
130+
maxCpuidExt = Math.Min(maxCpuidExt, 1024);
122131

123132
cpuidData = new uint[maxCpuid + 1, 4];
124133
for (uint i = 0; i < (maxCpuid + 1); i++)
125-
Opcode.CpuidTx(CPUID_0 + i, 0,
134+
Opcode.Cpuid(CPUID_0 + i, 0,
126135
out cpuidData[i, 0], out cpuidData[i, 1],
127-
out cpuidData[i, 2], out cpuidData[i, 3], mask);
136+
out cpuidData[i, 2], out cpuidData[i, 3]);
128137

129138
cpuidExtData = new uint[maxCpuidExt + 1, 4];
130139
for (uint i = 0; i < (maxCpuidExt + 1); i++)
131-
Opcode.CpuidTx(CPUID_EXT + i, 0,
132-
out cpuidExtData[i, 0], out cpuidExtData[i, 1],
133-
out cpuidExtData[i, 2], out cpuidExtData[i, 3], mask);
140+
Opcode.Cpuid(CPUID_EXT + i, 0,
141+
out cpuidExtData[i, 0], out cpuidExtData[i, 1],
142+
out cpuidExtData[i, 2], out cpuidExtData[i, 3]);
134143

135144
StringBuilder nameBuilder = new StringBuilder();
136145
for (uint i = 2; i <= 4; i++) {
137-
if (Opcode.CpuidTx(CPUID_EXT + i, 0,
138-
out eax, out ebx, out ecx, out edx, mask))
139-
{
140-
AppendRegister(nameBuilder, eax);
141-
AppendRegister(nameBuilder, ebx);
142-
AppendRegister(nameBuilder, ecx);
143-
AppendRegister(nameBuilder, edx);
144-
}
146+
Opcode.Cpuid(CPUID_EXT + i, 0, out eax, out ebx, out ecx, out edx);
147+
AppendRegister(nameBuilder, eax);
148+
AppendRegister(nameBuilder, ebx);
149+
AppendRegister(nameBuilder, ecx);
150+
AppendRegister(nameBuilder, edx);
145151
}
146152
nameBuilder.Replace('\0', ' ');
147-
cpuBrandString = nameBuilder.ToString().Trim();
153+
cpuBrandString = nameBuilder.ToString().Trim();
148154
nameBuilder.Replace("Dual-Core Processor", "");
149155
nameBuilder.Replace("Triple-Core Processor", "");
150156
nameBuilder.Replace("Quad-Core Processor", "");
@@ -175,7 +181,7 @@ public CPUID(int thread) {
175181
nameBuilder.Replace("RADEON R5, 10 COMPUTE CORES 4C+6G", "");
176182
nameBuilder.Replace("RADEON R7, 10 COMPUTE CORES 4C+6G", "");
177183
nameBuilder.Replace("RADEON R7, 12 COMPUTE CORES 4C+8G", "");
178-
nameBuilder.Replace("Radeon R5, 6 Compute Cores 2C+4G", "");
184+
nameBuilder.Replace("Radeon R5, 6 Compute Cores 2C+4G", "");
179185
nameBuilder.Replace("Radeon R5, 8 Compute Cores 4C+4G", "");
180186
nameBuilder.Replace("Radeon R6, 10 Compute Cores 4C+6G", "");
181187
nameBuilder.Replace("Radeon R7, 10 Compute Cores 4C+6G", "");
@@ -191,7 +197,7 @@ public CPUID(int thread) {
191197
name = nameBuilder.ToString();
192198
if (name.Contains("@"))
193199
name = name.Remove(name.LastIndexOf('@'));
194-
name = name.Trim();
200+
name = name.Trim();
195201

196202
this.family = ((cpuidData[1, 0] & 0x0FF00000) >> 20) +
197203
((cpuidData[1, 0] & 0x0F00) >> 8);
@@ -209,14 +215,14 @@ public CPUID(int thread) {
209215
maxCoreIdPerPackage = ((cpuidData[4, 0] >> 26) & 0x3F) + 1;
210216
else
211217
maxCoreIdPerPackage = 1;
212-
threadMaskWith =
218+
threadMaskWith =
213219
NextLog2(maxCoreAndThreadIdPerPackage / maxCoreIdPerPackage);
214220
coreMaskWith = NextLog2(maxCoreIdPerPackage);
215221
break;
216-
case Vendor.AMD:
222+
case Vendor.AMD:
217223
if (this.family == 0x17) {
218224
coreMaskWith = (cpuidExtData[8, 2] >> 12) & 0xF;
219-
threadMaskWith =
225+
threadMaskWith =
220226
NextLog2(((cpuidExtData[0x1E, 1] >> 8) & 0xFF) + 1);
221227
} else {
222228
uint corePerPackage;
@@ -226,7 +232,7 @@ public CPUID(int thread) {
226232
corePerPackage = 1;
227233
coreMaskWith = NextLog2(corePerPackage);
228234
threadMaskWith = 0;
229-
}
235+
}
230236
break;
231237
default:
232238
threadMaskWith = 0;
@@ -235,11 +241,11 @@ public CPUID(int thread) {
235241
}
236242

237243
processorId = (apicId >> (int)(coreMaskWith + threadMaskWith));
238-
coreId = ((apicId >> (int)(threadMaskWith))
244+
coreId = ((apicId >> (int)(threadMaskWith))
239245
- (processorId << (int)(coreMaskWith)));
240246
threadId = apicId
241247
- (processorId << (int)(coreMaskWith + threadMaskWith))
242-
- (coreId << (int)(threadMaskWith));
248+
- (coreId << (int)(threadMaskWith));
243249
}
244250

245251
public string Name {
@@ -250,10 +256,22 @@ public string BrandString {
250256
get { return cpuBrandString; }
251257
}
252258

259+
public int Group {
260+
get {
261+
return group;
262+
}
263+
}
264+
253265
public int Thread {
254266
get { return thread; }
255267
}
256268

269+
public GroupAffinity Affinity {
270+
get {
271+
return affinity;
272+
}
273+
}
274+
257275
public Vendor Vendor {
258276
get { return vendor; }
259277
}

0 commit comments

Comments
 (0)