1
- using System . ComponentModel ;
1
+ using System ;
2
+ using System . ComponentModel ;
2
3
using System . Runtime . InteropServices ;
3
4
4
5
namespace BenchmarkDotNet . Running ;
@@ -9,15 +10,27 @@ private static class PInvoke
9
10
{
10
11
public static SafePowerHandle PowerCreateRequest ( string reason )
11
12
{
12
- REASON_CONTEXT context = new REASON_CONTEXT ( )
13
+ IntPtr reasonPtr = Marshal . StringToHGlobalAuto ( reason ) ;
14
+ try
13
15
{
14
- Version = POWER_REQUEST_CONTEXT_VERSION ,
15
- Flags = POWER_REQUEST_CONTEXT_FLAGS . POWER_REQUEST_CONTEXT_SIMPLE_STRING ,
16
- SimpleReasonString = reason
17
- } ;
18
- SafePowerHandle safePowerHandle = PowerCreateRequest ( context ) ;
19
- if ( safePowerHandle . IsInvalid ) { throw new Win32Exception ( ) ; }
20
- return safePowerHandle ;
16
+ REASON_CONTEXT context = new REASON_CONTEXT ( )
17
+ {
18
+ Version = POWER_REQUEST_CONTEXT_VERSION ,
19
+ Flags = POWER_REQUEST_CONTEXT_FLAGS . POWER_REQUEST_CONTEXT_SIMPLE_STRING ,
20
+ Reason = new REASON_CONTEXT . REASON_CONTEXT_UNION { SimpleReasonString = reasonPtr }
21
+
22
+ } ;
23
+ SafePowerHandle safePowerHandle = PowerCreateRequest ( context ) ;
24
+ if ( safePowerHandle . IsInvalid ) { throw new Win32Exception ( ) ; }
25
+ return safePowerHandle ;
26
+ }
27
+ finally
28
+ {
29
+ if ( reasonPtr != IntPtr . Zero )
30
+ {
31
+ Marshal . FreeHGlobal ( reasonPtr ) ;
32
+ }
33
+ }
21
34
}
22
35
23
36
[ DllImport ( "kernel32.dll" , ExactSpelling = true , SetLastError = true ) ]
@@ -48,14 +61,34 @@ public static void PowerClearRequest(SafePowerHandle safePowerHandle, POWER_REQU
48
61
[ DllImport ( "kernel32.dll" , ExactSpelling = true , SetLastError = true ) ]
49
62
public static extern bool CloseHandle ( nint hObject ) ;
50
63
64
+ [ StructLayout ( LayoutKind . Sequential , CharSet = CharSet . Unicode ) ]
51
65
private struct REASON_CONTEXT
52
66
{
53
67
public uint Version ;
54
68
55
69
public POWER_REQUEST_CONTEXT_FLAGS Flags ;
56
70
57
- [ MarshalAs ( UnmanagedType . LPWStr ) ]
58
- public string SimpleReasonString ;
71
+ public REASON_CONTEXT_UNION Reason ;
72
+
73
+ [ StructLayout ( LayoutKind . Explicit , CharSet = CharSet . Unicode ) ]
74
+ public struct REASON_CONTEXT_UNION
75
+ {
76
+ [ FieldOffset ( 0 ) ]
77
+ public nint SimpleReasonString ;
78
+
79
+ // The DETAILED structure is not (yet) used, but needed for ARM CPUs, otherwise PowerCreateRequest fails, see #2745
80
+ [ FieldOffset ( 0 ) ]
81
+ public DETAILED Detailed ;
82
+
83
+ [ StructLayout ( LayoutKind . Sequential , CharSet = CharSet . Unicode ) ]
84
+ public struct DETAILED
85
+ {
86
+ public nint LocalizedReasonModule ;
87
+ public uint LocalizedReasonId ;
88
+ public uint ReasonStringCount ;
89
+ public nint ReasonStrings ;
90
+ }
91
+ }
59
92
}
60
93
61
94
private const uint POWER_REQUEST_CONTEXT_VERSION = 0U ;
0 commit comments