ReactOS  0.4.15-dev-3302-ga37d9a4
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

◆ 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.

388  : m_IdleTimeoutStatus(0),
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  }
GLuint buffer
Definition: glext.h:5915
static __inline VOID MxFreePool(__in PVOID Ptr)
Definition: mxmemorykm.h:41
unsigned char BYTE
Definition: xxhash.c:193
PPO_FX_COMPONENT Component
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
ULONG IdleStateCount
Definition: potypes.h:575

Member Function Documentation

◆ _SystemManagedIdleTimeoutAvailable()

BOOLEAN IdleTimeoutManagement::_SystemManagedIdleTimeoutAvailable ( VOID  )
static

Definition at line 211 of file supportkm.cpp.

214 {
216 }
PFN_POX_REGISTER_DEVICE PoxRegisterDevice
Definition: fxglobals.h:742
FxLibraryGlobalsType FxLibraryGlobals
Definition: globals.cpp:95
#define NULL
Definition: types.h:112

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 {
2384  NTSTATUS status;
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 
2512 exit:
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  //
2519  m_PoxSettings = NULL;
2520  }
2521  }
2522  return status;
2523 }
#define TRUE
Definition: types.h:120
static BOOLEAN _SystemManagedIdleTimeoutAvailable(VOID)
Definition: supportkm.cpp:211
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
DriverGlobals
FxDevice * device
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define FALSE
Definition: types.h:117
Definition: devices.h:37
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
unsigned char BOOLEAN
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACINGPNP
Definition: dbgtrace.h:67
IdleTimeoutStatusUpdateResult UpdateIdleTimeoutStatus(__in IdleTimeoutStatusFlag Flag)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
void exit(int exitcode)
Definition: _exit.c:33
static SERVICE_STATUS status
Definition: service.c:31
FxVerifierDbgBreakPoint(pFxDriverGlobals)
Definition: ps.c:97

◆ DriverSpecifiedPowerFrameworkSettings()

BOOLEAN IdleTimeoutManagement::DriverSpecifiedPowerFrameworkSettings ( VOID  )

◆ 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 }
static BOOLEAN _SystemManagedIdleTimeoutAvailable(VOID)
Definition: supportkm.cpp:211
DriverGlobals
FxDevice * device
long LONG
Definition: pedump.c:60
Definition: devices.h:37
#define InterlockedExchange
Definition: armddk.h:54
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACINGPNP
Definition: dbgtrace.h:67
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxVerifierDbgBreakPoint(pFxDriverGlobals)

◆ 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
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define NULL
Definition: types.h:112

Referenced by CommitPowerFrameworkSettings(), FreezeIdleTimeoutManagementStatus(), and UseSystemManagedIdleTimeout().

◆ 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
long LONG
Definition: pedump.c:60
Definition: xml2sdb.h:79

Referenced by CommitPowerFrameworkSettings(), and UseSystemManagedIdleTimeout().

◆ UseSystemManagedIdleTimeout()

NTSTATUS IdleTimeoutManagement::UseSystemManagedIdleTimeout ( __in PFX_DRIVER_GLOBALS  DriverGlobals)

Definition at line 2179 of file powerpolicystatemachine.cpp.

2182 {
2183  NTSTATUS status;
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  //
2201  statusUpdateResult = UpdateIdleTimeoutStatus(IdleTimeoutSystemManaged);
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 }
static BOOLEAN _SystemManagedIdleTimeoutAvailable(VOID)
Definition: supportkm.cpp:211
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
DriverGlobals
FxDevice * device
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define FALSE
Definition: types.h:117
Definition: devices.h:37
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACINGPNP
Definition: dbgtrace.h:67
IdleTimeoutStatusUpdateResult UpdateIdleTimeoutStatus(__in IdleTimeoutStatusFlag Flag)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
FxVerifierDbgBreakPoint(pFxDriverGlobals)
Definition: ps.c:97

◆ 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
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706

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: