mirror of
https://github.com/ayufan/steam-deck-tools.git
synced 2026-02-08 16:44:23 +01:00
Use global mutex to ensure driver access are sequential
This commit is contained in:
parent
a1a438c3f8
commit
f7e3e70c2b
|
|
@ -6,6 +6,7 @@ using System.Security;
|
|||
using System.Security.Principal;
|
||||
using System.Security.AccessControl;
|
||||
using System.Windows.Forms;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CommonHelpers
|
||||
{
|
||||
|
|
@ -21,10 +22,44 @@ namespace CommonHelpers
|
|||
};
|
||||
|
||||
private static Mutex? runOnceMutex;
|
||||
private static Mutex? globalLockMutex;
|
||||
|
||||
private const String GLOBAL_MUTEX_NAME = "Global\\SteamDeckToolsCommonHelpers";
|
||||
private const int GLOBAL_DEFAULT_TIMEOUT = 5000;
|
||||
|
||||
public static Mutex? WaitGlobalMutex(int timeoutMs)
|
||||
{
|
||||
if (globalLockMutex == null)
|
||||
globalLockMutex = TryCreateOrOpenExistingMutex(GLOBAL_MUTEX_NAME);
|
||||
|
||||
try
|
||||
{
|
||||
if (globalLockMutex.WaitOne(timeoutMs))
|
||||
return globalLockMutex;
|
||||
return null;
|
||||
}
|
||||
catch(AbandonedMutexException)
|
||||
{
|
||||
return globalLockMutex;
|
||||
}
|
||||
}
|
||||
|
||||
public static T WithGlobalMutex<T>(int timeoutMs, Func<T> func)
|
||||
{
|
||||
var mutex = WaitGlobalMutex(timeoutMs);
|
||||
if (mutex is null)
|
||||
return default(T);
|
||||
|
||||
try
|
||||
{
|
||||
return func();
|
||||
}
|
||||
finally
|
||||
{
|
||||
mutex.ReleaseMutex();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Open(String title, String? runOnce = null, int runOnceTimeout = 100)
|
||||
{
|
||||
if (runOnce is not null)
|
||||
|
|
@ -32,9 +67,11 @@ namespace CommonHelpers
|
|||
RunOnce(title, runOnce, runOnceTimeout);
|
||||
}
|
||||
|
||||
using (var globalLock = TryCreateOrOpenExistingMutex(GLOBAL_MUTEX_NAME))
|
||||
var mutex = WaitGlobalMutex(GLOBAL_DEFAULT_TIMEOUT);
|
||||
|
||||
try
|
||||
{
|
||||
if (!globalLock.WaitOne(GLOBAL_DEFAULT_TIMEOUT))
|
||||
if (mutex is null)
|
||||
{
|
||||
Fatal(title, "Failed to acquire global mutex.");
|
||||
}
|
||||
|
|
@ -51,8 +88,10 @@ namespace CommonHelpers
|
|||
}
|
||||
|
||||
HardwareComputer.Open();
|
||||
|
||||
globalLock.ReleaseMutex();
|
||||
}
|
||||
finally
|
||||
{
|
||||
mutex.ReleaseMutex();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,11 +73,27 @@ namespace FanControl
|
|||
|
||||
public void Update()
|
||||
{
|
||||
foreach (var sensor in allSensors.Values)
|
||||
sensor.Reset();
|
||||
var mutex = Instance.WaitGlobalMutex(200);
|
||||
|
||||
foreach (var hardware in Instance.HardwareComputer.Hardware)
|
||||
visitHardware(hardware);
|
||||
if (mutex is null)
|
||||
{
|
||||
// If we cannot acquire mutex slightly increase FAN to compensate just in case
|
||||
Vlv0100.SetFanDesiredRPM((ushort)(Vlv0100.GetFanDesiredRPM() * 110 / 100));
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var sensor in allSensors.Values)
|
||||
sensor.Reset();
|
||||
|
||||
foreach (var hardware in Instance.HardwareComputer.Hardware)
|
||||
visitHardware(hardware);
|
||||
}
|
||||
finally
|
||||
{
|
||||
mutex.ReleaseMutex();
|
||||
}
|
||||
|
||||
allSensors["Batt"].Update("VLV0100", Vlv0100.GetBattTemperature(), Mode);
|
||||
|
||||
|
|
|
|||
|
|
@ -334,19 +334,23 @@ namespace PerformanceOverlay
|
|||
|
||||
public void Update()
|
||||
{
|
||||
var allSensors = new List<ISensor>();
|
||||
|
||||
foreach (IHardware hardware in Instance.HardwareComputer.Hardware)
|
||||
Instance.WithGlobalMutex(200, () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
hardware.Update();
|
||||
}
|
||||
catch (SystemException) { }
|
||||
hardware.Accept(new SensorVisitor(sensor => allSensors.Add(sensor)));
|
||||
}
|
||||
var allSensors = new List<ISensor>();
|
||||
|
||||
this.AllHardwareSensors = allSensors;
|
||||
foreach (IHardware hardware in Instance.HardwareComputer.Hardware)
|
||||
{
|
||||
try
|
||||
{
|
||||
hardware.Update();
|
||||
}
|
||||
catch (SystemException) { }
|
||||
hardware.Accept(new SensorVisitor(sensor => allSensors.Add(sensor)));
|
||||
}
|
||||
|
||||
this.AllHardwareSensors = allSensors;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public string? GetValue(String name)
|
||||
|
|
|
|||
|
|
@ -51,21 +51,25 @@ namespace PowerControl.Helpers.GPU
|
|||
return true;
|
||||
}
|
||||
|
||||
public VangoghGPU? Open()
|
||||
public VangoghGPU? Open(bool validateSMU = true)
|
||||
{
|
||||
var gpu = VangoghGPU.OpenMMIO(MMIOAddress, MMIOSize);
|
||||
if (gpu == null)
|
||||
return null;
|
||||
|
||||
// Check supported SMU version
|
||||
var smuVersion = gpu.SMUVersion;
|
||||
if (smuVersion != SMUVersion)
|
||||
if (validateSMU)
|
||||
{
|
||||
Log("SMU: {0:X8} => not supported", smuVersion);
|
||||
return null;
|
||||
// Check supported SMU version
|
||||
var smuVersion = gpu.SMUVersion;
|
||||
if (smuVersion != SMUVersion)
|
||||
{
|
||||
Log("SMU: {0:X8} => not supported", smuVersion);
|
||||
return null;
|
||||
}
|
||||
|
||||
Log("SMU: {0:X8} => detected", smuVersion);
|
||||
}
|
||||
|
||||
Log("SMU: {0:X8} => detected", smuVersion);
|
||||
return gpu;
|
||||
}
|
||||
};
|
||||
|
|
@ -85,7 +89,7 @@ namespace PowerControl.Helpers.GPU
|
|||
|
||||
public static VangoghGPU? Open()
|
||||
{
|
||||
return DetectedDevice?.Open();
|
||||
return DetectedDevice?.Open(false);
|
||||
}
|
||||
|
||||
public static bool Detect()
|
||||
|
|
|
|||
|
|
@ -160,14 +160,19 @@ namespace PowerControl
|
|||
|
||||
if (VangoghGPU.IsSupported)
|
||||
{
|
||||
using (var sd = VangoghGPU.Open())
|
||||
return Instance.WithGlobalMutex<object>(200, () =>
|
||||
{
|
||||
if (sd is null)
|
||||
return null;
|
||||
using (var sd = VangoghGPU.Open())
|
||||
{
|
||||
if (sd is null)
|
||||
return null;
|
||||
|
||||
sd.SlowTDP = mW;
|
||||
sd.FastTDP = mW;
|
||||
}
|
||||
sd.SlowTDP = mW;
|
||||
sd.FastTDP = mW;
|
||||
}
|
||||
|
||||
return selected;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -185,9 +190,9 @@ namespace PowerControl
|
|||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
});
|
||||
}
|
||||
|
||||
return selected;
|
||||
return selected;
|
||||
}
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
|
|
@ -200,20 +205,23 @@ namespace PowerControl
|
|||
ResetValue = () => { return "Default"; },
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
using (var sd = VangoghGPU.Open())
|
||||
return Instance.WithGlobalMutex<object>(200, () =>
|
||||
{
|
||||
if (sd is null)
|
||||
return null;
|
||||
|
||||
if (selected.ToString() == "Default")
|
||||
using (var sd = VangoghGPU.Open())
|
||||
{
|
||||
sd.HardMinGfxClock = 200;
|
||||
if (sd is null)
|
||||
return null;
|
||||
|
||||
if (selected.ToString() == "Default")
|
||||
{
|
||||
sd.HardMinGfxClock = 200;
|
||||
return selected;
|
||||
}
|
||||
|
||||
sd.HardMinGfxClock = uint.Parse(selected.ToString().Replace("MHz", ""));
|
||||
return selected;
|
||||
}
|
||||
|
||||
sd.HardMinGfxClock = uint.Parse(selected.ToString().Replace("MHz", ""));
|
||||
return selected;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
|
|
@ -226,38 +234,41 @@ namespace PowerControl
|
|||
ResetValue = () => { return "Default"; },
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
using (var sd = VangoghGPU.Open())
|
||||
return Instance.WithGlobalMutex<object>(200, () =>
|
||||
{
|
||||
if (sd is null)
|
||||
return null;
|
||||
|
||||
switch(selected.ToString())
|
||||
using (var sd = VangoghGPU.Open())
|
||||
{
|
||||
case "Default":
|
||||
sd.MinCPUClock = 1400;
|
||||
sd.MaxCPUClock = 3500;
|
||||
break;
|
||||
|
||||
case "Power-Save":
|
||||
sd.MinCPUClock = 1400;
|
||||
sd.MaxCPUClock = 1800;
|
||||
break;
|
||||
|
||||
case "Balanced":
|
||||
sd.MinCPUClock = 2200;
|
||||
sd.MaxCPUClock = 2800;
|
||||
break;
|
||||
|
||||
case "Max":
|
||||
sd.MinCPUClock = 3000;
|
||||
sd.MaxCPUClock = 3500;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (sd is null)
|
||||
return null;
|
||||
|
||||
switch(selected.ToString())
|
||||
{
|
||||
case "Default":
|
||||
sd.MinCPUClock = 1400;
|
||||
sd.MaxCPUClock = 3500;
|
||||
break;
|
||||
|
||||
case "Power-Save":
|
||||
sd.MinCPUClock = 1400;
|
||||
sd.MaxCPUClock = 1800;
|
||||
break;
|
||||
|
||||
case "Balanced":
|
||||
sd.MinCPUClock = 2200;
|
||||
sd.MaxCPUClock = 2800;
|
||||
break;
|
||||
|
||||
case "Max":
|
||||
sd.MinCPUClock = 3000;
|
||||
sd.MaxCPUClock = 3500;
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace PowerControl
|
|||
{
|
||||
Trace.WriteLine("WinRing0 initialized=" + WinRing0.InitializeOls().ToString());
|
||||
|
||||
VangoghGPU.Detect();
|
||||
Instance.WithGlobalMutex(1000, () => VangoghGPU.Detect());
|
||||
}
|
||||
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
|
|
|
|||
Loading…
Reference in a new issue