test: callperf.c File Reference

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

# callperf.c File Reference

`#include "exp.h"`

Go to the source code of this file.

## Functions

VOID | ExInitializeCallData (IN PCALL_PERFORMANCE_DATA CallData)
VOID | ExRecordCallerInHashTable (IN PCALL_PERFORMANCE_DATA CallData, IN PVOID CallersAddress, IN PVOID CallersCaller)

## Function Documentation

VOID ExInitializeCallData | ( | IN PCALL_PERFORMANCE_DATA | CallData | ) |

Definition at line 28 of file callperf.c.

References CALL_HASH_TABLE_SIZE, Index, KeInitializeSpinLock(), and PCALL_PERFORMANCE_DATA.

Referenced by KiInitSystem().

    00034                    :
    00035
    00036     This function initializes a call performance data structure.
    00037
    00038 Arguments:
    00039
    00040     CallData - Supplies a pointer to the call performance data structure
    00041         that is initialized.
    00042
    00043 Return Value:
    00044
    00045     None.
    00046
    00047 --*/
    00048
    00049 {
    00050
    00051     ULONG Index;
    00052
    00053     //
    00054     // Initialize the spinlock and listheads for the call performance
    00055     // data structure.
    00056     //
    00057
    00058     KeInitializeSpinLock(&CallData->SpinLock);
    00059     for (Index = 0; Index < CALL_HASH_TABLE_SIZE; Index += 1) {
    00060         InitializeListHead(&CallData->HashTable[Index]);
    00061     }
    00062 }

VOID ExRecordCallerInHashTable | ( | IN PCALL_PERFORMANCE_DATA | CallData,
|  | IN PVOID | CallersAddress,
|  | IN PVOID | CallersCaller
| ) |

Definition at line 65 of file callperf.c.

References CALL_HASH_ENTRY, CALL_HASH_TABLE_SIZE, _CALL_HASH_ENTRY::CallCount, _CALL_HASH_ENTRY::CallersAddress, _CALL_HASH_ENTRY::CallersCaller, ExAllocatePoolWithTag, InitializationPhase, _CALL_HASH_ENTRY::ListEntry, NonPagedPool, NULL, and PCALL_HASH_ENTRY.

    00073                    :
    00074
    00075     This function records call data in the specified call performance
    00076     data structure.
    00077
    00078 Arguments:
    00079
    00080     CallData - Supplies a pointer to the call performance data structure
    00081         in which the call data is recorded.
    00082
    00083     CallersAddress - Supplies the address of the caller of a fucntion.
    00084
    00085     CallersCaller - Supplies the address of the caller of a caller of
    00086         a function.
    00087
    00088 Return Value:
    00089
    00090     None.
    00091
    00092 --*/
    00093
    00094 {
    00095
    00096     PCALL_HASH_ENTRY HashEntry;
    00097     ULONG Hash;
    00098     PCALL_HASH_ENTRY MatchEntry;
    00099     PLIST_ENTRY NextEntry;
    00100     KIRQL OldIrql;
    00101
    00102     //
    00103     // If the initialization phase is not zero, then collect call performance
    00104     // data.
    00105     //
    00106
    00107     if (InitializationPhase != 0) {
    00108
    00109         //
    00110         // Acquire the call performance data structure spinlock.
    00111         //
    00112
    00113         ExAcquireSpinLock(&CallData->SpinLock, &OldIrql);
    00114
    00115         //
    00116         // Lookup the callers address in call performance data hash table. If
    00117         // the address does not exist in the table, then create a new entry.
    00118         //
    00119
    00120         Hash = (ULONG)((ULONG_PTR)CallersAddress ^ (ULONG_PTR)CallersCaller);
    00121         Hash = ((Hash > 24) ^ (Hash > 16) ^ (Hash > 8) ^ (Hash)) & (CALL_HASH_TABLE_SIZE - 1);
    00122         MatchEntry = NULL;
    00123         NextEntry = CallData->HashTable[Hash].Flink;
    00124         while (NextEntry != &CallData->HashTable[Hash]) {
    00125             HashEntry = CONTAINING_RECORD(NextEntry,
    00126                                           CALL_HASH_ENTRY,
    00127                                           ListEntry);
    00128
    00129             if ((HashEntry->CallersAddress == CallersAddress) &&
    00130                 (HashEntry->CallersCaller == CallersCaller)) {
    00131                 MatchEntry = HashEntry;
    00132                 break;
    00133             }
    00134
    00135             NextEntry = NextEntry->Flink;
    00136         }
    00137
    00138         //
    00139         // If a matching caller address was found, then update the call site
    00140         // statistics. Otherwise, allocate a new hash entry and initialize
    00141         // call site statistics.
    00142         //
    00143
    00144         if (MatchEntry != NULL) {
    00145             MatchEntry->CallCount += 1;
    00146
    00147         } else {
    00148             MatchEntry = ExAllocatePoolWithTag(NonPagedPool,
    00149                                               sizeof(CALL_HASH_ENTRY),
    00150                                               'CdHe');
    00151
    00152             if (MatchEntry != NULL) {
    00153                 MatchEntry->CallersAddress = CallersAddress;
    00154                 MatchEntry->CallersCaller = CallersCaller;
    00155                 MatchEntry->CallCount = 1;
    00156                 InsertTailList(&CallData->HashTable[Hash],
    00157                                &MatchEntry->ListEntry);
    00158             }
    00159         }
    00160
    00161         //
    00162         // Release the call performance data structure spinlock.
    00163         //
    00164
    00165         ExReleaseSpinLock(&CallData->SpinLock, OldIrql);
    00166     }
    00167
    00168     return;
    00169 }
    }