ReactOS 0.4.15-dev-7788-g1ad9096
IdleTimeoutManagement Class Reference

#include <fxpowerpolicystatemachine.hpp>

Collaboration diagram for IdleTimeoutManagement:

Public Member Functions

 IdleTimeoutManagement (VOID)
 
 ~IdleTimeoutManagement (VOID)
 
NTSTATUS UseSystemManagedIdleTimeout (__in PFX_DRIVER_GLOBALS DriverGlobals)
 
VOID FreezeIdleTimeoutManagementStatus (__in PFX_DRIVER_GLOBALS DriverGlobals)
 
BOOLEAN UsingSystemManagedIdleTimeout (VOID)
 
NTSTATUS CommitPowerFrameworkSettings (__in PFX_DRIVER_GLOBALS DriverGlobals, __in PPOX_SETTINGS PoxSettings)
 
BOOLEAN DriverSpecifiedPowerFrameworkSettings (VOID)
 
PPOX_SETTINGS GetPowerFrameworkSettings (VOID)
 

Static Public Member Functions

static BOOLEAN _SystemManagedIdleTimeoutAvailable (VOID)
 

Private Types

enum  IdleTimeoutStatusFlag { IdleTimeoutStatusFrozen = 0x00000001 , IdleTimeoutSystemManaged = 0x00000002 , IdleTimeoutPoxSettingsSpecified = 0x00000004 }
 
enum  IdleTimeoutStatusUpdateResult { IdleTimeoutStatusFlagsUpdated , IdleTimeoutStatusFlagAlreadySet , IdleTimeoutStatusFlagsAlreadyFrozen , IdleTimeoutStatusFlagsUnexpected }
 

Private Member Functions

IdleTimeoutStatusUpdateResult UpdateIdleTimeoutStatus (__in IdleTimeoutStatusFlag Flag)
 
CfxDeviceGetDevice (VOID)
 

Private Attributes

LONG volatile m_IdleTimeoutStatus
 
PPOX_SETTINGS m_PoxSettings
 

Detailed Description

Definition at line 306 of file fxpowerpolicystatemachine.hpp.

Member Enumeration Documentation

◆ IdleTimeoutStatusFlag

Enumerator
IdleTimeoutStatusFrozen 
IdleTimeoutSystemManaged 
IdleTimeoutPoxSettingsSpecified 

Definition at line 335 of file fxpowerpolicystatemachine.hpp.

◆ IdleTimeoutStatusUpdateResult

Enumerator
IdleTimeoutStatusFlagsUpdated 
IdleTimeoutStatusFlagAlreadySet 
IdleTimeoutStatusFlagsAlreadyFrozen 
IdleTimeoutStatusFlagsUnexpected 

Definition at line 344 of file fxpowerpolicystatemachine.hpp.

344 {
345 //
346 // Flags were sucessfully updated
347 //
349
350 //
351 // The flag we were trying to set was already set
352 //
354
355 //
356 // It is too late to set the flag. The flags have already been frozen.
357 // Flags are frozen the first time a device is started.
358 //
360
361 //
362 // Flags are being set by multiple threads in parallel. This is not
363 // supported.
364 //
366 };

Constructor & Destructor Documentation

◆ IdleTimeoutManagement()

IdleTimeoutManagement::IdleTimeoutManagement ( VOID  )
inline

Definition at line 386 of file fxpowerpolicystatemachine.hpp.

390 {
391 }
#define NULL
Definition: types.h:112

◆ ~IdleTimeoutManagement()

IdleTimeoutManagement::~IdleTimeoutManagement ( VOID  )
inline

Definition at line 393 of file fxpowerpolicystatemachine.hpp.

396 {
397 BYTE * buffer = NULL;
398 ULONG poxSettingsOffset;
399
400 if (NULL != m_PoxSettings) {
401
403
404 //
405 // In the function FxPkgPnp::AssignPowerFrameworkSettings, we had
406 // allocated a buffer which we need to free now. Note that
407 // m_PoxSettings does not necessarily point to the beginning of the
408 // buffer. It points to the POX_SETTINGS structure in the buffer,
409 // which may or may not be in the beginning. If it is not in the
410 // beginning, figure out where the beginning of the buffer is.
411 //
412 if (m_PoxSettings->Component != NULL) {
413 //
414 // The computation below won't overflow because we already
415 // performed this computation successfully using safeint
416 // functions in FxPkgPnp::AssignPowerFrameworkSettings.
417 //
418 poxSettingsOffset =
419 (sizeof(*(m_PoxSettings->Component->IdleStates)) *
421 (sizeof(*(m_PoxSettings->Component)));
422 }
423 else {
424 poxSettingsOffset = 0;
425 }
426
427 //
428 // Move to the beginning of the buffer
429 //
430 buffer = buffer - poxSettingsOffset;
431
432 //
433 // Free the buffer
434 //
436 }
437 }
static __inline VOID MxFreePool(__in PVOID Ptr)
Definition: mxmemorykm.h:41
GLuint buffer
Definition: glext.h:5915
PPO_FX_COMPONENT Component
ULONG IdleStateCount
Definition: potypes.h:575
uint32_t ULONG
Definition: typedefs.h:59
unsigned char BYTE
Definition: xxhash.c:193

Member Function Documentation

◆ _SystemManagedIdleTimeoutAvailable()

BOOLEAN IdleTimeoutManagement::_SystemManagedIdleTimeoutAvailable ( VOID  )
static

Definition at line 211 of file supportkm.cpp.

214{
216}
FxLibraryGlobalsType FxLibraryGlobals
Definition: globals.cpp:95
PFN_POX_REGISTER_DEVICE PoxRegisterDevice
Definition: fxglobals.h:742

Referenced by CommitPowerFrameworkSettings(), FreezeIdleTimeoutManagementStatus(), FxPkgPnp::PowerPolicySetS0IdleSettings(), and UseSystemManagedIdleTimeout().

◆ CommitPowerFrameworkSettings()

NTSTATUS IdleTimeoutManagement::CommitPowerFrameworkSettings ( __in PFX_DRIVER_GLOBALS  DriverGlobals,
__in PPOX_SETTINGS  PoxSettings 
)

Definition at line 2379 of file powerpolicystatemachine.cpp.

2383{
2385 IdleTimeoutStatusUpdateResult statusUpdateResult;
2386 PVOID oldPoxSettings = NULL;
2387 BOOLEAN settingsSuccessfullySaved = FALSE;
2388 CfxDevice * device;
2389
2390 //
2391 // We should never get here if system-managed idle timeout is not available
2392 //
2394
2395 //
2396 // Get the device object so we can use it for logging
2397 //
2398 device = GetDevice();
2399
2400 //
2401 // Try to save the driver's power framework settings
2402 //
2404 PoxSettings,
2405 NULL // Comparand
2406 );
2407 if (NULL != oldPoxSettings) {
2408 //
2409 // The driver's power framework settings have already been specified
2410 // earlier. The driver should not be attempting to specify them more
2411 // than once.
2412 //
2416 "WDFDEVICE %p !devobj %p The driver attempted to specify power "
2417 "framework settings more than once. %!STATUS!.",
2418 device->GetHandle(),
2419 device->GetDeviceObject(),
2420 status
2421 );
2423 goto exit;
2424 }
2425 settingsSuccessfullySaved = TRUE;
2426
2427 //
2428 // Try to update the flag that indicates that the client driver has
2429 // specified settings that are to be used when we register with the power
2430 // framework.
2431 //
2432 statusUpdateResult = UpdateIdleTimeoutStatus(
2434 );
2435 switch (statusUpdateResult) {
2437 {
2438 //
2439 // Status is already frozen. Too late to update it.
2440 //
2444 "WDFDEVICE %p !devobj %p Power framework settings must be "
2445 "specified before the first start IRP is completed. %!STATUS!.",
2446 device->GetHandle(),
2447 device->GetDeviceObject(),
2448 status
2449 );
2451 goto exit;
2452 }
2453 break;
2454
2456 {
2457 //
2458 // Status being updated from multiple threads in parallel. Not
2459 // supported.
2460 //
2464 "WDFDEVICE %p !devobj %p Calls to assign S0-idle settings and "
2465 "to specify power framework settings are happening in parallel."
2466 " The driver needs to serialize these calls with respect to "
2467 "each other. %!STATUS!.",
2468 device->GetHandle(),
2469 device->GetDeviceObject(),
2470 status
2471 );
2473 goto exit;
2474 }
2475 break;
2476
2478 {
2479 //
2480 // Status flag was already set. This should never happen for the
2481 // IdleTimeoutPoxSettingsSpecified flag because we have logic in the
2482 // beginning of this function to ensure that only the first caller
2483 // attempts to set this flag.
2484 //
2485 ASSERTMSG(
2486 "Attempt to set the IdleTimeoutPoxSettingsSpecified flag more "
2487 "than once\n", FALSE);
2489 goto exit;
2490 }
2491
2493 {
2495 }
2496 break;
2497
2498 default:
2499 {
2500 ASSERTMSG("Unexpected IdleTimeoutStatusUpdateResult value\n",
2501 FALSE);
2503 goto exit;
2504 }
2505 }
2506
2507 //
2508 // If we get here, we must have a successful status
2509 //
2511
2512exit:
2513 if (FALSE == NT_SUCCESS(status)) {
2514 if (settingsSuccessfullySaved) {
2515 //
2516 // Since a failure has occurred, we must reset the pointer to the
2517 // power framework settings.
2518 //
2520 }
2521 }
2522 return status;
2523}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
IdleTimeoutStatusUpdateResult UpdateIdleTimeoutStatus(__in IdleTimeoutStatusFlag Flag)
static BOOLEAN _SystemManagedIdleTimeoutAvailable(VOID)
Definition: supportkm.cpp:211
#define TRACINGPNP
Definition: dbgtrace.h:67
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
return pList GetDevice()
FxVerifierDbgBreakPoint(pFxDriverGlobals)
DriverGlobals
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define ASSERT(a)
Definition: mode.c:44
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define exit(n)
Definition: config.h:202
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
Definition: devices.h:37
Definition: ps.c:97
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138

◆ DriverSpecifiedPowerFrameworkSettings()

BOOLEAN IdleTimeoutManagement::DriverSpecifiedPowerFrameworkSettings ( VOID  )

Definition at line 2371 of file powerpolicystatemachine.cpp.

2374{
2376}

◆ FreezeIdleTimeoutManagementStatus()

VOID IdleTimeoutManagement::FreezeIdleTimeoutManagementStatus ( __in PFX_DRIVER_GLOBALS  DriverGlobals)

Definition at line 2290 of file powerpolicystatemachine.cpp.

2293{
2294 LONG idleTimeoutSnapshot;
2295 LONG idleTimeoutStatus;
2296 LONG idleTimeoutPreviousStatus;
2297 CfxDevice * device;
2298
2299 //
2300 // Get the device object so we can use it for logging
2301 //
2302 device = GetDevice();
2303
2304 //
2305 // Take a snapshot of the idle timeout management status
2306 //
2307 idleTimeoutSnapshot = m_IdleTimeoutStatus;
2308
2309 //
2310 // Set the bit that freezes the status
2311 //
2312 idleTimeoutStatus = idleTimeoutSnapshot | IdleTimeoutStatusFrozen;
2313
2314 //
2315 // Update the status
2316 //
2317 idleTimeoutPreviousStatus = InterlockedExchange(&m_IdleTimeoutStatus,
2318 idleTimeoutStatus);
2319
2320 if (idleTimeoutPreviousStatus != idleTimeoutSnapshot) {
2321 //
2322 // An update of idle timeout status is racing with the freezing of idle
2323 // timeout status
2324 //
2327 "WDFDEVICE %p !devobj %p The driver's S0-idle settings and/or power"
2328 " framework settings did not take effect because they were supplied"
2329 " too late. The driver must ensure that the settings are provided "
2330 "before the first start IRP is completed.",
2331 device->GetHandle(),
2332 device->GetDeviceObject()
2333 );
2335 }
2336
2337 //
2338 // If the driver has specified power framework settings and system managed
2339 // idle timeout is available on this OS, then the driver must have opted for
2340 // system managed idle timeout.
2341 //
2342 if ((0 != (idleTimeoutStatus & IdleTimeoutPoxSettingsSpecified)) &&
2344 (0 == (idleTimeoutStatus & IdleTimeoutSystemManaged))) {
2347 "WDFDEVICE %p !devobj %p The driver specified power framework "
2348 "settings, but did not opt for system-managed idle timeout.",
2349 device->GetHandle(),
2350 device->GetDeviceObject()
2351 );
2353 }
2354}
#define InterlockedExchange
Definition: armddk.h:54
long LONG
Definition: pedump.c:60
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28

◆ GetDevice()

CfxDevice * IdleTimeoutManagement::GetDevice ( VOID  )
private

Definition at line 2087 of file powerpolicystatemachine.cpp.

2090{
2091 IdlePolicySettings * idlePolicySettings = NULL;
2092 FxPowerPolicyOwnerSettings * ppoSettings = NULL;
2093 FxPkgPnp * pPkgPnp = NULL;
2094
2095 idlePolicySettings = (IdlePolicySettings *) CONTAINING_RECORD(
2096 this,
2098 m_TimeoutMgmt
2099 );
2101 idlePolicySettings,
2103 m_IdleSettings
2104 );
2105 pPkgPnp = ppoSettings->m_PkgPnp;
2106
2107 return pPkgPnp->GetDevice();
2108}
__inline CfxDevice * GetDevice(VOID)
Definition: fxpackage.hpp:46
FxPkgPnp * pPkgPnp
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

◆ GetPowerFrameworkSettings()

PPOX_SETTINGS IdleTimeoutManagement::GetPowerFrameworkSettings ( VOID  )
inline

Definition at line 472 of file fxpowerpolicystatemachine.hpp.

475 {
476 return m_PoxSettings;
477 }

◆ UpdateIdleTimeoutStatus()

IdleTimeoutManagement::IdleTimeoutStatusUpdateResult IdleTimeoutManagement::UpdateIdleTimeoutStatus ( __in IdleTimeoutStatusFlag  Flag)
private

Definition at line 2111 of file powerpolicystatemachine.cpp.

2114{
2115 LONG idleTimeoutStatusSnapshot;
2116 LONG updatedIdleTimeoutStatus;
2117 LONG preInterlockedIdleTimeoutStatus;
2118
2119 //
2120 // Take a snapshot of the idle timeout management status
2121 //
2122 idleTimeoutStatusSnapshot = m_IdleTimeoutStatus;
2123
2124 //
2125 // Verify that the flag we're trying to set is not already set
2126 //
2127 if (0 != (idleTimeoutStatusSnapshot & Flag)) {
2129 }
2130
2131 //
2132 // Verify that the idle timeout management status is not already
2133 // "frozen"
2134 //
2135 if (0 != (idleTimeoutStatusSnapshot & IdleTimeoutStatusFrozen)) {
2136 //
2137 // It was too late to set the flag. The flag value was already
2138 // "frozen".
2139 //
2141 }
2142
2143 //
2144 // Try to set the flag
2145 //
2146 updatedIdleTimeoutStatus = idleTimeoutStatusSnapshot | Flag;
2147
2148 preInterlockedIdleTimeoutStatus = InterlockedCompareExchange(
2150 updatedIdleTimeoutStatus,
2151 idleTimeoutStatusSnapshot
2152 );
2153 if (preInterlockedIdleTimeoutStatus != idleTimeoutStatusSnapshot) {
2154
2155 if (0 != (preInterlockedIdleTimeoutStatus &
2157 //
2158 // It was too late to set the flag. The flag value was already
2159 // "frozen".
2160 //
2162 }
2163 else {
2164 //
2165 // Idle timeout management status is being changed by multiple
2166 // threads in parallel. This is not supported.
2167 //
2169 }
2170 }
2171
2172 //
2173 // We have successfully set the flag
2174 //
2176}
#define InterlockedCompareExchange
Definition: interlocked.h:104
Definition: xml2sdb.h:80

Referenced by CommitPowerFrameworkSettings(), and UseSystemManagedIdleTimeout().

◆ UseSystemManagedIdleTimeout()

NTSTATUS IdleTimeoutManagement::UseSystemManagedIdleTimeout ( __in PFX_DRIVER_GLOBALS  DriverGlobals)

Definition at line 2179 of file powerpolicystatemachine.cpp.

2182{
2184 IdleTimeoutStatusUpdateResult statusUpdateResult;
2185 CfxDevice * device;
2186
2187 //
2188 // First check if we are running on Windows 8 or above
2189 //
2191
2192 //
2193 // Get the device object so we can use it for logging
2194 //
2195 device = GetDevice();
2196
2197 //
2198 // Try to update the flag that specifies that the power framework should
2199 // determine the idle timeout.
2200 //
2202
2203 switch (statusUpdateResult) {
2205 {
2206 //
2207 // Status is already frozen. Too late to update it.
2208 //
2212 "WDFDEVICE %p !devobj %p If the power framework is made "
2213 "responsible for determining the idle timeout, then the "
2214 "first call to assign S0-idle policy must occur before the "
2215 "first start IRP is completed. However, in this case, it "
2216 "occurred after the first start IRP was completed. "
2217 "%!STATUS!.",
2218 device->GetHandle(),
2219 device->GetDeviceObject(),
2220 status
2221 );
2223 }
2224 break;
2225
2227 {
2228 //
2229 // Status being updated from multiple threads in parallel. Not
2230 // supported.
2231 //
2235 "WDFDEVICE %p !devobj %p Calls to assign S0-idle settings "
2236 "and to specify power framework settings are happening in "
2237 "parallel. The driver needs to serialize these calls with "
2238 "respect to each other. %!STATUS!.",
2239 device->GetHandle(),
2240 device->GetDeviceObject(),
2241 status
2242 );
2244 }
2245 break;
2246
2248 {
2249 //
2250 // Status flag was already set. This should never happen for the
2251 // IdleTimeoutSystemManaged flag. The caller ensures this.
2252 //
2253 ASSERTMSG(
2254 "IdleTimeoutManagement::UseSystemManagedIdleTimeout was "
2255 "called more than once\n", FALSE);
2256 }
2257
2258 //
2259 // Fall through
2260 //
2261 // || || ||
2262 // \/ \/ \/
2263 //
2265 {
2267 }
2268 break;
2269
2270 default:
2271 {
2272 ASSERTMSG("Unexpected IdleTimeoutStatusUpdateResult value\n",
2273 FALSE);
2275 }
2276 }
2277
2278 } else {
2279 //
2280 // If we're not running on Windows 8 or above, then there is nothing to
2281 // do.
2282 //
2284 }
2285
2286 return status;
2287}

◆ UsingSystemManagedIdleTimeout()

BOOLEAN IdleTimeoutManagement::UsingSystemManagedIdleTimeout ( VOID  )

Definition at line 2357 of file powerpolicystatemachine.cpp.

2360{
2361 //
2362 // If the value of this constant is changed, the debugger extension needs
2363 // to be fixed as well.
2364 //
2366
2368}
#define C_ASSERT(e)
Definition: intsafe.h:73

Referenced by FxPkgPnp::IsS0IdleSystemManaged().

Member Data Documentation

◆ m_IdleTimeoutStatus

◆ m_PoxSettings

PPOX_SETTINGS IdleTimeoutManagement::m_PoxSettings
private

The documentation for this class was generated from the following files: