Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ntnap.c File Reference

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <string.h>
#include "ntnapdef.h"
#include "ntnap.h"

Go to the source code of this file.

Functions

VOID NapDllInit (VOID)
NTSTATUS NapCreateDataSection (PNAPCONTROL *NapSectionPointer)
VOID NapRecordInfo (IN ULONG ServiceNumber, IN LARGE_INTEGER Counters[])
NTSTATUS NapClearData (VOID)
NTSTATUS NapRetrieveData (OUT NAPDATA *NapApiData, OUT PCHAR **NapApiNames, OUT PLARGE_INTEGER *NapCounterFrequency)
NTSTATUS NapGetApiCount (OUT PULONG NapApiCount)
NTSTATUS NapPause (VOID)
NTSTATUS NapResume (VOID)

Variables

BOOLEAN NapInitialized = FALSE
LARGE_INTEGER NapFrequency
PNAPCONTROL NapControl = NULL
PNAPDATA NapProfilingData = NULL


Function Documentation

NTSTATUS NapClearData VOID   ) 
 

Definition at line 378 of file ntnap.c.

References L, MAX_LONG, MAX_ULONG, NapProfilingData, and NapReleaseSpinLock().

Referenced by NapDllInit().

00384 : 00385 00386 NapClearData() is called to clear all the counters and timers. 00387 The calibration counters are not cleared. For the rest, 00388 if not previously collected, the data will be lost. 00389 00390 Arguments: 00391 00392 None 00393 00394 Return Value: 00395 00396 Status 00397 00398 --*/ 00399 00400 { 00401 ULONG ServiceNumber; 00402 00403 // 00404 // Initialize the first one after the calibration data 00405 // 00406 00407 NapAcquireSpinLock(&(NapProfilingData[1].NapLock)); 00408 00409 NapProfilingData[1].Calls = 0L; 00410 NapProfilingData[1].TimingErrors = 0L; 00411 NapProfilingData[1].TotalTime.HighPart = 0L; 00412 NapProfilingData[1].TotalTime.LowPart = 0L; 00413 NapProfilingData[1].FirstTime.HighPart = 0L; 00414 NapProfilingData[1].FirstTime.LowPart = 0L; 00415 NapProfilingData[1].MaxTime.HighPart = 0L; 00416 NapProfilingData[1].MaxTime.LowPart = 0L; 00417 NapProfilingData[1].MinTime.HighPart = MAX_LONG; 00418 NapProfilingData[1].MinTime.LowPart = MAX_ULONG; 00419 00420 // 00421 // Now use the initialized first one to initialize the rest 00422 // 00423 00424 00425 for (ServiceNumber = 2; ServiceNumber <= NAP_API_COUNT; ServiceNumber++) { 00426 00427 NapAcquireSpinLock(&(NapProfilingData[ServiceNumber].NapLock)); 00428 00429 NapProfilingData[ServiceNumber] = NapProfilingData[1]; 00430 00431 NapReleaseSpinLock(&(NapProfilingData[ServiceNumber].NapLock)); 00432 } 00433 00434 NapReleaseSpinLock(&(NapProfilingData[1].NapLock)); 00435 00436 return(STATUS_SUCCESS); 00437 }

NTSTATUS NapCreateDataSection PNAPCONTROL NapSectionPointer  ) 
 

Definition at line 164 of file ntnap.c.

References NT_SUCCESS, NtCreateSection(), NtMapViewOfSection(), NTSTATUS(), NULL, ObjectAttributes, and Status.

Referenced by NapDllInit().

00169 : 00170 00171 NapCreateData() is called to create the profiling data section. 00172 One section, named "\NapDataSection", is used for the whole system. 00173 It is accessible by anyone, so don't mess it up. 00174 00175 Arguments: 00176 00177 NapSectionPointer - a pointer to a pointer which will be set to 00178 to point to the beginning of the section. 00179 00180 Return Value: 00181 00182 Status 00183 00184 --*/ 00185 00186 00187 { 00188 NTSTATUS Status; 00189 HANDLE NapSectionHandle; 00190 HANDLE MyProcess; 00191 STRING NapSectionName; 00192 OBJECT_ATTRIBUTES ObjectAttributes; 00193 LARGE_INTEGER AllocationSize; 00194 ULONG ViewSize; 00195 PNAPCONTROL SectionPointer; 00196 00197 // 00198 // Initialize object attributes for the dump file 00199 // 00200 00201 NapSectionName.Length = 15; 00202 NapSectionName.MaximumLength = 15; 00203 NapSectionName.Buffer = "\\NapDataSection"; 00204 00205 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); 00206 ObjectAttributes.ObjectName = &NapSectionName; 00207 ObjectAttributes.RootDirectory = NULL; 00208 ObjectAttributes.SecurityDescriptor = NULL; 00209 ObjectAttributes.SecurityQualityOfService = NULL; 00210 ObjectAttributes.Attributes = OBJ_OPENIF | 00211 OBJ_CASE_INSENSITIVE; 00212 00213 00214 AllocationSize.HighPart = 0; 00215 AllocationSize.LowPart = (NAP_API_COUNT + 1) * sizeof(NAPDATA); 00216 00217 Status = NtCreateSection(&NapSectionHandle, 00218 SECTION_MAP_READ | 00219 SECTION_MAP_WRITE, 00220 &ObjectAttributes, 00221 &AllocationSize, 00222 PAGE_READWRITE, 00223 SEC_COMMIT, 00224 NULL); 00225 00226 if (NT_SUCCESS(Status)) { 00227 00228 MyProcess = NtCurrentProcess(); 00229 00230 ViewSize = AllocationSize.LowPart; 00231 00232 SectionPointer = NULL; 00233 00234 Status = NtMapViewOfSection(NapSectionHandle, 00235 MyProcess, 00236 (PVOID *)&SectionPointer, 00237 0, 00238 AllocationSize.LowPart, 00239 NULL, 00240 &ViewSize, 00241 ViewUnmap, 00242 MEM_TOP_DOWN, 00243 PAGE_READWRITE); 00244 00245 *NapSectionPointer = SectionPointer; 00246 } 00247 00248 return(Status); 00249 }

VOID NapDllInit VOID   ) 
 

Definition at line 61 of file ntnap.c.

References _NAPCONTROL::Initialized, L, MAX_LONG, MAX_ULONG, NapCalibrate(), NapClearData(), NapControl, NapCreateDataSection(), NapFrequency, NapInitialized, NapProfilingData, NT_SUCCESS, NtQueryPerformanceCounter(), NUM_ITERATIONS, _NAPCONTROL::Paused, and TRUE.

00067 : 00068 00069 NapDllInit() is called before calling any profiling api. It 00070 initializes profiling for the NT native API's. 00071 00072 NOTE: Initialization occurs only once and is controlled by 00073 the NapInitDone global flag. 00074 00075 Arguments: 00076 00077 None 00078 00079 Return Value: 00080 00081 None 00082 00083 --*/ 00084 00085 { 00086 ULONG i; 00087 LARGE_INTEGER CurrentCounter; 00088 00089 if (!NapInitialized) { 00090 00091 // 00092 // Instance data for this process's ntdll.dll not yet initialized. 00093 // 00094 00095 NapInitialized = TRUE; 00096 00097 // 00098 // Get Counter frequency (current counter value is thrown away) 00099 // This call is not profiled because NapControl == NULL here. 00100 // 00101 00102 NtQueryPerformanceCounter(&CurrentCounter, 00103 &NapFrequency); 00104 00105 // 00106 // Allocate or open data section for api profiling data. 00107 // 00108 00109 if (NT_SUCCESS(NapCreateDataSection(&NapControl))) { 00110 00111 NapProfilingData = (PNAPDATA)(NapControl + 1); 00112 00113 if (!NapControl->Initialized) { 00114 00115 // 00116 // We are the first process to get here: we jsut 00117 // allocated the section, so must initialize it. 00118 // 00119 00120 NapControl->Initialized = TRUE; 00121 00122 NapControl->Paused = 0; 00123 00124 // 00125 // Clear the data area used for calibration data. 00126 // 00127 00128 NapProfilingData[0].NapLock = 0L; 00129 NapProfilingData[0].Calls = 0L; 00130 NapProfilingData[0].TimingErrors = 0L; 00131 NapProfilingData[0].TotalTime.HighPart = 0L; 00132 NapProfilingData[0].TotalTime.LowPart = 0L; 00133 NapProfilingData[0].FirstTime.HighPart = 0L; 00134 NapProfilingData[0].FirstTime.LowPart = 0L; 00135 NapProfilingData[0].MaxTime.HighPart = 0L; 00136 NapProfilingData[0].MaxTime.LowPart = 0L; 00137 NapProfilingData[0].MinTime.HighPart = MAX_LONG; 00138 NapProfilingData[0].MinTime.LowPart = MAX_ULONG; 00139 00140 // 00141 // Clear the rest of the data collection area 00142 // 00143 00144 NapClearData(); 00145 00146 // 00147 // Calibrate time overhead from profiling. We care mostly 00148 // about the minimum time here, to avoid extra time from 00149 // interrupts etc. 00150 // 00151 00152 for (i=0; i<NUM_ITERATIONS; i++) { 00153 NapCalibrate(); 00154 } 00155 } 00156 } 00157 } 00158 }

NTSTATUS NapGetApiCount OUT PULONG  NapApiCount  ) 
 

Definition at line 500 of file ntnap.c.

00506 : 00507 00508 NapGetApiCount() is called to get the number of API's which are 00509 being profiled. This can then be used to allocate an array for 00510 receiving the data from NapReturnData. 00511 00512 Arguments: 00513 00514 NapApiCount - A pointer throug which the count is returned. 00515 00516 Return Value: 00517 00518 Status 00519 00520 --*/ 00521 00522 00523 { 00524 00525 *NapApiCount = NAP_API_COUNT; 00526 00527 return(STATUS_SUCCESS); 00528 00529 }

NTSTATUS NapPause VOID   ) 
 

Definition at line 535 of file ntnap.c.

References NapControl, and _NAPCONTROL::Paused.

00541 : 00542 00543 NapPause() is called to temporarily cease data collection. 00544 Data collection is resumed by a companion call to NapResume. 00545 00546 Arguments: 00547 00548 None 00549 00550 Return Value: 00551 00552 Status 00553 00554 --*/ 00555 00556 00557 { 00558 NapControl->Paused++; 00559 00560 return(STATUS_SUCCESS); 00561 }

VOID NapRecordInfo IN ULONG  ServiceNumber,
IN LARGE_INTEGER  Counters[]
 

Definition at line 255 of file ntnap.c.

References NapControl, NapProfilingData, NapReleaseSpinLock(), NULL, and _NAPCONTROL::Paused.

00262 : 00263 00264 NapRecordInfo() is called after the API being measured has 00265 returned, and the value of the performance counter has been 00266 obtained. 00267 00268 NOTE: Initialization occurs only once and is controlled by 00269 the NapInitDone global flag. 00270 00271 Arguments: 00272 00273 ServiceNumber - the number of the service being measured. 00274 -1 is reserved for calibration. 00275 00276 Counters - a pointer to the value of the counter after the call 00277 to the measured routine. Followed immediately 00278 in memory by the value of the counter before the 00279 call to the measured routine. 00280 00281 Return Value: 00282 00283 None 00284 00285 --*/ 00286 00287 00288 { 00289 LARGE_INTEGER ElapsedTime; 00290 LARGE_INTEGER Difference; 00291 00292 00293 // 00294 // First make sure we have been initialized 00295 // 00296 00297 if (NapControl != NULL) { 00298 00299 // 00300 // Check to be sure profiling is not paused 00301 00302 if (NapControl->Paused == 0) { 00303 00304 // 00305 // Since ServiceNumber -1 is used for calibration, bump same 00306 // so indexes start at 0. 00307 // 00308 00309 ServiceNumber++; 00310 00311 // 00312 // Prevent others from changing data at the same time 00313 // we are. 00314 // 00315 00316 NapAcquireSpinLock(&(NapProfilingData[ServiceNumber].NapLock)); 00317 00318 // 00319 // Record API info 00320 // 00321 00322 NapProfilingData[ServiceNumber].Calls++; 00323 00324 // 00325 // Elapsed time is end time minus start time 00326 // 00327 00328 ElapsedTime = 00329 RtlLargeIntegerSubtract(Counters[0],Counters[1]); 00330 00331 // 00332 // Now add elapsed time to total time 00333 // 00334 00335 NapProfilingData[ServiceNumber].TotalTime = 00336 RtlLargeIntegerAdd(NapProfilingData[ServiceNumber].TotalTime, 00337 ElapsedTime); 00338 00339 if (NapProfilingData[ServiceNumber].Calls == 1) { 00340 NapProfilingData[ServiceNumber].FirstTime = ElapsedTime; 00341 } 00342 else { 00343 Difference = 00344 RtlLargeIntegerSubtract( 00345 NapProfilingData[ServiceNumber].MaxTime, 00346 ElapsedTime); 00347 if (Difference.HighPart < 0) { 00348 00349 // 00350 // A new maximum was attained 00351 // 00352 00353 NapProfilingData[ServiceNumber].MaxTime = ElapsedTime; 00354 00355 } 00356 Difference = 00357 RtlLargeIntegerSubtract( 00358 ElapsedTime, 00359 NapProfilingData[ServiceNumber].MinTime); 00360 if (Difference.HighPart < 0) { 00361 00362 // 00363 // A new minimum was attained 00364 // 00365 00366 NapProfilingData[ServiceNumber].MinTime = ElapsedTime; 00367 } 00368 } 00369 00370 NapReleaseSpinLock(&(NapProfilingData[ServiceNumber].NapLock)); 00371 } 00372 } 00373 }

NTSTATUS NapResume VOID   ) 
 

Definition at line 565 of file ntnap.c.

References NapControl, and _NAPCONTROL::Paused.

00571 : 00572 00573 NapResume() is called to resume data collection after a companion 00574 call to NapPause. 00575 00576 Arguments: 00577 00578 None 00579 00580 Return Value: 00581 00582 Status 00583 00584 --*/ 00585 00586 00587 { 00588 NapControl->Paused--; 00589 00590 return(STATUS_SUCCESS); 00591 } }

NTSTATUS NapRetrieveData OUT NAPDATA *  NapApiData,
OUT PCHAR **  NapApiNames,
OUT PLARGE_INTEGER *  NapCounterFrequency
 

Definition at line 442 of file ntnap.c.

References NapFrequency, NapNames, NapProfilingData, and NapReleaseSpinLock().

00450 : 00451 00452 NapRetrieveData() is called to get all the relevant data 00453 about API's that have been profiled. It is wise to call 00454 NapPause() before calling this, and NapResume() afterwards. 00455 Can't just do these in here, 'cause you may be doing stuff outside 00456 of this call you don't want profiled. 00457 00458 Arguments: 00459 00460 NapApiData - a pointer to a buffer to which is copied 00461 the array of counters; must be large enough for 00462 NAP_API_COUNT+1; call NapGetApiCount to obtain needed 00463 size. 00464 00465 NapApiNames - a pointer to which is copied a pointer to 00466 an array of pointers to API names 00467 00468 NapCounterFrequency - a buffer to which is copied the frequency 00469 of the performance counter 00470 00471 Return Value: 00472 00473 Status 00474 00475 --*/ 00476 00477 { 00478 ULONG ServiceNumber; 00479 00480 *NapApiNames = NapNames; 00481 00482 *NapCounterFrequency = &NapFrequency; 00483 00484 for (ServiceNumber = 0; ServiceNumber <= NAP_API_COUNT; ServiceNumber++) { 00485 00486 NapAcquireSpinLock(&(NapProfilingData[ServiceNumber].NapLock)); 00487 00488 NapApiData[ServiceNumber] = NapProfilingData[ServiceNumber]; 00489 00490 NapReleaseSpinLock(&(NapProfilingData[ServiceNumber].NapLock)); 00491 NapReleaseSpinLock(&(NapApiData[ServiceNumber].NapLock)); 00492 } 00493 00494 return(STATUS_SUCCESS); 00495 }


Variable Documentation

PNAPCONTROL NapControl = NULL
 

Definition at line 48 of file ntnap.c.

Referenced by NapDllInit(), NapPause(), NapRecordInfo(), and NapResume().

LARGE_INTEGER NapFrequency
 

Definition at line 42 of file ntnap.c.

Referenced by NapDllInit(), and NapRetrieveData().

BOOLEAN NapInitialized = FALSE
 

Definition at line 36 of file ntnap.c.

Referenced by NapDllInit().

PNAPDATA NapProfilingData = NULL
 

Definition at line 57 of file ntnap.c.

Referenced by NapClearData(), NapDllInit(), NapRecordInfo(), and NapRetrieveData().


Generated on Sat May 15 19:44:53 2004 for test by doxygen 1.3.7