ReactOS  0.4.15-dev-309-g7c8d563
profobj.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for profobj.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI KeInitializeProfile (PKPROFILE Profile, PKPROCESS Process, PVOID ImageBase, SIZE_T ImageSize, ULONG BucketSize, KPROFILE_SOURCE ProfileSource, KAFFINITY Affinity)
 
BOOLEAN NTAPI KeStartProfile (IN PKPROFILE Profile, IN PVOID Buffer)
 
BOOLEAN NTAPI KeStopProfile (IN PKPROFILE Profile)
 
ULONG NTAPI KeQueryIntervalProfile (IN KPROFILE_SOURCE ProfileSource)
 
VOID NTAPI KeSetIntervalProfile (IN ULONG Interval, IN KPROFILE_SOURCE ProfileSource)
 
VOID NTAPI KeProfileInterrupt (IN PKTRAP_FRAME TrapFrame)
 
VOID NTAPI KiParseProfileList (IN PKTRAP_FRAME TrapFrame, IN KPROFILE_SOURCE Source, IN PLIST_ENTRY ListHead)
 
VOID NTAPI KeProfileInterruptWithSource (IN PKTRAP_FRAME TrapFrame, IN KPROFILE_SOURCE Source)
 
VOID NTAPI KeSetProfileIrql (IN KIRQL ProfileIrql)
 

Variables

KIRQL KiProfileIrql = PROFILE_LEVEL
 
LIST_ENTRY KiProfileListHead
 
LIST_ENTRY KiProfileSourceListHead
 
KSPIN_LOCK KiProfileLock
 
ULONG KiProfileTimeInterval = 78125
 
ULONG KiProfileAlignmentFixupInterval
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file profobj.c.

Function Documentation

◆ KeInitializeProfile()

VOID NTAPI KeInitializeProfile ( PKPROFILE  Profile,
PKPROCESS  Process,
PVOID  ImageBase,
SIZE_T  ImageSize,
ULONG  BucketSize,
KPROFILE_SOURCE  ProfileSource,
KAFFINITY  Affinity 
)

Definition at line 28 of file profobj.c.

35 {
36  /* Initialize the Header */
37  Profile->Type = ProfileObject;
38  Profile->Size = sizeof(KPROFILE);
39 
40  /* Copy all the settings we were given */
41  Profile->Process = Process;
42  Profile->RangeBase = ImageBase;
43  Profile->BucketShift = BucketSize - 2; /* See ntinternals.net -- Alex */
44  Profile->RangeLimit = (PVOID)((ULONG_PTR)ImageBase + ImageSize);
45  Profile->Started = FALSE;
46  Profile->Source = ProfileSource;
47  Profile->Affinity = Affinity;
48 }
BOOLEAN Started
Definition: ketypes.h:817
CSHORT Type
Definition: ketypes.h:806
KAFFINITY Affinity
Definition: ketypes.h:815
PVOID RangeBase
Definition: ketypes.h:810
uint32_t ULONG_PTR
Definition: typedefs.h:64
struct _KPROCESS * Process
Definition: ketypes.h:809
KPROFILE_SOURCE Source
Definition: ketypes.h:816
PVOID RangeLimit
Definition: ketypes.h:811
void * PVOID
Definition: retypes.h:9
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:170
CSHORT Size
Definition: ketypes.h:807
ULONG BucketShift
Definition: ketypes.h:812
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
struct _KPROFILE KPROFILE

◆ KeProfileInterrupt()

VOID NTAPI KeProfileInterrupt ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 296 of file profobj.c.

297 {
298  /* Called from HAL for Timer Profiling */
300 }
VOID NTAPI KeProfileInterruptWithSource(IN PKTRAP_FRAME TrapFrame, IN KPROFILE_SOURCE Source)
Definition: profobj.c:354

◆ KeProfileInterruptWithSource()

VOID NTAPI KeProfileInterruptWithSource ( IN PKTRAP_FRAME  TrapFrame,
IN KPROFILE_SOURCE  Source 
)

Definition at line 354 of file profobj.c.

356 {
357  PKPROCESS Process = KeGetCurrentThread()->ApcState.Process;
358 
359  /* We have to parse 2 lists. Per-Process and System-Wide */
360  KiParseProfileList(TrapFrame, Source, &Process->ProfileListHead);
362 }
LIST_ENTRY KiProfileListHead
Definition: profobj.c:18
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
VOID NTAPI KiParseProfileList(IN PKTRAP_FRAME TrapFrame, IN KPROFILE_SOURCE Source, IN PLIST_ENTRY ListHead)
Definition: profobj.c:304
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
#define KeGetCurrentThread
Definition: hal.h:44

Referenced by KeProfileInterrupt().

◆ KeQueryIntervalProfile()

ULONG NTAPI KeQueryIntervalProfile ( IN KPROFILE_SOURCE  ProfileSource)

Definition at line 219 of file profobj.c.

220 {
221  HAL_PROFILE_SOURCE_INFORMATION ProfileSourceInformation;
224 
225  /* Check what profile this is */
226  if (ProfileSource == ProfileTime)
227  {
228  /* Return the time interval */
230  }
231  else if (ProfileSource == ProfileAlignmentFixup)
232  {
233  /* Return the alignment interval */
235  }
236  else
237  {
238  /* Request it from HAL */
239  ProfileSourceInformation.Source = ProfileSource;
242  &ProfileSourceInformation,
243  &ReturnLength);
244 
245  /* Check if HAL handled it and supports this profile */
246  if (NT_SUCCESS(Status) && (ProfileSourceInformation.Supported))
247  {
248  /* Get the interval */
249  Interval = ProfileSourceInformation.Interval;
250  }
251  else
252  {
253  /* Unsupported or invalid source, fail */
254  Interval = 0;
255  }
256  }
257 
258  /* Return the interval we got */
259  return Interval;
260 }
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
LONG NTSTATUS
Definition: precomp.h:26
#define HalQuerySystemInformation
Definition: haltypes.h:283
ULONG KiProfileTimeInterval
Definition: profobj.c:21
DWORD Interval
Definition: netstat.c:33
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
ULONG KiProfileAlignmentFixupInterval
Definition: profobj.c:22
unsigned int ULONG
Definition: retypes.h:1

◆ KeSetIntervalProfile()

VOID NTAPI KeSetIntervalProfile ( IN ULONG  Interval,
IN KPROFILE_SOURCE  ProfileSource 
)

Definition at line 264 of file profobj.c.

266 {
267  HAL_PROFILE_SOURCE_INTERVAL ProfileSourceInterval;
268 
269  /* Check what profile this is */
270  if (ProfileSource == ProfileTime)
271  {
272  /* Set the interval through HAL */
274  }
275  else if (ProfileSource == ProfileAlignmentFixup)
276  {
277  /* Set the alignment interval */
279  }
280  else
281  {
282  /* HAL handles any other interval */
283  ProfileSourceInterval.Source = ProfileSource;
284  ProfileSourceInterval.Interval = Interval;
287  &ProfileSourceInterval);
288  }
289 }
ULONG_PTR NTAPI HalSetProfileInterval(IN ULONG_PTR Interval)
Definition: profil.c:44
#define HalSetSystemInformation
Definition: haltypes.h:284
ULONG KiProfileTimeInterval
Definition: profobj.c:21
DWORD Interval
Definition: netstat.c:33
KPROFILE_SOURCE Source
Definition: haltypes.h:328
ULONG KiProfileAlignmentFixupInterval
Definition: profobj.c:22
unsigned int ULONG
Definition: retypes.h:1

◆ KeSetProfileIrql()

VOID NTAPI KeSetProfileIrql ( IN KIRQL  ProfileIrql)

Definition at line 369 of file profobj.c.

370 {
371  /* Set the IRQL at which Profiling will run */
372  KiProfileIrql = ProfileIrql;
373 }
KIRQL KiProfileIrql
Definition: profobj.c:17

◆ KeStartProfile()

BOOLEAN NTAPI KeStartProfile ( IN PKPROFILE  Profile,
IN PVOID  Buffer 
)

Definition at line 52 of file profobj.c.

54 {
55  KIRQL OldIrql;
56  PKPROFILE_SOURCE_OBJECT SourceBuffer;
57  PKPROFILE_SOURCE_OBJECT CurrentSource;
58  BOOLEAN FreeBuffer = TRUE, SourceFound = FALSE, StartedProfile;
59  PKPROCESS ProfileProcess;
60  PLIST_ENTRY NextEntry;
61 
62  /* Allocate a buffer first, before we raise IRQL */
63  SourceBuffer = ExAllocatePoolWithTag(NonPagedPool,
64  sizeof(KPROFILE_SOURCE_OBJECT),
65  'forP');
66  if (!SourceBuffer) return FALSE;
67  RtlZeroMemory(SourceBuffer, sizeof(KPROFILE_SOURCE_OBJECT));
68 
69  /* Raise to profile IRQL and acquire the profile lock */
72 
73  /* Make sure it's not running */
74  if (!Profile->Started)
75  {
76  /* Set it as Started */
77  Profile->Buffer = Buffer;
78  Profile->Started = TRUE;
79  StartedProfile = TRUE;
80 
81  /* Get the process, if any */
82  ProfileProcess = Profile->Process;
83 
84  /* Check where we should insert it */
85  if (ProfileProcess)
86  {
87  /* Insert it into the Process List */
88  InsertTailList(&ProfileProcess->ProfileListHead, &Profile->ProfileListEntry);
89  }
90  else
91  {
92  /* Insert it into the Global List */
93  InsertTailList(&KiProfileListHead, &Profile->ProfileListEntry);
94  }
95 
96  /* Start looping */
97  for (NextEntry = KiProfileSourceListHead.Flink;
98  NextEntry != &KiProfileSourceListHead;
99  NextEntry = NextEntry->Flink)
100  {
101  /* Get the entry */
102  CurrentSource = CONTAINING_RECORD(NextEntry,
104  ListEntry);
105 
106  /* Check if it's the same as the one being requested now */
107  if (CurrentSource->Source == Profile->Source)
108  {
109  /* It is, break out */
110  SourceFound = TRUE;
111  break;
112  }
113  }
114 
115  /* See if the loop found something */
116  if (!SourceFound)
117  {
118  /* Nothing found, use our allocated buffer */
119  CurrentSource = SourceBuffer;
120 
121  /* Set up the Source Object */
122  CurrentSource->Source = Profile->Source;
124 
125  /* Don't free the pool later on */
126  FreeBuffer = FALSE;
127  }
128  }
129  else
130  {
131  /* Already running so nothing to start */
132  StartedProfile = FALSE;
133  }
134 
135  /* Release the profile lock */
137 
138  /* Tell HAL to start the profile interrupt */
139  HalStartProfileInterrupt(Profile->Source);
140 
141  /* Lower back to original IRQL */
143 
144  /* Free the pool */
145  if (FreeBuffer) ExFreePoolWithTag(SourceBuffer, 'forP');
146 
147  /* Return whether we could start the profile */
148  return StartedProfile;
149 }
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
VOID NTAPI HalStartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
Definition: profil.c:33
KIRQL KiProfileIrql
Definition: profobj.c:17
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
KPROFILE_SOURCE Source
Definition: ke.h:16
unsigned char BOOLEAN
KSPIN_LOCK KiProfileLock
Definition: profobj.c:20
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
LIST_ENTRY ListEntry
Definition: ke.h:17
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
LIST_ENTRY KiProfileListHead
Definition: profobj.c:18
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: typedefs.h:118
LIST_ENTRY ProfileListHead
Definition: ketypes.h:1975
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
LIST_ENTRY KiProfileSourceListHead
Definition: profobj.c:19

◆ KeStopProfile()

BOOLEAN NTAPI KeStopProfile ( IN PKPROFILE  Profile)

Definition at line 153 of file profobj.c.

154 {
155  KIRQL OldIrql;
156  PKPROFILE_SOURCE_OBJECT CurrentSource = NULL;
157  PLIST_ENTRY NextEntry;
158  BOOLEAN SourceFound = FALSE, StoppedProfile;
159 
160  /* Raise to profile IRQL and acquire the profile lock */
163 
164  /* Make sure it's running */
165  if (Profile->Started)
166  {
167  /* Remove it from the list and disable */
168  RemoveEntryList(&Profile->ProfileListEntry);
169  Profile->Started = FALSE;
170  StoppedProfile = TRUE;
171 
172  /* Start looping */
173  for (NextEntry = KiProfileSourceListHead.Flink;
174  NextEntry != &KiProfileSourceListHead;
175  NextEntry = NextEntry->Flink)
176  {
177  /* Get the entry */
178  CurrentSource = CONTAINING_RECORD(NextEntry,
180  ListEntry);
181 
182  /* Check if this is the Source Object */
183  if (CurrentSource->Source == Profile->Source)
184  {
185  /* Remember we found one */
186  SourceFound = TRUE;
187 
188  /* Remove it and break out */
189  RemoveEntryList(&CurrentSource->ListEntry);
190  break;
191  }
192  }
193 
194  }
195  else
196  {
197  /* It wasn't! */
198  StoppedProfile = FALSE;
199  }
200 
201  /* Release the profile lock */
203 
204  /* Stop the profile interrupt */
205  HalStopProfileInterrupt(Profile->Source);
206 
207  /* Lower back to original IRQL */
209 
210  /* Free the Source Object */
211  if (SourceFound) ExFreePool(CurrentSource);
212 
213  /* Return whether we could stop the profile */
214  return StoppedProfile;
215 }
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
KIRQL KiProfileIrql
Definition: profobj.c:17
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
KPROFILE_SOURCE Source
Definition: ke.h:16
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
KSPIN_LOCK KiProfileLock
Definition: profobj.c:20
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
LIST_ENTRY ListEntry
Definition: ke.h:17
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: typedefs.h:118
VOID NTAPI HalStopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
Definition: profil.c:22
LIST_ENTRY KiProfileSourceListHead
Definition: profobj.c:19
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ KiParseProfileList()

VOID NTAPI KiParseProfileList ( IN PKTRAP_FRAME  TrapFrame,
IN KPROFILE_SOURCE  Source,
IN PLIST_ENTRY  ListHead 
)

Definition at line 304 of file profobj.c.

307 {
308  PULONG BucketValue;
309  PKPROFILE Profile;
310  PLIST_ENTRY NextEntry;
311  ULONG_PTR ProgramCounter;
312 
313  /* Get the Program Counter */
314  ProgramCounter = KeGetTrapFramePc(TrapFrame);
315 
316  /* Loop the List */
317  for (NextEntry = ListHead->Flink;
318  NextEntry != ListHead;
319  NextEntry = NextEntry->Flink)
320  {
321  /* Get the entry */
322  Profile = CONTAINING_RECORD(NextEntry, KPROFILE, ProfileListEntry);
323 
324  /* Check if the source is good, and if it's within the range */
325  if ((Profile->Source != Source) ||
326  (ProgramCounter < (ULONG_PTR)Profile->RangeBase) ||
327  (ProgramCounter > (ULONG_PTR)Profile->RangeLimit))
328  {
329  continue;
330  }
331 
332  /* Get the Pointer to the Bucket Value representing this Program Counter */
333  BucketValue = (PULONG)((ULONG_PTR)Profile->Buffer +
334  (((ProgramCounter - (ULONG_PTR)Profile->RangeBase)
335  >> Profile->BucketShift) &~ 0x3));
336 
337  /* Increment the value */
338  (*BucketValue)++;
339  }
340 }
PVOID Buffer
Definition: ketypes.h:813
PVOID RangeBase
Definition: ketypes.h:810
uint32_t ULONG_PTR
Definition: typedefs.h:64
KPROFILE_SOURCE Source
Definition: ketypes.h:816
PVOID RangeLimit
Definition: ketypes.h:811
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
#define KeGetTrapFramePc(TrapFrame)
Definition: ke.h:130
Definition: typedefs.h:118
unsigned int * PULONG
Definition: retypes.h:1
ULONG BucketShift
Definition: ketypes.h:812
#define ULONG_PTR
Definition: config.h:101
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167

Referenced by KeProfileInterruptWithSource().

Variable Documentation

◆ KiProfileAlignmentFixupInterval

ULONG KiProfileAlignmentFixupInterval

Definition at line 22 of file profobj.c.

Referenced by KeQueryIntervalProfile(), and KeSetIntervalProfile().

◆ KiProfileIrql

KIRQL KiProfileIrql = PROFILE_LEVEL

Definition at line 17 of file profobj.c.

Referenced by KeSetProfileIrql(), KeStartProfile(), and KeStopProfile().

◆ KiProfileListHead

LIST_ENTRY KiProfileListHead

◆ KiProfileLock

KSPIN_LOCK KiProfileLock

Definition at line 20 of file profobj.c.

Referenced by KeStartProfile(), KeStopProfile(), KiInitializeKernel(), and KiInitSystem().

◆ KiProfileSourceListHead

LIST_ENTRY KiProfileSourceListHead

Definition at line 19 of file profobj.c.

Referenced by KeStartProfile(), KeStopProfile(), KiInitializeKernel(), and KiInitSystem().

◆ KiProfileTimeInterval

ULONG KiProfileTimeInterval = 78125

Definition at line 21 of file profobj.c.

Referenced by KeQueryIntervalProfile(), and KeSetIntervalProfile().